json-ld 3.1.2 → 3.1.7
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 +124 -48
- data/VERSION +1 -1
- data/bin/jsonld +27 -30
- data/lib/json/ld.rb +6 -2
- data/lib/json/ld/api.rb +33 -24
- data/lib/json/ld/compact.rb +65 -37
- data/lib/json/ld/conneg.rb +1 -1
- data/lib/json/ld/context.rb +612 -539
- data/lib/json/ld/expand.rb +158 -77
- data/lib/json/ld/format.rb +20 -7
- data/lib/json/ld/from_rdf.rb +40 -17
- data/lib/json/ld/reader.rb +20 -11
- data/lib/json/ld/streaming_reader.rb +578 -0
- data/lib/json/ld/to_rdf.rb +9 -5
- data/lib/json/ld/writer.rb +10 -3
- data/spec/compact_spec.rb +207 -2
- data/spec/context_spec.rb +13 -60
- data/spec/expand_spec.rb +248 -0
- data/spec/from_rdf_spec.rb +181 -0
- data/spec/matchers.rb +1 -1
- data/spec/reader_spec.rb +33 -34
- data/spec/streaming_reader_spec.rb +237 -0
- data/spec/suite_helper.rb +14 -8
- data/spec/suite_to_rdf_spec.rb +1 -0
- data/spec/to_rdf_spec.rb +206 -0
- data/spec/writer_spec.rb +193 -0
- metadata +9 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b9345f0853c9ee6d7e1bb91817ca7d9effc1ce5d591f98fa92a11c396c1f0fbb
|
4
|
+
data.tar.gz: 7a84d8f7b4dd0fe379dd8b915d6e899f610807959d9ea4ef66c0ab4c22657807
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d2ff1429edeea61f1655e445862140b5477dfa978cfaeaa3a417417fff24adfc17b6adea77cb24041c8c3daafaf7661d05023a3f1e2e4c161194be7dc4c96dd7
|
7
|
+
data.tar.gz: e04b64a78d9bfdc88d808219440b758540a3e6bd2f7dae4ee73831b093ab8ada77641acfc2c4c079b413f17b0d88a0149058fa3959c2fbdd6e0d421c8885fa5a
|
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)
|
8
|
+
[](https://gitter.im/gitterHQ/gitter)
|
8
9
|
|
9
10
|
## Features
|
10
11
|
|
@@ -14,26 +15,90 @@ 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
20
|
[Implementation Report](file.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.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
|
+
**Note: This feature is subject to change or elimination as the standards process progresses.**
|
59
|
+
|
60
|
+
#### Serializing a Graph containing embedded statements
|
61
|
+
|
62
|
+
require 'json-ld'
|
63
|
+
statement = RDF::Statement(RDF::URI('bob'), RDF::Vocab::FOAF.age, RDF::Literal(23))
|
64
|
+
graph = RDF::Graph.new << [statement, RDF::URI("ex:certainty"), RDF::Literal(0.9)]
|
65
|
+
graph.dump(:jsonld, validate: false, standard_prefixes: true)
|
66
|
+
# => {"@id": {"@id": "bob", "foaf:age" 23}, "ex:certainty": 0.9}
|
67
|
+
|
68
|
+
Alternatively, using the {JSON::LD::API.fromRdf} method:
|
69
|
+
|
70
|
+
JSON::LD::API::fromRdf(graph)
|
71
|
+
# => {"@id": {"@id": "bob", "foaf:age" 23}, "ex:certainty": 0.9}
|
72
|
+
|
73
|
+
#### Reading a Graph containing embedded statements
|
74
|
+
|
75
|
+
By default, {JSON::LD::API.toRdf} (and {JSON::LD::Reader}) will reject a document containing a subject resource.
|
76
|
+
|
77
|
+
jsonld = %({
|
78
|
+
"@id": {
|
79
|
+
"@id": "bob", "foaf:age" 23
|
80
|
+
},
|
81
|
+
"ex:certainty": 0.9
|
82
|
+
})
|
83
|
+
graph = RDF::Graph.new << JSON::LD::API.toRdf(input)
|
84
|
+
# => JSON::LD::JsonLdError::InvalidIdValue
|
85
|
+
|
86
|
+
{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.
|
87
|
+
|
88
|
+
graph = RDF::Graph.new do |graph|
|
89
|
+
JSON::LD::Reader.new(jsonld, rdfstar: true) {|reader| graph << reader}
|
90
|
+
end
|
91
|
+
graph.count #=> 1
|
30
92
|
|
31
93
|
## Examples
|
94
|
+
|
32
95
|
```ruby
|
33
96
|
require 'rubygems'
|
34
97
|
require 'json/ld'
|
35
98
|
```
|
99
|
+
|
36
100
|
### Expand a Document
|
101
|
+
|
37
102
|
```ruby
|
38
103
|
input = JSON.parse %({
|
39
104
|
"@context": {
|
@@ -53,8 +118,9 @@ require 'json/ld'
|
|
53
118
|
"http://xmlns.com/foaf/0.1/avatar": [{"@value": "https://twitter.com/account/profile_image/manusporny"}]
|
54
119
|
}]
|
55
120
|
```
|
121
|
+
|
56
122
|
### Compact a Document
|
57
|
-
|
123
|
+
|
58
124
|
input = JSON.parse %([{
|
59
125
|
"http://xmlns.com/foaf/0.1/name": ["Manu Sporny"],
|
60
126
|
"http://xmlns.com/foaf/0.1/homepage": [{"@id": "https://manu.sporny.org/"}],
|
@@ -80,9 +146,9 @@ require 'json/ld'
|
|
80
146
|
"homepage": "https://manu.sporny.org/",
|
81
147
|
"name": "Manu Sporny"
|
82
148
|
}
|
83
|
-
|
149
|
+
|
84
150
|
### Frame a Document
|
85
|
-
|
151
|
+
|
86
152
|
input = JSON.parse %({
|
87
153
|
"@context": {
|
88
154
|
"Book": "http://example.org/vocab#Book",
|
@@ -163,9 +229,9 @@ require 'json/ld'
|
|
163
229
|
}
|
164
230
|
]
|
165
231
|
}
|
166
|
-
|
232
|
+
|
167
233
|
### Turn JSON-LD into RDF (Turtle)
|
168
|
-
|
234
|
+
|
169
235
|
input = JSON.parse %({
|
170
236
|
"@context": {
|
171
237
|
"": "https://manu.sporny.org/",
|
@@ -186,9 +252,9 @@ require 'json/ld'
|
|
186
252
|
<http://example.org/people#joebob> a foaf:Person;
|
187
253
|
foaf:name "Joe Bob";
|
188
254
|
foaf:nick ("joe" "bob" "jaybe") .
|
189
|
-
|
255
|
+
|
190
256
|
### Turn RDF into JSON-LD
|
191
|
-
|
257
|
+
|
192
258
|
require 'rdf/turtle'
|
193
259
|
input = RDF::Graph.new << RDF::Turtle::Reader.new(%(
|
194
260
|
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
|
@@ -224,13 +290,14 @@ require 'json/ld'
|
|
224
290
|
"http://xmlns.com/foaf/0.1/name": [{"@value": "Manu Sporny"}]
|
225
291
|
}
|
226
292
|
]
|
227
|
-
|
293
|
+
|
228
294
|
## Use a custom Document Loader
|
229
295
|
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
296
|
|
231
297
|
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:
|
298
|
+
|
232
299
|
```ruby
|
233
|
-
|
300
|
+
load_document_local = Proc.new do |url, **options, &block|
|
234
301
|
if RDF::URI(url, canonicalize: true) == RDF::URI('http://schema.org/')
|
235
302
|
remote_document = JSON::LD::API::RemoteDocument.new(url, File.read("etc/schema.org.jsonld"))
|
236
303
|
return block_given? ? yield(remote_document) : remote_document
|
@@ -238,28 +305,34 @@ def load_document_local(url, options={}, &block)
|
|
238
305
|
JSON::LD::API.documentLoader(url, options, &block)
|
239
306
|
end
|
240
307
|
end
|
308
|
+
|
241
309
|
```
|
242
310
|
Then, when performing something like expansion:
|
311
|
+
|
243
312
|
```ruby
|
244
313
|
JSON::LD::API.expand(input, documentLoader: load_document_local)
|
245
314
|
```
|
246
315
|
|
247
316
|
## Preloading contexts
|
248
317
|
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.
|
318
|
+
|
249
319
|
```ruby
|
250
320
|
ctx = JSON::LD::Context.new().parse('http://schema.org/')
|
251
321
|
JSON::LD::Context.add_preloaded('http://schema.org/', ctx)
|
252
322
|
```
|
323
|
+
|
253
324
|
On lookup, URIs with an `https` prefix are normalized to `http`.
|
254
325
|
|
255
326
|
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
327
|
|
257
328
|
## RDF Reader and Writer
|
258
329
|
{JSON::LD} also acts as a normal RDF reader and writer, using the standard RDF.rb reader/writer interfaces:
|
330
|
+
|
259
331
|
```ruby
|
260
332
|
graph = RDF::Graph.load("etc/doap.jsonld", format: :jsonld)
|
261
333
|
graph.dump(:jsonld, standard_prefixes: true)
|
262
334
|
```
|
335
|
+
|
263
336
|
`RDF::GRAPH#dump` can also take a `:context` option to use a separately defined context
|
264
337
|
|
265
338
|
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 +342,7 @@ This implementation is being used as a test-bed for features planned for an upco
|
|
269
342
|
|
270
343
|
### Scoped Contexts
|
271
344
|
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
|
-
|
345
|
+
|
273
346
|
{
|
274
347
|
"@context": {
|
275
348
|
"ex": "http://example.com/",
|
@@ -284,10 +357,10 @@ A term definition can include `@context`, which is applied to values of that obj
|
|
284
357
|
},
|
285
358
|
"foo": "Bar"
|
286
359
|
}
|
287
|
-
|
360
|
+
|
288
361
|
### @id and @type maps
|
289
362
|
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
|
-
|
363
|
+
|
291
364
|
{
|
292
365
|
"@context": {
|
293
366
|
"@vocab": "http://example/",
|
@@ -298,10 +371,10 @@ The value of `@container` in a term definition can include `@id` or `@type`, in
|
|
298
371
|
"_:bar": {"label": "Object with @id _:bar"}
|
299
372
|
}
|
300
373
|
}
|
301
|
-
|
374
|
+
|
302
375
|
### @graph containers and maps
|
303
376
|
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
|
-
|
377
|
+
|
305
378
|
{
|
306
379
|
"@context": {
|
307
380
|
"@vocab": "http://example.org/",
|
@@ -311,9 +384,9 @@ A term can have `@container` set to include `@graph` optionally including `@id`
|
|
311
384
|
"value": "x"
|
312
385
|
}
|
313
386
|
}
|
314
|
-
|
387
|
+
|
315
388
|
which expands to the following:
|
316
|
-
|
389
|
+
|
317
390
|
[{
|
318
391
|
"http://example.org/input": [{
|
319
392
|
"@graph": [{
|
@@ -321,18 +394,18 @@ which expands to the following:
|
|
321
394
|
}]
|
322
395
|
}]
|
323
396
|
}]
|
324
|
-
|
397
|
+
|
325
398
|
Compaction reverses this process, optionally ensuring that a single value is contained within an array of `@container` also includes `@set`:
|
326
|
-
|
399
|
+
|
327
400
|
{
|
328
401
|
"@context": {
|
329
402
|
"@vocab": "http://example.org/",
|
330
403
|
"input": {"@container": ["@graph", "@set"]}
|
331
404
|
}
|
332
405
|
}
|
333
|
-
|
406
|
+
|
334
407
|
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
|
-
|
408
|
+
|
336
409
|
{
|
337
410
|
"@context": {
|
338
411
|
"@vocab": "http://example.org/",
|
@@ -342,9 +415,9 @@ A graph map uses the map form already existing for `@index`, `@language`, `@type
|
|
342
415
|
"g1": {"value": "x"}
|
343
416
|
}
|
344
417
|
}
|
345
|
-
|
418
|
+
|
346
419
|
treats "g1" as an index, and expands to the following:
|
347
|
-
|
420
|
+
|
348
421
|
[{
|
349
422
|
"http://example.org/input": [{
|
350
423
|
"@index": "g1",
|
@@ -353,11 +426,11 @@ treats "g1" as an index, and expands to the following:
|
|
353
426
|
}]
|
354
427
|
}]
|
355
428
|
}])
|
356
|
-
|
429
|
+
|
357
430
|
This can also include `@set` to ensure that, when compacting, a single value of an index will be in array form.
|
358
431
|
|
359
432
|
The _id_ version is similar:
|
360
|
-
|
433
|
+
|
361
434
|
{
|
362
435
|
"@context": {
|
363
436
|
"@vocab": "http://example.org/",
|
@@ -367,9 +440,9 @@ The _id_ version is similar:
|
|
367
440
|
"http://example.com/g1": {"value": "x"}
|
368
441
|
}
|
369
442
|
}
|
370
|
-
|
443
|
+
|
371
444
|
which expands to:
|
372
|
-
|
445
|
+
|
373
446
|
[{
|
374
447
|
"http://example.org/input": [{
|
375
448
|
"@id": "http://example.com/g1",
|
@@ -378,10 +451,10 @@ which expands to:
|
|
378
451
|
}]
|
379
452
|
}]
|
380
453
|
}])
|
381
|
-
|
454
|
+
|
382
455
|
### Transparent Nesting
|
383
456
|
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
|
-
|
457
|
+
|
385
458
|
{
|
386
459
|
"@context": {
|
387
460
|
"skos": "http://www.w3.org/2004/02/skos/core#",
|
@@ -397,9 +470,9 @@ Many JSON APIs separate properties from their entities using an intermediate obj
|
|
397
470
|
"other_label": "This is the other label"
|
398
471
|
}
|
399
472
|
}
|
400
|
-
|
473
|
+
|
401
474
|
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
|
-
|
475
|
+
|
403
476
|
{
|
404
477
|
"@context": {
|
405
478
|
"skos": "http://www.w3.org/2004/02/skos/core#",
|
@@ -413,9 +486,9 @@ Many JSON APIs separate properties from their entities using an intermediate obj
|
|
413
486
|
"main_label": "This is the main label for my resource",
|
414
487
|
"other_label": "This is the other label"
|
415
488
|
}
|
416
|
-
|
489
|
+
|
417
490
|
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
|
-
|
491
|
+
|
419
492
|
{
|
420
493
|
"@context": {
|
421
494
|
"skos": "http://www.w3.org/2004/02/skos/core#",
|
@@ -431,7 +504,7 @@ Many JSON APIs separate properties from their entities using an intermediate obj
|
|
431
504
|
"other_label": "This is the other label"
|
432
505
|
}
|
433
506
|
}
|
434
|
-
|
507
|
+
|
435
508
|
In this way, nesting survives round-tripping through expansion, and framed output can include nested properties.
|
436
509
|
|
437
510
|
## Sinatra/Rack support
|
@@ -509,14 +582,14 @@ Note, the API method signatures differed in versions before 1.0, in that they al
|
|
509
582
|
## Installation
|
510
583
|
The recommended installation method is via [RubyGems](https://rubygems.org/).
|
511
584
|
To install the latest official release of the `JSON-LD` gem, do:
|
512
|
-
|
513
|
-
|
514
|
-
|
585
|
+
|
586
|
+
% [sudo] gem install json-ld
|
587
|
+
|
515
588
|
## Download
|
516
589
|
To get a local working copy of the development repository, do:
|
517
|
-
|
518
|
-
|
519
|
-
|
590
|
+
|
591
|
+
% git clone git://github.com/ruby-rdf/json-ld.git
|
592
|
+
|
520
593
|
## Mailing List
|
521
594
|
* <https://lists.w3.org/Archives/Public/public-rdf-ruby/>
|
522
595
|
|
@@ -534,7 +607,9 @@ To get a local working copy of the development repository, do:
|
|
534
607
|
list in the the `README`. Alphabetical order applies.
|
535
608
|
* Do note that in order for us to merge any non-trivial changes (as a rule
|
536
609
|
of thumb, additions larger than about 15 lines of code), we need an
|
537
|
-
explicit [public domain dedication][PDD] on record from you
|
610
|
+
explicit [public domain dedication][PDD] on record from you,
|
611
|
+
which you will be asked to agree to on the first commit to a repo within the organization.
|
612
|
+
Note that the agreement applies to all repos in the [Ruby RDF](https://github.com/ruby-rdf/) organization.
|
538
613
|
|
539
614
|
License
|
540
615
|
-------
|
@@ -546,8 +621,9 @@ see <https://unlicense.org/> or the accompanying {file:UNLICENSE} file.
|
|
546
621
|
[RDF]: https://www.w3.org/RDF/
|
547
622
|
[YARD]: https://yardoc.org/
|
548
623
|
[YARD-GS]: https://rubydoc.info/docs/yard/file/docs/GettingStarted.md
|
549
|
-
[PDD]: https://
|
624
|
+
[PDD]: https://unlicense.org/#unlicensing-contributions
|
550
625
|
[RDF.rb]: https://rubygems.org/gems/rdf
|
626
|
+
[JSON-LD*]: https://json-ld.github.io/json-ld-star/
|
551
627
|
[Rack::LinkedData]: https://rubygems.org/gems/rack-linkeddata
|
552
628
|
[Backports]: https://rubygems.org/gems/backports
|
553
629
|
[JSON-LD]: https://www.w3.org/TR/json-ld11/ "JSON-LD 1.1"
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.1.
|
1
|
+
3.1.7
|
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.has_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.has_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,49 +140,47 @@ 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[:parser_options][:context] = options[:context] if parser_options[:stream]
|
186
|
-
|
187
184
|
if !(options.keys & [:expand, :compact, :flatten, :frame]).empty? &&
|
188
185
|
(parser_options[:stream] || options[:output_format] != :jsonld)
|
189
186
|
STDERR.puts "Incompatible options"
|
@@ -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
|