json-ld 3.2.0 → 3.2.3
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 +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)
|