json-ld 3.2.0 → 3.2.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +6 -7
- data/VERSION +1 -1
- data/lib/json/ld/api.rb +55 -16
- data/lib/json/ld/context.rb +7 -7
- data/lib/json/ld/expand.rb +2 -2
- data/lib/json/ld/format.rb +83 -116
- data/lib/json/ld/reader.rb +2 -2
- data/lib/json/ld/streaming_reader.rb +2 -1
- data/lib/json/ld/to_rdf.rb +9 -8
- data/lib/json/ld/writer.rb +9 -10
- data/lib/json/ld.rb +3 -0
- data/spec/api_spec.rb +67 -19
- data/spec/format_spec.rb +7 -3
- data/spec/frame_spec.rb +25 -1
- data/spec/reader_spec.rb +14 -14
- data/spec/suite_helper.rb +1 -0
- data/spec/test-files/{test-1-compacted.json → test-1-compacted.jsonld} +0 -0
- data/spec/test-files/{test-1-context.json → test-1-context.jsonld} +0 -0
- data/spec/test-files/{test-1-expanded.json → test-1-expanded.jsonld} +0 -0
- data/spec/test-files/{test-1-input.json → test-1-input.jsonld} +0 -0
- data/spec/test-files/{test-2-compacted.json → test-2-compacted.jsonld} +0 -0
- data/spec/test-files/{test-2-context.json → test-2-context.jsonld} +0 -0
- data/spec/test-files/{test-2-expanded.json → test-2-expanded.jsonld} +0 -0
- data/spec/test-files/{test-2-input.json → test-2-input.jsonld} +0 -0
- data/spec/test-files/{test-3-compacted.json → test-3-compacted.jsonld} +0 -0
- data/spec/test-files/{test-3-context.json → test-3-context.jsonld} +0 -0
- data/spec/test-files/{test-3-expanded.json → test-3-expanded.jsonld} +0 -0
- data/spec/test-files/{test-3-input.json → test-3-input.jsonld} +0 -0
- data/spec/test-files/{test-4-compacted.json → test-4-compacted.jsonld} +0 -0
- data/spec/test-files/{test-4-context.json → test-4-context.jsonld} +0 -0
- data/spec/test-files/{test-4-expanded.json → test-4-expanded.jsonld} +0 -0
- data/spec/test-files/{test-4-input.json → test-4-input.jsonld} +0 -0
- data/spec/test-files/{test-5-compacted.json → test-5-compacted.jsonld} +0 -0
- data/spec/test-files/{test-5-context.json → test-5-context.jsonld} +0 -0
- data/spec/test-files/{test-5-expanded.json → test-5-expanded.jsonld} +0 -0
- data/spec/test-files/{test-5-input.json → test-5-input.jsonld} +0 -0
- data/spec/test-files/{test-6-compacted.json → test-6-compacted.jsonld} +0 -0
- data/spec/test-files/{test-6-context.json → test-6-context.jsonld} +0 -0
- data/spec/test-files/{test-6-expanded.json → test-6-expanded.jsonld} +0 -0
- data/spec/test-files/{test-6-input.json → test-6-input.jsonld} +0 -0
- data/spec/test-files/{test-7-compacted.json → test-7-compacted.jsonld} +0 -0
- data/spec/test-files/{test-7-context.json → test-7-context.jsonld} +0 -0
- data/spec/test-files/{test-7-expanded.json → test-7-expanded.jsonld} +0 -0
- data/spec/test-files/{test-7-input.json → test-7-input.jsonld} +0 -0
- data/spec/test-files/{test-8-compacted.json → test-8-compacted.jsonld} +0 -0
- data/spec/test-files/{test-8-context.json → test-8-context.jsonld} +0 -0
- data/spec/test-files/{test-8-expanded.json → test-8-expanded.jsonld} +0 -0
- data/spec/test-files/{test-8-frame.json → test-8-frame.jsonld} +0 -0
- data/spec/test-files/{test-8-framed.json → test-8-framed.jsonld} +0 -0
- data/spec/test-files/{test-8-input.json → test-8-input.jsonld} +0 -0
- data/spec/test-files/{test-9-compacted.json → test-9-compacted.jsonld} +0 -0
- data/spec/test-files/{test-9-context.json → test-9-context.jsonld} +0 -0
- data/spec/test-files/{test-9-expanded.json → test-9-expanded.jsonld} +0 -0
- data/spec/test-files/{test-9-input.json → test-9-input.jsonld} +0 -0
- metadata +94 -89
- data/spec/test-files/test-1-normalized.json +0 -8
- data/spec/test-files/test-2-normalized.json +0 -32
- data/spec/test-files/test-3-normalized.json +0 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ff11a49b52d7ca0faf6deaac7324f08530747b53ec857ebe007c027a1bf412b4
|
4
|
+
data.tar.gz: b0a808fc12be08ecaa47f399c0f20ff26120cc36820bf45d6c434ad1f31f53e3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c3e17fbb3280f393ece72136d09182d1032982ca116d49577f03dc72ca35ebc8193495054a1944e525acdad8ae67ce6cb341f6859c5e97a7d2497ca047d7ee40
|
7
|
+
data.tar.gz: eef60e136ca7d86ac66cd0b74d5b01862b4f5c7039352c7d6e678b73ab783bf7bbf2f397f7fd928421bc52e332389cab1432e69175d6fa0d260dfcf7a315a66a
|
data/README.md
CHANGED
@@ -32,10 +32,10 @@ This gem also implements an optimized streaming writer used for generating JSON-
|
|
32
32
|
* Each statement written as a separate node in expanded/flattened form.
|
33
33
|
* `RDF List`s are written as separate nodes using `rdf:first` and `rdf:rest` properties.
|
34
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_,
|
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_, _subject_, _predicate_ and _object_.
|
36
36
|
|
37
37
|
### MultiJson parser
|
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.
|
38
|
+
The [MultiJson](https://rubygems.org/gems/multi_json) gem is used for parsing and serializing JSON; this defaults to the native JSON parser/serializer, 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. Additionally, a custom serialilzer may be specified by passing the `:serializer` option to {JSON::LD::Writer} or methods of {JSON::LD::API}. See [MultiJson](https://rubygems.org/gems/multi_json) for more information.
|
39
39
|
|
40
40
|
### JSON-LD-star (RDFStar)
|
41
41
|
|
@@ -72,7 +72,7 @@ In the first case, the embedded node is not asserted, and only appears as the su
|
|
72
72
|
|
73
73
|
#### Serializing a Graph containing embedded statements
|
74
74
|
|
75
|
-
require 'json
|
75
|
+
require 'json/ld'
|
76
76
|
statement = RDF::Statement(RDF::URI('bob'), RDF::Vocab::FOAF.age, RDF::Literal(23))
|
77
77
|
graph = RDF::Graph.new << [statement, RDF::URI("ex:certainty"), RDF::Literal(0.9)]
|
78
78
|
graph.dump(:jsonld, validate: false, standard_prefixes: true)
|
@@ -565,7 +565,7 @@ The {JSON::LD::ContentNegotiation#call} method looks for a result which includes
|
|
565
565
|
See [Rack::LinkedData][] to do the same thing with an RDF Graph or Dataset as the source, rather than Ruby objects.
|
566
566
|
|
567
567
|
## Documentation
|
568
|
-
Full documentation available on [RubyDoc](https://
|
568
|
+
Full documentation available on [RubyDoc](https://ruby-rdf.github.io/json-ld/file/README.md)
|
569
569
|
|
570
570
|
## Differences from [JSON-LD API][]
|
571
571
|
The specified JSON-LD API is based on a WebIDL definition implementing [Promises][] intended for use within a browser.
|
@@ -624,8 +624,7 @@ To get a local working copy of the development repository, do:
|
|
624
624
|
which you will be asked to agree to on the first commit to a repo within the organization.
|
625
625
|
Note that the agreement applies to all repos in the [Ruby RDF](https://github.com/ruby-rdf/) organization.
|
626
626
|
|
627
|
-
License
|
628
|
-
-------
|
627
|
+
## License
|
629
628
|
|
630
629
|
This is free and unencumbered public domain software. For more information,
|
631
630
|
see <https://unlicense.org/> or the accompanying {file:UNLICENSE} file.
|
@@ -641,7 +640,7 @@ see <https://unlicense.org/> or the accompanying {file:UNLICENSE} file.
|
|
641
640
|
[Backports]: https://rubygems.org/gems/backports
|
642
641
|
[JSON-LD]: https://www.w3.org/TR/json-ld11/ "JSON-LD 1.1"
|
643
642
|
[JSON-LD API]: https://www.w3.org/TR/json-ld11-api/ "JSON-LD 1.1 Processing Algorithms and API"
|
644
|
-
[JSON-LD Framing]: https://www.w3.org/TR/json-ld11-framing/ "JSON-LD
|
643
|
+
[JSON-LD Framing]: https://www.w3.org/TR/json-ld11-framing/ "JSON-LD 1.1 Framing"
|
645
644
|
[Promises]: https://dom.spec.whatwg.org/#promises
|
646
645
|
[jsonlint]: https://rubygems.org/gems/jsonlint
|
647
646
|
[Sinatra]: https://www.sinatrarb.com/
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.2.
|
1
|
+
3.2.3
|
data/lib/json/ld/api.rb
CHANGED
@@ -126,7 +126,8 @@ module JSON::LD
|
|
126
126
|
|
127
127
|
case remote_doc.document
|
128
128
|
when String
|
129
|
-
|
129
|
+
mj_opts = options.keep_if {|k,v| k != :adapter || MUTLI_JSON_ADAPTERS.include?(v)}
|
130
|
+
MultiJson.load(remote_doc.document, **mj_opts)
|
130
131
|
else
|
131
132
|
# Already parsed
|
132
133
|
remote_doc.document
|
@@ -155,6 +156,9 @@ module JSON::LD
|
|
155
156
|
#
|
156
157
|
# @param [String, #read, Hash, Array] input
|
157
158
|
# The JSON-LD object to copy and perform the expansion upon.
|
159
|
+
# @param [Proc] serializer (nil)
|
160
|
+
# A Serializer method used for generating the JSON serialization of the result. If absent, the internal Ruby objects are returned, which can be transformed to JSON externally via `#to_json`.
|
161
|
+
# See {JSON::LD::API.serializer}.
|
158
162
|
# @param [Hash{Symbol => Object}] options
|
159
163
|
# @option options (see #initialize)
|
160
164
|
# @raise [JsonLdError]
|
@@ -167,7 +171,7 @@ module JSON::LD
|
|
167
171
|
# @return [Object, Array<Hash>]
|
168
172
|
# If a block is given, the result of evaluating the block is returned, otherwise, the expanded JSON-LD document
|
169
173
|
# @see https://www.w3.org/TR/json-ld11-api/#expansion-algorithm
|
170
|
-
def self.expand(input, framing: false, **options, &block)
|
174
|
+
def self.expand(input, framing: false, serializer: nil, **options, &block)
|
171
175
|
result = doc_base = nil
|
172
176
|
API.new(input, options[:expandContext], **options) do
|
173
177
|
result = self.expand(self.value, nil, self.context,
|
@@ -180,6 +184,7 @@ module JSON::LD
|
|
180
184
|
|
181
185
|
# Finally, if element is a JSON object, it is wrapped into an array.
|
182
186
|
result = [result].compact unless result.is_a?(Array)
|
187
|
+
result = serializer.call(result, **options) if serializer
|
183
188
|
|
184
189
|
if block_given?
|
185
190
|
case block.arity
|
@@ -204,6 +209,9 @@ module JSON::LD
|
|
204
209
|
# The JSON-LD object to copy and perform the compaction upon.
|
205
210
|
# @param [String, #read, Hash, Array, JSON::LD::Context] context
|
206
211
|
# The base context to use when compacting the input.
|
212
|
+
# @param [Proc] serializer (nil)
|
213
|
+
# A Serializer instance used for generating the JSON serialization of the result. If absent, the internal Ruby objects are returned, which can be transformed to JSON externally via `#to_json`.
|
214
|
+
# See {JSON::LD::API.serializer}.
|
207
215
|
# @param [Boolean] expanded (false) Input is already expanded
|
208
216
|
# @param [Hash{Symbol => Object}] options
|
209
217
|
# @option options (see #initialize)
|
@@ -215,7 +223,7 @@ module JSON::LD
|
|
215
223
|
# If a block is given, the result of evaluating the block is returned, otherwise, the compacted JSON-LD document
|
216
224
|
# @raise [JsonLdError]
|
217
225
|
# @see https://www.w3.org/TR/json-ld11-api/#compaction-algorithm
|
218
|
-
def self.compact(input, context, expanded: false, **options)
|
226
|
+
def self.compact(input, context, expanded: false, serializer: nil, **options)
|
219
227
|
result = nil
|
220
228
|
options = {compactToRelative: true}.merge(options)
|
221
229
|
|
@@ -238,6 +246,7 @@ module JSON::LD
|
|
238
246
|
end
|
239
247
|
result = ctx.merge(result) unless ctx.fetch('@context', {}).empty?
|
240
248
|
end
|
249
|
+
result = serializer.call(result, **options) if serializer
|
241
250
|
block_given? ? yield(result) : result
|
242
251
|
end
|
243
252
|
|
@@ -251,6 +260,9 @@ module JSON::LD
|
|
251
260
|
# @param [String, #read, Hash, Array, JSON::LD::EvaluationContext] context
|
252
261
|
# An optional external context to use additionally to the context embedded in input when expanding the input.
|
253
262
|
# @param [Boolean] expanded (false) Input is already expanded
|
263
|
+
# @param [Proc] serializer (nil)
|
264
|
+
# A Serializer instance used for generating the JSON serialization of the result. If absent, the internal Ruby objects are returned, which can be transformed to JSON externally via `#to_json`.
|
265
|
+
# See {JSON::LD::API.serializer}.
|
254
266
|
# @param [Hash{Symbol => Object}] options
|
255
267
|
# @option options (see #initialize)
|
256
268
|
# @option options [Boolean] :createAnnotations
|
@@ -262,7 +274,7 @@ module JSON::LD
|
|
262
274
|
# @return [Object, Hash]
|
263
275
|
# If a block is given, the result of evaluating the block is returned, otherwise, the flattened JSON-LD document
|
264
276
|
# @see https://www.w3.org/TR/json-ld11-api/#framing-algorithm
|
265
|
-
def self.flatten(input, context, expanded: false, **options)
|
277
|
+
def self.flatten(input, context, expanded: false, serializer: nil, **options)
|
266
278
|
flattened = []
|
267
279
|
options = {
|
268
280
|
compactToRelative: true,
|
@@ -318,6 +330,7 @@ module JSON::LD
|
|
318
330
|
end
|
319
331
|
end
|
320
332
|
|
333
|
+
flattened = serializer.call(flattened, **options) if serializer
|
321
334
|
block_given? ? yield(flattened) : flattened
|
322
335
|
end
|
323
336
|
|
@@ -350,7 +363,7 @@ module JSON::LD
|
|
350
363
|
# If a block is given, the result of evaluating the block is returned, otherwise, the framed JSON-LD document
|
351
364
|
# @raise [InvalidFrame]
|
352
365
|
# @see https://www.w3.org/TR/json-ld11-api/#framing-algorithm
|
353
|
-
def self.frame(input, frame, expanded: false, **options)
|
366
|
+
def self.frame(input, frame, expanded: false, serializer: nil, **options)
|
354
367
|
result = nil
|
355
368
|
options = {
|
356
369
|
base: (RDF::URI(input) if input.is_a?(String)),
|
@@ -379,7 +392,8 @@ module JSON::LD
|
|
379
392
|
requestProfile: 'http://www.w3.org/ns/json-ld#frame',
|
380
393
|
**options)
|
381
394
|
if remote_doc.document.is_a?(String)
|
382
|
-
|
395
|
+
mj_opts = options.keep_if {|k,v| k != :adapter || MUTLI_JSON_ADAPTERS.include?(v)}
|
396
|
+
MultiJson.load(remote_doc.document, **mj_opts)
|
383
397
|
else
|
384
398
|
remote_doc.document
|
385
399
|
end
|
@@ -467,6 +481,7 @@ module JSON::LD
|
|
467
481
|
result
|
468
482
|
end
|
469
483
|
|
484
|
+
result = serializer.call(result, **options) if serializer
|
470
485
|
block_given? ? yield(result) : result
|
471
486
|
end
|
472
487
|
|
@@ -528,18 +543,21 @@ module JSON::LD
|
|
528
543
|
# The resulting `Array` is either returned or yielded, if a block is given.
|
529
544
|
#
|
530
545
|
# @param [RDF::Enumerable] input
|
546
|
+
# @param [Boolean] useRdfType (false)
|
547
|
+
# If set to `true`, the JSON-LD processor will treat `rdf:type` like a normal property instead of using `@type`.
|
548
|
+
# @param [Boolean] useNativeTypes (false) use native representations
|
549
|
+
# @param [Proc] serializer (nil)
|
550
|
+
# A Serializer instance used for generating the JSON serialization of the result. If absent, the internal Ruby objects are returned, which can be transformed to JSON externally via `#to_json`.
|
551
|
+
# See {JSON::LD::API.serializer}.
|
531
552
|
# @param [Hash{Symbol => Object}] options
|
532
553
|
# @option options (see #initialize)
|
533
|
-
# @option options [Boolean] :useRdfType (false)
|
534
|
-
# If set to `true`, the JSON-LD processor will treat `rdf:type` like a normal property instead of using `@type`.
|
535
|
-
# @option options [Boolean] :useNativeTypes (false) use native representations
|
536
554
|
# @yield jsonld
|
537
555
|
# @yieldparam [Hash] jsonld
|
538
556
|
# The JSON-LD document in expanded form
|
539
557
|
# @yieldreturn [Object] returned object
|
540
558
|
# @return [Object, Hash]
|
541
559
|
# If a block is given, the result of evaluating the block is returned, otherwise, the expanded JSON-LD document
|
542
|
-
def self.fromRdf(input, useRdfType: false, useNativeTypes: false, **options, &block)
|
560
|
+
def self.fromRdf(input, useRdfType: false, useNativeTypes: false, serializer: nil, **options, &block)
|
543
561
|
result = nil
|
544
562
|
|
545
563
|
API.new(nil, nil, **options) do
|
@@ -548,6 +566,7 @@ module JSON::LD
|
|
548
566
|
useNativeTypes: useNativeTypes)
|
549
567
|
end
|
550
568
|
|
569
|
+
result = serializer.call(result, **options) if serializer
|
551
570
|
block_given? ? yield(result) : result
|
552
571
|
end
|
553
572
|
|
@@ -648,7 +667,8 @@ module JSON::LD
|
|
648
667
|
end
|
649
668
|
else
|
650
669
|
validate_input(remote_doc.document, url: remote_doc.documentUrl) if validate
|
651
|
-
|
670
|
+
mj_opts = options.keep_if {|k,v| k != :adapter || MUTLI_JSON_ADAPTERS.include?(v)}
|
671
|
+
MultiJson.load(remote_doc.document, **mj_opts)
|
652
672
|
end
|
653
673
|
end
|
654
674
|
|
@@ -682,8 +702,8 @@ module JSON::LD
|
|
682
702
|
base_uri ||= url.base_uri if url.respond_to?(:base_uri)
|
683
703
|
content_type = options[:content_type]
|
684
704
|
content_type ||= url.content_type if url.respond_to?(:content_type)
|
685
|
-
context_url = if url.respond_to?(:links) && url.links
|
686
|
-
(content_type == '
|
705
|
+
context_url = if url.respond_to?(:links) && url.links &&
|
706
|
+
(content_type == 'application/json' || content_type.match?(%r(application/(^ld)+json)))
|
687
707
|
link = url.links.find_link(LINK_REL_CONTEXT)
|
688
708
|
link.href if link
|
689
709
|
end
|
@@ -759,7 +779,8 @@ module JSON::LD
|
|
759
779
|
raise JSON::LD::JsonLdError::LoadingDocumentFailed, "Script tag has type=#{element.attributes['type']}" unless element.attributes['type'].to_s.start_with?('application/ld+json')
|
760
780
|
content = element.inner_html
|
761
781
|
validate_input(content, url: url) if options[:validate]
|
762
|
-
|
782
|
+
mj_opts = options.keep_if {|k,v| k != :adapter || MUTLI_JSON_ADAPTERS.include?(v)}
|
783
|
+
MultiJson.load(content, **mj_opts)
|
763
784
|
elsif extractAllScripts
|
764
785
|
res = []
|
765
786
|
elements = if profile
|
@@ -773,7 +794,8 @@ module JSON::LD
|
|
773
794
|
elements.each do |element|
|
774
795
|
content = element.inner_html
|
775
796
|
validate_input(content, url: url) if options[:validate]
|
776
|
-
|
797
|
+
mj_opts = options.keep_if {|k,v| k != :adapter || MUTLI_JSON_ADAPTERS.include?(v)}
|
798
|
+
r = MultiJson.load(content, **mj_opts)
|
777
799
|
if r.is_a?(Hash)
|
778
800
|
res << r
|
779
801
|
elsif r.is_a?(Array)
|
@@ -788,12 +810,29 @@ module JSON::LD
|
|
788
810
|
raise JSON::LD::JsonLdError::LoadingDocumentFailed, "No script tag found" unless element
|
789
811
|
content = element.inner_html
|
790
812
|
validate_input(content, url: url) if options[:validate]
|
791
|
-
|
813
|
+
mj_opts = options.keep_if {|k,v| k != :adapter || MUTLI_JSON_ADAPTERS.include?(v)}
|
814
|
+
MultiJson.load(content, **mj_opts)
|
792
815
|
end
|
793
816
|
rescue MultiJson::ParseError => e
|
794
817
|
raise JSON::LD::JsonLdError::InvalidScriptElement, e.message
|
795
818
|
end
|
796
819
|
|
820
|
+
##
|
821
|
+
# The default serializer for serialzing Ruby Objects to JSON.
|
822
|
+
#
|
823
|
+
# Defaults to `MultiJson.dump`
|
824
|
+
#
|
825
|
+
# @param [Object] object
|
826
|
+
# @param [Array<Object>] args
|
827
|
+
# other arguments that may be passed for some specific implementation.
|
828
|
+
# @param [Hash<Symbol, Object>] options
|
829
|
+
# options passed from the invoking context.
|
830
|
+
# @option options [Object] :serializer_opts (JSON_STATE)
|
831
|
+
def self.serializer(object, *args, **options)
|
832
|
+
serializer_opts = options.fetch(:serializer_opts, JSON_STATE)
|
833
|
+
MultiJson.dump(object, serializer_opts)
|
834
|
+
end
|
835
|
+
|
797
836
|
##
|
798
837
|
# Validate JSON using JsonLint, if loaded
|
799
838
|
private
|
data/lib/json/ld/context.rb
CHANGED
@@ -5,13 +5,6 @@ require 'bigdecimal'
|
|
5
5
|
require 'set'
|
6
6
|
require 'rdf/util/cache'
|
7
7
|
|
8
|
-
begin
|
9
|
-
# Attempt to load this to avoid unnecessary context fetches
|
10
|
-
require 'json-ld-preloaded'
|
11
|
-
rescue LoadError
|
12
|
-
# Silently allow this to fail
|
13
|
-
end
|
14
|
-
|
15
8
|
module JSON::LD
|
16
9
|
class Context
|
17
10
|
include Utils
|
@@ -50,6 +43,13 @@ module JSON::LD
|
|
50
43
|
end
|
51
44
|
end
|
52
45
|
|
46
|
+
begin
|
47
|
+
# Attempt to load this to avoid unnecessary context fetches
|
48
|
+
require 'json/ld/preloaded'
|
49
|
+
rescue LoadError
|
50
|
+
# Silently allow this to fail
|
51
|
+
end
|
52
|
+
|
53
53
|
# The base.
|
54
54
|
#
|
55
55
|
# @return [RDF::URI] Current base IRI, used for expanding relative IRIs.
|
data/lib/json/ld/expand.rb
CHANGED
@@ -88,7 +88,7 @@ module JSON::LD
|
|
88
88
|
|
89
89
|
# If element contains the key @context, set active context to the result of the Context Processing algorithm, passing active context and the value of the @context key as local context.
|
90
90
|
if input.key?('@context')
|
91
|
-
context = context.parse(input
|
91
|
+
context = context.parse(input['@context'], base: @options[:base])
|
92
92
|
log_debug("expand", depth: log_depth.to_i) {"context: #{context.inspect}"}
|
93
93
|
end
|
94
94
|
|
@@ -99,7 +99,7 @@ module JSON::LD
|
|
99
99
|
|
100
100
|
# See if keys mapping to @type have terms with a local context
|
101
101
|
type_key = nil
|
102
|
-
input.keys.sort.
|
102
|
+
(input.keys - %w(@context)).sort.
|
103
103
|
select {|k| context.expand_iri(k, vocab: true, base: @options[:base]) == '@type'}.
|
104
104
|
each do |tk|
|
105
105
|
|
data/lib/json/ld/format.rb
CHANGED
@@ -23,7 +23,8 @@ module JSON::LD
|
|
23
23
|
class Format < RDF::Format
|
24
24
|
content_type 'application/ld+json',
|
25
25
|
extension: :jsonld,
|
26
|
-
alias: 'application/x-ld+json'
|
26
|
+
alias: 'application/x-ld+json',
|
27
|
+
uri: 'http://www.w3.org/ns/formats/JSON-LD'
|
27
28
|
content_encoding 'utf-8'
|
28
29
|
|
29
30
|
reader { JSON::LD::Reader }
|
@@ -44,8 +45,80 @@ module JSON::LD
|
|
44
45
|
!sample.include?("http://www.w3.org/ns/csvw")
|
45
46
|
end
|
46
47
|
|
48
|
+
# Specify how to execute CLI commands for each supported format.
|
49
|
+
# Derived formats (e.g., YAML-LD) define their own entrypoints.
|
50
|
+
LD_FORMATS = {
|
51
|
+
jsonld: {
|
52
|
+
expand: ->(input, **options) {
|
53
|
+
JSON::LD::API.expand(input,
|
54
|
+
serializer: JSON::LD::API.method(:serializer),
|
55
|
+
**options)
|
56
|
+
},
|
57
|
+
compact: ->(input, **options) {
|
58
|
+
JSON::LD::API.compact(input,
|
59
|
+
options[:context],
|
60
|
+
serializer: JSON::LD::API.method(:serializer),
|
61
|
+
**options)
|
62
|
+
},
|
63
|
+
flatten: ->(input, **options) {
|
64
|
+
JSON::LD::API.flatten(input,
|
65
|
+
options[:context],
|
66
|
+
serializer: JSON::LD::API.method(:serializer),
|
67
|
+
**options)
|
68
|
+
},
|
69
|
+
frame: ->(input, **options) {
|
70
|
+
JSON::LD::API.frame(input,
|
71
|
+
options[:frame],
|
72
|
+
serializer: JSON::LD::API.method(:serializer),
|
73
|
+
**options)
|
74
|
+
},
|
75
|
+
}
|
76
|
+
}
|
77
|
+
|
78
|
+
# Execute the body of a CLI command, generic for each different API method based on definitions on {LD_FORMATS}.
|
79
|
+
#
|
80
|
+
# Expands the input, or transforms from an RDF format based on the `:format` option, and then executes the appropriate command based on `:output_format` and does appropriate output serialization.
|
81
|
+
# @private
|
82
|
+
def self.cli_exec(command, files, output: $stdin, **options)
|
83
|
+
output.set_encoding(Encoding::UTF_8) if output.respond_to?(:set_encoding) && RUBY_PLATFORM == "java"
|
84
|
+
options[:base] ||= options[:base_uri]
|
85
|
+
|
86
|
+
# Parse using input format, serialize using output format
|
87
|
+
in_fmt = LD_FORMATS[options.fetch(:format, :jsonld)]
|
88
|
+
out_fmt = LD_FORMATS[options.fetch(:output_format, :jsonld)]
|
89
|
+
|
90
|
+
if in_fmt
|
91
|
+
# Input is a JSON-LD based source (or derived)
|
92
|
+
if files.empty?
|
93
|
+
# If files are empty, either use options[:evaluate] or STDIN
|
94
|
+
input = options[:evaluate] ? StringIO.new(options[:evaluate]) : STDIN
|
95
|
+
input.set_encoding(options.fetch(:encoding, Encoding::UTF_8))
|
96
|
+
expanded = in_fmt[:expand].call(input, serializer: nil, **options)
|
97
|
+
output.puts out_fmt[command].call(expanded, expanded: true, **options)
|
98
|
+
else
|
99
|
+
files.each do |file|
|
100
|
+
expanded = in_fmt[:expand].call(file, serializer: nil, **options)
|
101
|
+
output.puts out_fmt[command].call(expanded, expanded: true, **options)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
else
|
105
|
+
# Turn RDF into JSON-LD first
|
106
|
+
RDF::CLI.parse(files, **options) do |reader|
|
107
|
+
JSON::LD::API.fromRdf(reader, serializer: nil, **options) do |expanded|
|
108
|
+
output.puts out_fmt[command].call(expanded, expanded: true, **options)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
47
114
|
##
|
48
|
-
# Hash of CLI commands appropriate for this format
|
115
|
+
# Hash of CLI commands appropriate for this format:
|
116
|
+
#
|
117
|
+
# * `expand` => {JSON::LD::API.expand}
|
118
|
+
# * `compact` => {JSON::LD::API.compact}
|
119
|
+
# * `flatten` => {JSON::LD::API.flatten}
|
120
|
+
# * `frame` => {JSON::LD::API.frame}
|
121
|
+
#
|
49
122
|
# @return [Hash{Symbol => Hash}]
|
50
123
|
def self.cli_commands
|
51
124
|
{
|
@@ -53,73 +126,21 @@ module JSON::LD
|
|
53
126
|
description: "Expand JSON-LD or parsed RDF",
|
54
127
|
parse: false,
|
55
128
|
help: "expand [--context <context-file>] files ...",
|
56
|
-
filter: {output_format:
|
129
|
+
filter: {output_format: LD_FORMATS.keys}, # Only shows output format set
|
57
130
|
lambda: ->(files, **options) do
|
58
|
-
out = options[:output] || $stdout
|
59
|
-
out.set_encoding(Encoding::UTF_8) if RUBY_PLATFORM == "java"
|
60
131
|
options = options.merge(expandContext: options.delete(:context)) if options.key?(:context)
|
61
|
-
|
62
|
-
if options[:format] == :jsonld
|
63
|
-
if files.empty?
|
64
|
-
# If files are empty, either use options[:evaluate] or STDIN
|
65
|
-
input = options[:evaluate] ? StringIO.new(options[:evaluate]) : STDIN
|
66
|
-
input.set_encoding(options.fetch(:encoding, Encoding::UTF_8))
|
67
|
-
JSON::LD::API.expand(input, validate: false, **options) do |expanded|
|
68
|
-
out.puts expanded.to_json(JSON::LD::JSON_STATE)
|
69
|
-
end
|
70
|
-
else
|
71
|
-
files.each do |file|
|
72
|
-
JSON::LD::API.expand(file, validate: false, **options) do |expanded|
|
73
|
-
out.puts expanded.to_json(JSON::LD::JSON_STATE)
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
77
|
-
else
|
78
|
-
# Turn RDF into JSON-LD first
|
79
|
-
RDF::CLI.parse(files, **options) do |reader|
|
80
|
-
JSON::LD::API.fromRdf(reader) do |expanded|
|
81
|
-
out.puts expanded.to_json(JSON::LD::JSON_STATE)
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
132
|
+
cli_exec(:expand, files, **options)
|
85
133
|
end,
|
86
134
|
option_use: {context: :removed}
|
87
135
|
},
|
88
136
|
compact: {
|
89
137
|
description: "Compact JSON-LD or parsed RDF",
|
90
138
|
parse: false,
|
91
|
-
filter: {output_format:
|
139
|
+
filter: {output_format: LD_FORMATS.keys}, # Only shows output format set
|
92
140
|
help: "compact --context <context-file> files ...",
|
93
141
|
lambda: ->(files, **options) do
|
94
142
|
raise ArgumentError, "Compacting requires a context" unless options[:context]
|
95
|
-
|
96
|
-
out.set_encoding(Encoding::UTF_8) if RUBY_PLATFORM == "java"
|
97
|
-
options[:base] ||= options[:base_uri]
|
98
|
-
if options[:format] == :jsonld
|
99
|
-
if files.empty?
|
100
|
-
# If files are empty, either use options[:evaluate] or STDIN
|
101
|
-
input = options[:evaluate] ? StringIO.new(options[:evaluate]) : STDIN
|
102
|
-
input.set_encoding(options.fetch(:encoding, Encoding::UTF_8))
|
103
|
-
JSON::LD::API.compact(input, options[:context], **options) do |compacted|
|
104
|
-
out.puts compacted.to_json(JSON::LD::JSON_STATE)
|
105
|
-
end
|
106
|
-
else
|
107
|
-
files.each do |file|
|
108
|
-
JSON::LD::API.compact(file, options[:context], **options) do |compacted|
|
109
|
-
out.puts compacted.to_json(JSON::LD::JSON_STATE)
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|
113
|
-
else
|
114
|
-
# Turn RDF into JSON-LD first
|
115
|
-
RDF::CLI.parse(files, **options) do |reader|
|
116
|
-
JSON::LD::API.fromRdf(reader) do |expanded|
|
117
|
-
JSON::LD::API.compact(expanded, options[:context], **options) do |compacted|
|
118
|
-
out.puts compacted.to_json(JSON::LD::JSON_STATE)
|
119
|
-
end
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|
143
|
+
cli_exec(:compact, files, **options)
|
123
144
|
end,
|
124
145
|
options: [
|
125
146
|
RDF::CLI::Option.new(
|
@@ -135,36 +156,9 @@ module JSON::LD
|
|
135
156
|
description: "Flatten JSON-LD or parsed RDF",
|
136
157
|
parse: false,
|
137
158
|
help: "flatten [--context <context-file>] files ...",
|
138
|
-
filter: {output_format:
|
159
|
+
filter: {output_format: LD_FORMATS.keys}, # Only shows output format set
|
139
160
|
lambda: ->(files, **options) do
|
140
|
-
|
141
|
-
out.set_encoding(Encoding::UTF_8) if RUBY_PLATFORM == "java"
|
142
|
-
options[:base] ||= options[:base_uri]
|
143
|
-
if options[:format] == :jsonld
|
144
|
-
if files.empty?
|
145
|
-
# If files are empty, either use options[:evaluate] or STDIN
|
146
|
-
input = options[:evaluate] ? StringIO.new(options[:evaluate]) : STDIN
|
147
|
-
input.set_encoding(options.fetch(:encoding, Encoding::UTF_8))
|
148
|
-
JSON::LD::API.flatten(input, options[:context], **options) do |flattened|
|
149
|
-
out.puts flattened.to_json(JSON::LD::JSON_STATE)
|
150
|
-
end
|
151
|
-
else
|
152
|
-
files.each do |file|
|
153
|
-
JSON::LD::API.flatten(file, options[:context], **options) do |flattened|
|
154
|
-
out.puts flattened.to_json(JSON::LD::JSON_STATE)
|
155
|
-
end
|
156
|
-
end
|
157
|
-
end
|
158
|
-
else
|
159
|
-
# Turn RDF into JSON-LD first
|
160
|
-
RDF::CLI.parse(files, **options) do |reader|
|
161
|
-
JSON::LD::API.fromRdf(reader) do |expanded|
|
162
|
-
JSON::LD::API.flatten(expanded, options[:context], **options) do |flattened|
|
163
|
-
out.puts flattened.to_json(JSON::LD::JSON_STATE)
|
164
|
-
end
|
165
|
-
end
|
166
|
-
end
|
167
|
-
end
|
161
|
+
cli_exec(:compact, files, **options)
|
168
162
|
end,
|
169
163
|
options: [
|
170
164
|
RDF::CLI::Option.new(
|
@@ -187,37 +181,10 @@ module JSON::LD
|
|
187
181
|
description: "Frame JSON-LD or parsed RDF",
|
188
182
|
parse: false,
|
189
183
|
help: "frame --frame <frame-file> files ...",
|
190
|
-
filter: {output_format:
|
184
|
+
filter: {output_format: LD_FORMATS.keys}, # Only shows output format set
|
191
185
|
lambda: ->(files, **options) do
|
192
186
|
raise ArgumentError, "Framing requires a frame" unless options[:frame]
|
193
|
-
|
194
|
-
out.set_encoding(Encoding::UTF_8) if RUBY_PLATFORM == "java"
|
195
|
-
options[:base] ||= options[:base_uri]
|
196
|
-
if options[:format] == :jsonld
|
197
|
-
if files.empty?
|
198
|
-
# If files are empty, either use options[:evaluate] or STDIN
|
199
|
-
input = options[:evaluate] ? StringIO.new(options[:evaluate]) : STDIN
|
200
|
-
input.set_encoding(options.fetch(:encoding, Encoding::UTF_8))
|
201
|
-
JSON::LD::API.frame(input, options[:frame], **options) do |framed|
|
202
|
-
out.puts framed.to_json(JSON::LD::JSON_STATE)
|
203
|
-
end
|
204
|
-
else
|
205
|
-
files.each do |file|
|
206
|
-
JSON::LD::API.frame(file, options[:frame], **options) do |framed|
|
207
|
-
out.puts framed.to_json(JSON::LD::JSON_STATE)
|
208
|
-
end
|
209
|
-
end
|
210
|
-
end
|
211
|
-
else
|
212
|
-
# Turn RDF into JSON-LD first
|
213
|
-
RDF::CLI.parse(files, **options) do |reader|
|
214
|
-
JSON::LD::API.fromRdf(reader) do |expanded|
|
215
|
-
JSON::LD::API.frame(expanded, options[:frame], **options) do |framed|
|
216
|
-
out.puts framed.to_json(JSON::LD::JSON_STATE)
|
217
|
-
end
|
218
|
-
end
|
219
|
-
end
|
220
|
-
end
|
187
|
+
cli_exec(:compact, files, **options)
|
221
188
|
end,
|
222
189
|
option_use: {context: :removed},
|
223
190
|
options: [
|
data/lib/json/ld/reader.rb
CHANGED
@@ -12,7 +12,7 @@ module JSON::LD
|
|
12
12
|
|
13
13
|
##
|
14
14
|
# JSON-LD Reader options
|
15
|
-
# @see
|
15
|
+
# @see https://ruby-rdf.github.io/rdf/RDF/Reader#options-class_method
|
16
16
|
def self.options
|
17
17
|
super + [
|
18
18
|
RDF::CLI::Option.new(
|
@@ -57,7 +57,7 @@ module JSON::LD
|
|
57
57
|
end
|
58
58
|
|
59
59
|
##
|
60
|
-
# Initializes the
|
60
|
+
# Initializes the JSON-LD reader instance.
|
61
61
|
#
|
62
62
|
# @param [IO, File, String] input
|
63
63
|
# @param [Hash{Symbol => Object}] options
|
@@ -26,7 +26,8 @@ module JSON::LD
|
|
26
26
|
unique_bnodes, rename_bnodes = @options[:unique_bnodes], @options.fetch(:rename_bnodes, true)
|
27
27
|
# FIXME: document loader doesn't stream
|
28
28
|
@base = RDF::URI(@options[:base] || base_uri)
|
29
|
-
|
29
|
+
mj_opts = @options.keep_if {|k,v| k != :adapter || MUTLI_JSON_ADAPTERS.include?(v)}
|
30
|
+
value = MultiJson.load(@doc, mj_opts)
|
30
31
|
context_ref = @options[:expandContext]
|
31
32
|
#context_ref = @options.fetch(:expandContext, remote_doc.contextUrl)
|
32
33
|
context = Context.parse(context_ref, **@options)
|