json-ld 3.1.3 → 3.1.8
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
[![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,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
|