json-ld 3.1.4 → 3.1.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +131 -48
- data/VERSION +1 -1
- data/bin/jsonld +31 -32
- data/lib/json/ld.rb +5 -2
- data/lib/json/ld/api.rb +35 -16
- data/lib/json/ld/compact.rb +41 -29
- data/lib/json/ld/conneg.rb +1 -1
- data/lib/json/ld/context.rb +51 -59
- data/lib/json/ld/expand.rb +72 -16
- data/lib/json/ld/extensions.rb +4 -4
- data/lib/json/ld/flatten.rb +137 -9
- data/lib/json/ld/format.rb +28 -8
- data/lib/json/ld/frame.rb +8 -8
- data/lib/json/ld/from_rdf.rb +46 -16
- data/lib/json/ld/reader.rb +2 -1
- data/lib/json/ld/streaming_reader.rb +5 -5
- 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 +0 -2
- 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/spec_helper.rb +32 -0
- data/spec/suite_flatten_spec.rb +4 -0
- data/spec/suite_frame_spec.rb +7 -0
- data/spec/suite_helper.rb +13 -7
- 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 +66 -64
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2d6d6a64b4f09b881332fe9b54bd2c1d0ad116d590bd457443831ccc5fae3ea9
|
4
|
+
data.tar.gz: 91deee18963670cb94360b5c278dc7a8ae55ccbd897c580a54d291f1f98cfd15
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f96e6b68f363ccd0b96035a66c438ff59801162742fb1b7fd6443684ee2539d34a994f01c95d9019ae46732efdd9eca37539c837af8137efa2fefb9db0930e0f
|
7
|
+
data.tar.gz: 5fe42b5836c6620aa3b485b2622ef94c7d73c63ec3de495779520c697201cdcd2ae4920e3b210f19cc49523e6b1a02b6b73482bc3fc23b7bb9717ba7cd50f04b
|
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
|
-
[![Gem Version](https://badge.fury.io/rb/json-ld.png)](https://
|
6
|
-
[![Build Status](https://secure.travis-ci.org/ruby-rdf/json-ld.png?branch=
|
7
|
-
[![Coverage Status](https://coveralls.io/repos/ruby-rdf/json-ld/badge.svg)](https://coveralls.io/
|
5
|
+
[![Gem Version](https://badge.fury.io/rb/json-ld.png)](https://rubygems.org/gems/json-ld)
|
6
|
+
[![Build Status](https://secure.travis-ci.org/ruby-rdf/json-ld.png?branch=develop)](https://github.com/ruby-rdf/json-ld/actions?query=workflow%3ACI)
|
7
|
+
[![Coverage Status](https://coveralls.io/repos/ruby-rdf/json-ld/badge.svg?branch=develop)](https://coveralls.io/github/ruby-rdf/json-ld?branch=develop)
|
8
|
+
[![Gitter chat](https://badges.gitter.im/ruby-rdf.png)](https://gitter.im/gitterHQ/gitter)
|
8
9
|
|
9
10
|
## Features
|
10
11
|
|
@@ -14,8 +15,9 @@ 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-star][JSON-LD-star].
|
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
|
|
@@ -25,21 +27,91 @@ This gem implements an optimized streaming reader used for generating RDF from l
|
|
25
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.
|
26
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`.
|
27
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
|
+
|
28
37
|
### MultiJson parser
|
29
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.
|
30
39
|
|
31
|
-
### JSON-LD
|
32
|
-
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-star (RDFStar)
|
33
41
|
|
34
|
-
|
35
|
-
|
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-star][JSON-LD-star].
|
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
|
36
105
|
|
37
106
|
## Examples
|
107
|
+
|
38
108
|
```ruby
|
39
109
|
require 'rubygems'
|
40
110
|
require 'json/ld'
|
41
111
|
```
|
112
|
+
|
42
113
|
### Expand a Document
|
114
|
+
|
43
115
|
```ruby
|
44
116
|
input = JSON.parse %({
|
45
117
|
"@context": {
|
@@ -59,8 +131,9 @@ require 'json/ld'
|
|
59
131
|
"http://xmlns.com/foaf/0.1/avatar": [{"@value": "https://twitter.com/account/profile_image/manusporny"}]
|
60
132
|
}]
|
61
133
|
```
|
134
|
+
|
62
135
|
### Compact a Document
|
63
|
-
|
136
|
+
|
64
137
|
input = JSON.parse %([{
|
65
138
|
"http://xmlns.com/foaf/0.1/name": ["Manu Sporny"],
|
66
139
|
"http://xmlns.com/foaf/0.1/homepage": [{"@id": "https://manu.sporny.org/"}],
|
@@ -86,9 +159,9 @@ require 'json/ld'
|
|
86
159
|
"homepage": "https://manu.sporny.org/",
|
87
160
|
"name": "Manu Sporny"
|
88
161
|
}
|
89
|
-
|
162
|
+
|
90
163
|
### Frame a Document
|
91
|
-
|
164
|
+
|
92
165
|
input = JSON.parse %({
|
93
166
|
"@context": {
|
94
167
|
"Book": "http://example.org/vocab#Book",
|
@@ -169,9 +242,9 @@ require 'json/ld'
|
|
169
242
|
}
|
170
243
|
]
|
171
244
|
}
|
172
|
-
|
245
|
+
|
173
246
|
### Turn JSON-LD into RDF (Turtle)
|
174
|
-
|
247
|
+
|
175
248
|
input = JSON.parse %({
|
176
249
|
"@context": {
|
177
250
|
"": "https://manu.sporny.org/",
|
@@ -192,9 +265,9 @@ require 'json/ld'
|
|
192
265
|
<http://example.org/people#joebob> a foaf:Person;
|
193
266
|
foaf:name "Joe Bob";
|
194
267
|
foaf:nick ("joe" "bob" "jaybe") .
|
195
|
-
|
268
|
+
|
196
269
|
### Turn RDF into JSON-LD
|
197
|
-
|
270
|
+
|
198
271
|
require 'rdf/turtle'
|
199
272
|
input = RDF::Graph.new << RDF::Turtle::Reader.new(%(
|
200
273
|
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
|
@@ -230,11 +303,12 @@ require 'json/ld'
|
|
230
303
|
"http://xmlns.com/foaf/0.1/name": [{"@value": "Manu Sporny"}]
|
231
304
|
}
|
232
305
|
]
|
233
|
-
|
306
|
+
|
234
307
|
## Use a custom Document Loader
|
235
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)).
|
236
309
|
|
237
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
|
+
|
238
312
|
```ruby
|
239
313
|
load_document_local = Proc.new do |url, **options, &block|
|
240
314
|
if RDF::URI(url, canonicalize: true) == RDF::URI('http://schema.org/')
|
@@ -244,28 +318,34 @@ load_document_local = Proc.new do |url, **options, &block|
|
|
244
318
|
JSON::LD::API.documentLoader(url, options, &block)
|
245
319
|
end
|
246
320
|
end
|
321
|
+
|
247
322
|
```
|
248
323
|
Then, when performing something like expansion:
|
324
|
+
|
249
325
|
```ruby
|
250
326
|
JSON::LD::API.expand(input, documentLoader: load_document_local)
|
251
327
|
```
|
252
328
|
|
253
329
|
## Preloading contexts
|
254
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
|
+
|
255
332
|
```ruby
|
256
333
|
ctx = JSON::LD::Context.new().parse('http://schema.org/')
|
257
334
|
JSON::LD::Context.add_preloaded('http://schema.org/', ctx)
|
258
335
|
```
|
336
|
+
|
259
337
|
On lookup, URIs with an `https` prefix are normalized to `http`.
|
260
338
|
|
261
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}.
|
262
340
|
|
263
341
|
## RDF Reader and Writer
|
264
342
|
{JSON::LD} also acts as a normal RDF reader and writer, using the standard RDF.rb reader/writer interfaces:
|
343
|
+
|
265
344
|
```ruby
|
266
345
|
graph = RDF::Graph.load("etc/doap.jsonld", format: :jsonld)
|
267
346
|
graph.dump(:jsonld, standard_prefixes: true)
|
268
347
|
```
|
348
|
+
|
269
349
|
`RDF::GRAPH#dump` can also take a `:context` option to use a separately defined context
|
270
350
|
|
271
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 `]`.
|
@@ -275,7 +355,7 @@ This implementation is being used as a test-bed for features planned for an upco
|
|
275
355
|
|
276
356
|
### Scoped Contexts
|
277
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.
|
278
|
-
|
358
|
+
|
279
359
|
{
|
280
360
|
"@context": {
|
281
361
|
"ex": "http://example.com/",
|
@@ -290,10 +370,10 @@ A term definition can include `@context`, which is applied to values of that obj
|
|
290
370
|
},
|
291
371
|
"foo": "Bar"
|
292
372
|
}
|
293
|
-
|
373
|
+
|
294
374
|
### @id and @type maps
|
295
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.
|
296
|
-
|
376
|
+
|
297
377
|
{
|
298
378
|
"@context": {
|
299
379
|
"@vocab": "http://example/",
|
@@ -304,10 +384,10 @@ The value of `@container` in a term definition can include `@id` or `@type`, in
|
|
304
384
|
"_:bar": {"label": "Object with @id _:bar"}
|
305
385
|
}
|
306
386
|
}
|
307
|
-
|
387
|
+
|
308
388
|
### @graph containers and maps
|
309
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.
|
310
|
-
|
390
|
+
|
311
391
|
{
|
312
392
|
"@context": {
|
313
393
|
"@vocab": "http://example.org/",
|
@@ -317,9 +397,9 @@ A term can have `@container` set to include `@graph` optionally including `@id`
|
|
317
397
|
"value": "x"
|
318
398
|
}
|
319
399
|
}
|
320
|
-
|
400
|
+
|
321
401
|
which expands to the following:
|
322
|
-
|
402
|
+
|
323
403
|
[{
|
324
404
|
"http://example.org/input": [{
|
325
405
|
"@graph": [{
|
@@ -327,18 +407,18 @@ which expands to the following:
|
|
327
407
|
}]
|
328
408
|
}]
|
329
409
|
}]
|
330
|
-
|
410
|
+
|
331
411
|
Compaction reverses this process, optionally ensuring that a single value is contained within an array of `@container` also includes `@set`:
|
332
|
-
|
412
|
+
|
333
413
|
{
|
334
414
|
"@context": {
|
335
415
|
"@vocab": "http://example.org/",
|
336
416
|
"input": {"@container": ["@graph", "@set"]}
|
337
417
|
}
|
338
418
|
}
|
339
|
-
|
419
|
+
|
340
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.
|
341
|
-
|
421
|
+
|
342
422
|
{
|
343
423
|
"@context": {
|
344
424
|
"@vocab": "http://example.org/",
|
@@ -348,9 +428,9 @@ A graph map uses the map form already existing for `@index`, `@language`, `@type
|
|
348
428
|
"g1": {"value": "x"}
|
349
429
|
}
|
350
430
|
}
|
351
|
-
|
431
|
+
|
352
432
|
treats "g1" as an index, and expands to the following:
|
353
|
-
|
433
|
+
|
354
434
|
[{
|
355
435
|
"http://example.org/input": [{
|
356
436
|
"@index": "g1",
|
@@ -359,11 +439,11 @@ treats "g1" as an index, and expands to the following:
|
|
359
439
|
}]
|
360
440
|
}]
|
361
441
|
}])
|
362
|
-
|
442
|
+
|
363
443
|
This can also include `@set` to ensure that, when compacting, a single value of an index will be in array form.
|
364
444
|
|
365
445
|
The _id_ version is similar:
|
366
|
-
|
446
|
+
|
367
447
|
{
|
368
448
|
"@context": {
|
369
449
|
"@vocab": "http://example.org/",
|
@@ -373,9 +453,9 @@ The _id_ version is similar:
|
|
373
453
|
"http://example.com/g1": {"value": "x"}
|
374
454
|
}
|
375
455
|
}
|
376
|
-
|
456
|
+
|
377
457
|
which expands to:
|
378
|
-
|
458
|
+
|
379
459
|
[{
|
380
460
|
"http://example.org/input": [{
|
381
461
|
"@id": "http://example.com/g1",
|
@@ -384,10 +464,10 @@ which expands to:
|
|
384
464
|
}]
|
385
465
|
}]
|
386
466
|
}])
|
387
|
-
|
467
|
+
|
388
468
|
### Transparent Nesting
|
389
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:
|
390
|
-
|
470
|
+
|
391
471
|
{
|
392
472
|
"@context": {
|
393
473
|
"skos": "http://www.w3.org/2004/02/skos/core#",
|
@@ -403,9 +483,9 @@ Many JSON APIs separate properties from their entities using an intermediate obj
|
|
403
483
|
"other_label": "This is the other label"
|
404
484
|
}
|
405
485
|
}
|
406
|
-
|
486
|
+
|
407
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:
|
408
|
-
|
488
|
+
|
409
489
|
{
|
410
490
|
"@context": {
|
411
491
|
"skos": "http://www.w3.org/2004/02/skos/core#",
|
@@ -419,9 +499,9 @@ Many JSON APIs separate properties from their entities using an intermediate obj
|
|
419
499
|
"main_label": "This is the main label for my resource",
|
420
500
|
"other_label": "This is the other label"
|
421
501
|
}
|
422
|
-
|
502
|
+
|
423
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.
|
424
|
-
|
504
|
+
|
425
505
|
{
|
426
506
|
"@context": {
|
427
507
|
"skos": "http://www.w3.org/2004/02/skos/core#",
|
@@ -437,7 +517,7 @@ Many JSON APIs separate properties from their entities using an intermediate obj
|
|
437
517
|
"other_label": "This is the other label"
|
438
518
|
}
|
439
519
|
}
|
440
|
-
|
520
|
+
|
441
521
|
In this way, nesting survives round-tripping through expansion, and framed output can include nested properties.
|
442
522
|
|
443
523
|
## Sinatra/Rack support
|
@@ -515,14 +595,14 @@ Note, the API method signatures differed in versions before 1.0, in that they al
|
|
515
595
|
## Installation
|
516
596
|
The recommended installation method is via [RubyGems](https://rubygems.org/).
|
517
597
|
To install the latest official release of the `JSON-LD` gem, do:
|
518
|
-
|
519
|
-
|
520
|
-
|
598
|
+
|
599
|
+
% [sudo] gem install json-ld
|
600
|
+
|
521
601
|
## Download
|
522
602
|
To get a local working copy of the development repository, do:
|
523
|
-
|
524
|
-
|
525
|
-
|
603
|
+
|
604
|
+
% git clone git://github.com/ruby-rdf/json-ld.git
|
605
|
+
|
526
606
|
## Mailing List
|
527
607
|
* <https://lists.w3.org/Archives/Public/public-rdf-ruby/>
|
528
608
|
|
@@ -540,7 +620,9 @@ To get a local working copy of the development repository, do:
|
|
540
620
|
list in the the `README`. Alphabetical order applies.
|
541
621
|
* Do note that in order for us to merge any non-trivial changes (as a rule
|
542
622
|
of thumb, additions larger than about 15 lines of code), we need an
|
543
|
-
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.
|
544
626
|
|
545
627
|
License
|
546
628
|
-------
|
@@ -552,8 +634,9 @@ see <https://unlicense.org/> or the accompanying {file:UNLICENSE} file.
|
|
552
634
|
[RDF]: https://www.w3.org/RDF/
|
553
635
|
[YARD]: https://yardoc.org/
|
554
636
|
[YARD-GS]: https://rubydoc.info/docs/yard/file/docs/GettingStarted.md
|
555
|
-
[PDD]: https://
|
637
|
+
[PDD]: https://unlicense.org/#unlicensing-contributions
|
556
638
|
[RDF.rb]: https://rubygems.org/gems/rdf
|
639
|
+
[JSON-LD-star]: https://json-ld.github.io/json-ld-star/
|
557
640
|
[Rack::LinkedData]: https://rubygems.org/gems/rack-linkeddata
|
558
641
|
[Backports]: https://rubygems.org/gems/backports
|
559
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.9
|
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,41 +19,41 @@ 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
|
54
|
-
reader ||= JSON::LD::Reader.new(input, 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
|
+
reader ||= JSON::LD::Reader.new(input, **parser_options)
|
55
55
|
num = 0
|
56
|
-
RDF::Writer.for(options[:output_format]).new(options[:output], parser_options) do |w|
|
56
|
+
RDF::Writer.for(options[:output_format]).new(options[:output], **parser_options) do |w|
|
57
57
|
reader.each do |statement|
|
58
58
|
num += 1
|
59
59
|
w << statement
|
@@ -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,
|
@@ -114,6 +113,7 @@ OPT_ARGS = [
|
|
114
113
|
["--processingMode",GetoptLong::REQUIRED_ARGUMENT,"Set processing mode, defaults to json-ld-1.1"],
|
115
114
|
["--quiet", GetoptLong::NO_ARGUMENT, "Supress most output other than progress indicators"],
|
116
115
|
["--rename_bnodes", GetoptLong::OPTIONAL_ARGUMENT,"Rename bnodes as part of expansion, or keep them the same"],
|
116
|
+
["--rdfstar", GetoptLong::NO_ARGUMENT, "Parse JSON-LD-star"],
|
117
117
|
["--requireAll", GetoptLong::OPTIONAL_ARGUMENT,"Rename bnodes as part of expansion, or keep them the same"],
|
118
118
|
["--stream", GetoptLong::NO_ARGUMENT, "Use Streaming reader/writer"],
|
119
119
|
["--unique_bnodes", GetoptLong::OPTIONAL_ARGUMENT,"Use unique bnode identifiers"],
|
@@ -142,49 +142,48 @@ opts.each do |opt, arg|
|
|
142
142
|
case opt
|
143
143
|
when '--debug' then logger.level = Logger::DEBUG
|
144
144
|
when '--compact' then options[:compact] = true
|
145
|
-
when "--compactArrays" then
|
146
|
-
when '--context' then
|
145
|
+
when "--compactArrays" then parser_options[:compactArrays] = (arg || 'true') == 'true'
|
146
|
+
when '--context' then parser_options[:context] = RDF::URI(arg).absolute? ? arg : File.open(arg)
|
147
147
|
when '--evaluate' then input = arg
|
148
148
|
when '--expand' then options[:expand] = true
|
149
|
-
when "--expanded" then
|
150
|
-
when "--explicit" then
|
149
|
+
when "--expanded" then parser_options[:expanded] = (arg || 'true') == 'true'
|
150
|
+
when "--explicit" then parser_options[:compactArrays] = (arg || 'true') == 'true'
|
151
151
|
when '--format' then options[:output_format] = arg.to_sym
|
152
152
|
when '--flatten' then options[:flatten] = arg
|
153
|
-
when '--frame' then options[:frame] = arg
|
153
|
+
when '--frame' then options[:frame] = parser_otpions[:frame] = RDF::URI(arg).absolute? ? arg : File.open(arg)
|
154
154
|
when '--input-format' then options[:input_format] = arg.to_sym
|
155
|
-
when "--omitDefault" then
|
155
|
+
when "--omitDefault" then parser_options[:omitDefault] = (arg || 'true') == 'true'
|
156
156
|
when '--output' then options[:output] = File.open(arg, "w")
|
157
157
|
when '--parse-only' then options[:parse_only] = true
|
158
|
-
when '--processingMode' then
|
158
|
+
when '--processingMode' then parser_options[:processingMode] = arg
|
159
159
|
when '--quiet'
|
160
160
|
options[:quiet] = true
|
161
161
|
logger.level = Logger::FATAL
|
162
|
-
when "--
|
163
|
-
when "--
|
162
|
+
when "--rdfstar" then parser_options[:rdfstar] = true
|
163
|
+
when "--rename_bnodes" then parser_options[:rename_bnodes] = (arg || 'true') == 'true'
|
164
|
+
when "--requireAll" then parser_options[:requireAll] = (arg || 'true') == 'true'
|
164
165
|
when '--stream' then parser_options[:stream] = true
|
165
|
-
when "--unique_bnodes" then
|
166
|
+
when "--unique_bnodes" then parser_options[:unique_bnodes] = (arg || 'true') == 'true'
|
166
167
|
when '--uri' then parser_options[:base] = arg
|
167
168
|
when '--validate' then parser_options[:validate] = true
|
168
169
|
when '--help' then usage
|
169
170
|
when '--embed'
|
170
171
|
case arg
|
171
|
-
when '@always', '@never', '@link', '@
|
172
|
-
|
172
|
+
when '@always', '@never', '@link', '@once'
|
173
|
+
parser_options[:embed] = arg
|
173
174
|
when 'true'
|
174
|
-
|
175
|
+
parser_options[:embed] = '@never'
|
175
176
|
when 'false'
|
176
|
-
|
177
|
+
parser_options[:embed] = '@first'
|
177
178
|
else
|
178
|
-
STDERR.puts "--embed option takes one of @always, @never, @link,
|
179
|
+
STDERR.puts "--embed option takes one of @always, @never, @link, or @once"
|
179
180
|
exit(1)
|
180
181
|
end
|
181
182
|
end
|
182
183
|
end
|
183
184
|
|
184
185
|
# Hack
|
185
|
-
options
|
186
|
-
|
187
|
-
if !(options.keys & [:expand, :compact, :flatten, :frame]).empty? &&
|
186
|
+
if !(options.keys & %i{expand compact flatten frame}).empty? &&
|
188
187
|
(parser_options[:stream] || options[:output_format] != :jsonld)
|
189
188
|
STDERR.puts "Incompatible options"
|
190
189
|
exit(1)
|
@@ -192,11 +191,11 @@ end
|
|
192
191
|
|
193
192
|
if ARGV.empty?
|
194
193
|
s = input ? input : $stdin.read
|
195
|
-
run(StringIO.new(s), options)
|
194
|
+
run(StringIO.new(s), options, parser_options)
|
196
195
|
else
|
197
196
|
ARGV.each do |file|
|
198
197
|
# Call with opened files
|
199
|
-
RDF::Util::File.open_file(file, options) {|f| run(f, options)}
|
198
|
+
RDF::Util::File.open_file(file, **options) {|f| run(f, options, parser_options)}
|
200
199
|
end
|
201
200
|
end
|
202
201
|
puts
|