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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4755155aaabbcf15c3f29429eb085ac5e54c0785df8a84ebb42d8dbbb840c9b3
4
- data.tar.gz: e8f5a6fc936ee33473f8f54ae9ee1587816b3146f4c94e179eebb2ebaa85feea
3
+ metadata.gz: 2d6d6a64b4f09b881332fe9b54bd2c1d0ad116d590bd457443831ccc5fae3ea9
4
+ data.tar.gz: 91deee18963670cb94360b5c278dc7a8ae55ccbd897c580a54d291f1f98cfd15
5
5
  SHA512:
6
- metadata.gz: 8ebbbad6fde10f4ce69d8485292a580d2d9dc9cf1ffafcd878efb03a3c47bdfcd2188f1f50ec3a4d96b1a3cf7718d5926118f0283204f7420765e691d5782b78
7
- data.tar.gz: bb86cdff64bceb60c574e5a72448394c9882817990b4a734e29ab1f6bc2f177fabf2fb0437bfa5c312ca87a1f7be10123cae1bc45db8722fb1029701cb38f16c
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://badge.fury.io/rb/json-ld)
6
- [![Build Status](https://secure.travis-ci.org/ruby-rdf/json-ld.png?branch=master)](https://travis-ci.org/ruby-rdf/json-ld)
7
- [![Coverage Status](https://coveralls.io/repos/ruby-rdf/json-ld/badge.svg)](https://coveralls.io/r/ruby-rdf/json-ld)
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](file.earl.html)
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 Streaming Profile
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
- * Each statement written as a separate node in expanded/flattened form.
35
- * RDF Lists are written as separate nodes using `rdf:first` and `rdf:rest` properties.
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
- ```ruby
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
- ```ruby
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
- ```ruby
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
- ```ruby
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
- ```ruby
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
- ```ruby
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
- ```ruby
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
- ```ruby
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
- ```ruby
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
- ```ruby
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
- ```ruby
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
- ```ruby
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
- ```ruby
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
- ```json
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
- ```json
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
- ```json
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
- ```bash
519
- % [sudo] gem install json-ld
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
- ```bash
524
- % git clone git://github.com/ruby-rdf/json-ld.git
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://lists.w3.org/Archives/Public/public-rdf-ruby/2010May/0013.html
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.4
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, options[:parser_options])
22
+ reader_class.new(input, parser_options)
23
23
  end
24
24
 
25
25
  start = Time.new
26
26
  if options[:expand]
27
- options = options.merge(expandContext: options.delete(:context)) if options.has_key?(:context)
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, options)
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, options[:context], options)
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, options[:context], options)
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, options[:frame], options)
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
- options = options.merge(expandContext: options.delete(:context)) if options.has_key?(:context)
53
- parser_options = options[:parser_options].merge(standard_prefixes: true)
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 options[:compactArrays] = (arg || 'true') == 'true'
146
- when '--context' then options[:context] = arg
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 options[:expanded] = (arg || 'true') == 'true'
150
- when "--explicit" then options[:compactArrays] = (arg || 'true') == 'true'
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 options[:omitDefault] = (arg || 'true') == 'true'
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 options[:processingMode] = arg
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 "--rename_bnodes" then options[:rename_bnodes] = (arg || 'true') == 'true'
163
- when "--requireAll" then options[:requireAll] = (arg || 'true') == 'true'
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 options[:unique_bnodes] = (arg || 'true') == 'true'
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', '@last', '@first'
172
- options[:embed] = arg
172
+ when '@always', '@never', '@link', '@once'
173
+ parser_options[:embed] = arg
173
174
  when 'true'
174
- options[:embed] = '@never'
175
+ parser_options[:embed] = '@never'
175
176
  when 'false'
176
- options[:embed] = '@first'
177
+ parser_options[:embed] = '@first'
177
178
  else
178
- STDERR.puts "--embed option takes one of @always, @never, @link, @first, or @last"
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[:parser_options][:context] = options[:context] if parser_options[:stream]
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