From 29b5ab2c82cab85367d113c9639374ad70f6e1db Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Sun, 15 May 2022 12:37:02 -0700 Subject: [PATCH 1/5] @embed in list test. --- spec/frame_spec.rb | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/spec/frame_spec.rb b/spec/frame_spec.rb index fdecfb9..1a4deb9 100644 --- a/spec/frame_spec.rb +++ b/spec/frame_spec.rb @@ -2438,7 +2438,31 @@ "@id": "ex:entity1" }), processingMode: "json-ld-1.1" - } + }, + "don't embed list elements": { + frame: %({ + "@context": {"ex": "http://example.org/"}, + "ex:embed": { + "@list": [{"@embed": "@never"}] + } + }), + input: %({ + "@context": {"ex": "http://example.org/"}, + "@id": "ex:Sub1", + "ex:embed": { + "@list": [{ + "@id": "ex:Sub2", + "ex:prop": "property" + }] + } + }), + output: %({ + "@context": {"ex": "http://example.org/"}, + "@id": "ex:Sub1", + "ex:embed": {"@list": [{"@id": "ex:Sub2"}]} + }), + processingMode: "json-ld-1.1" + }, }.each do |title, params| it title do do_frame(params) From 6cf3cd18e397e88cd4206606f7e1be23590f41ce Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Sun, 3 Jul 2022 16:21:29 -0700 Subject: [PATCH 2/5] Add `serializer` option to API methods and Writer to be able to specify the proc to use when serializing to JSON. --- lib/json/ld/api.rb | 43 +++++++++++++++++++----- lib/json/ld/to_rdf.rb | 2 +- lib/json/ld/writer.rb | 5 ++- spec/api_spec.rb | 78 +++++++++++++++++++++++++++++++++++-------- spec/suite_helper.rb | 1 + 5 files changed, 105 insertions(+), 24 deletions(-) diff --git a/lib/json/ld/api.rb b/lib/json/ld/api.rb index cf20320..d0a76c5 100644 --- a/lib/json/ld/api.rb +++ b/lib/json/ld/api.rb @@ -155,6 +155,9 @@ def initialize(input, context, **options, &block) # # @param [String, #read, Hash, Array] input # The JSON-LD object to copy and perform the expansion upon. + # @param [Proc] serializer (nil) + # 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`. + # See {JSON::LD::API.serializer}. # @param [Hash{Symbol => Object}] options # @option options (see #initialize) # @raise [JsonLdError] @@ -167,7 +170,7 @@ def initialize(input, context, **options, &block) # @return [Object, Array] # If a block is given, the result of evaluating the block is returned, otherwise, the expanded JSON-LD document # @see https://www.w3.org/TR/json-ld11-api/#expansion-algorithm - def self.expand(input, framing: false, **options, &block) + def self.expand(input, framing: false, serializer: nil, **options, &block) result = doc_base = nil API.new(input, options[:expandContext], **options) do result = self.expand(self.value, nil, self.context, @@ -180,6 +183,7 @@ def self.expand(input, framing: false, **options, &block) # Finally, if element is a JSON object, it is wrapped into an array. result = [result].compact unless result.is_a?(Array) + result = serializer.call(result) if serializer if block_given? case block.arity @@ -204,6 +208,9 @@ def self.expand(input, framing: false, **options, &block) # The JSON-LD object to copy and perform the compaction upon. # @param [String, #read, Hash, Array, JSON::LD::Context] context # The base context to use when compacting the input. + # @param [Proc] serializer (nil) + # 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`. + # See {JSON::LD::API.serializer}. # @param [Boolean] expanded (false) Input is already expanded # @param [Hash{Symbol => Object}] options # @option options (see #initialize) @@ -215,7 +222,7 @@ def self.expand(input, framing: false, **options, &block) # If a block is given, the result of evaluating the block is returned, otherwise, the compacted JSON-LD document # @raise [JsonLdError] # @see https://www.w3.org/TR/json-ld11-api/#compaction-algorithm - def self.compact(input, context, expanded: false, **options) + def self.compact(input, context, expanded: false, serializer: nil, **options) result = nil options = {compactToRelative: true}.merge(options) @@ -238,6 +245,7 @@ def self.compact(input, context, expanded: false, **options) end result = ctx.merge(result) unless ctx.fetch('@context', {}).empty? end + result = serializer.call(result) if serializer block_given? ? yield(result) : result end @@ -251,6 +259,9 @@ def self.compact(input, context, expanded: false, **options) # @param [String, #read, Hash, Array, JSON::LD::EvaluationContext] context # An optional external context to use additionally to the context embedded in input when expanding the input. # @param [Boolean] expanded (false) Input is already expanded + # @param [Proc] serializer (nil) + # 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`. + # See {JSON::LD::API.serializer}. # @param [Hash{Symbol => Object}] options # @option options (see #initialize) # @option options [Boolean] :createAnnotations @@ -262,7 +273,7 @@ def self.compact(input, context, expanded: false, **options) # @return [Object, Hash] # If a block is given, the result of evaluating the block is returned, otherwise, the flattened JSON-LD document # @see https://www.w3.org/TR/json-ld11-api/#framing-algorithm - def self.flatten(input, context, expanded: false, **options) + def self.flatten(input, context, expanded: false, serializer: nil, **options) flattened = [] options = { compactToRelative: true, @@ -318,6 +329,7 @@ def self.flatten(input, context, expanded: false, **options) end end + flattened = serializer.call(flattened) if serializer block_given? ? yield(flattened) : flattened end @@ -350,7 +362,7 @@ def self.flatten(input, context, expanded: false, **options) # If a block is given, the result of evaluating the block is returned, otherwise, the framed JSON-LD document # @raise [InvalidFrame] # @see https://www.w3.org/TR/json-ld11-api/#framing-algorithm - def self.frame(input, frame, expanded: false, **options) + def self.frame(input, frame, expanded: false, serializer: nil, **options) result = nil options = { base: (RDF::URI(input) if input.is_a?(String)), @@ -467,6 +479,7 @@ def self.frame(input, frame, expanded: false, **options) result end + result = serializer.call(result) if serializer block_given? ? yield(result) : result end @@ -528,18 +541,21 @@ def self.toRdf(input, expanded: false, **options, &block) # The resulting `Array` is either returned or yielded, if a block is given. # # @param [RDF::Enumerable] input + # @param [Boolean] useRdfType (false) + # If set to `true`, the JSON-LD processor will treat `rdf:type` like a normal property instead of using `@type`. + # @param [Boolean] useNativeTypes (false) use native representations + # @param [Proc] serializer (nil) + # 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`. + # See {JSON::LD::API.serializer}. # @param [Hash{Symbol => Object}] options # @option options (see #initialize) - # @option options [Boolean] :useRdfType (false) - # If set to `true`, the JSON-LD processor will treat `rdf:type` like a normal property instead of using `@type`. - # @option options [Boolean] :useNativeTypes (false) use native representations # @yield jsonld # @yieldparam [Hash] jsonld # The JSON-LD document in expanded form # @yieldreturn [Object] returned object # @return [Object, Hash] # If a block is given, the result of evaluating the block is returned, otherwise, the expanded JSON-LD document - def self.fromRdf(input, useRdfType: false, useNativeTypes: false, **options, &block) + def self.fromRdf(input, useRdfType: false, useNativeTypes: false, serializer: nil, **options, &block) result = nil API.new(nil, nil, **options) do @@ -548,6 +564,7 @@ def self.fromRdf(input, useRdfType: false, useNativeTypes: false, **options, &bl useNativeTypes: useNativeTypes) end + result = serializer.call(result) if serializer block_given? ? yield(result) : result end @@ -794,6 +811,16 @@ def self.load_html(input, url:, raise JSON::LD::JsonLdError::InvalidScriptElement, e.message end + ## + # The default serializer for serialzing Ruby Objects to JSON. + # + # Defaults to `MultiJson.dump` + # + # @param [Object] object + def self.serializer(object) + MultiJson.dump(object, JSON_STATE) + end + ## # Validate JSON using JsonLint, if loaded private diff --git a/lib/json/ld/to_rdf.rb b/lib/json/ld/to_rdf.rb index 76209ca..deb9434 100644 --- a/lib/json/ld/to_rdf.rb +++ b/lib/json/ld/to_rdf.rb @@ -11,7 +11,7 @@ module ToRDF ## # @param [Hash{String => Object}] item # @param [RDF::Resource] graph_name - # @param [Boolean] emitted triples are quoted triples. + # @param [Boolean] quoted emitted triples are quoted triples. # @yield statement # @yieldparam [RDF::Statement] statement # @return RDF::Resource the subject of this item diff --git a/lib/json/ld/writer.rb b/lib/json/ld/writer.rb index 04a0c8b..93c2af5 100644 --- a/lib/json/ld/writer.rb +++ b/lib/json/ld/writer.rb @@ -229,6 +229,8 @@ def default_context=(url); @default_context = url; end # frame to use when serializing. # @option options [Boolean] :unique_bnodes (false) # Use unique bnode identifiers, defaults to using the identifier which the node was originall initialized with (if any). + # @option options [Proc] serializer (JSON::LD::API.serializer) + # A Serializer method used for generating the JSON serialization of the result. # @option options [Boolean] :stream (false) # Do not attempt to optimize graph presentation, suitable for streaming large graphs. # @yield [writer] `self` @@ -239,6 +241,7 @@ def default_context=(url); @default_context = url; end def initialize(output = $stdout, **options, &block) options[:base_uri] ||= options[:base] if options.key?(:base) options[:base] ||= options[:base_uri] if options.key?(:base_uri) + @serializer = options.fetch(:serializer, JSON::LD::API.method(:serializer)) super do @repo = RDF::Repository.new @@ -335,7 +338,7 @@ def write_epilogue result = API.compact(result, context, **@options) end - @output.write(result.to_json(JSON_STATE)) + @output.write(@serializer.call(result)) end super diff --git a/spec/api_spec.rb b/spec/api_spec.rb index c9ae999..d574f65 100644 --- a/spec/api_spec.rb +++ b/spec/api_spec.rb @@ -56,22 +56,72 @@ ttl = filename.sub(/-input\..*$/, '-rdf.ttl') context test, skip: ("Not supported in JRuby" if RUBY_ENGINE == "jruby" && %w(oj yajl).include?(adapter.to_s)) do - it "expands" do - options = {logger: logger, adapter: adapter} - options[:expandContext] = File.open(context) if context - jld = described_class.expand(File.open(filename), **options) - expect(jld).to produce_jsonld(JSON.load(File.open(expanded)), logger) - end if File.exist?(expanded) + if File.exist?(expanded) + it "expands" do + options = {logger: logger, adapter: adapter} + File.open(context) do |ctx_io| + File.open(filename) do |file| + options[:expandContext] = ctx_io if context + jld = described_class.expand(file, **options) + expect(jld).to produce_jsonld(JSON.parse(File.read(expanded)), logger) + end + end + end + + it "expands with serializer" do + options = {logger: logger, adapter: adapter} + File.open(context) do |ctx_io| + File.open(filename) do |file| + options[:expandContext] = ctx_io if context + jld = described_class.expand(file, serializer: JSON::LD::API.method(:serializer), **options) + expect(jld).to be_a(String) + expect(JSON.load(jld)).to produce_jsonld(JSON.parse(File.read(expanded)), logger) + end + end + end + end - it "compacts" do - jld = described_class.compact(File.open(filename), File.open(context), adapter: adapter, logger: logger) - expect(jld).to produce_jsonld(JSON.load(File.open(compacted)), logger) - end if File.exist?(compacted) && File.exist?(context) + if File.exist?(compacted) && File.exist?(context) + it "compacts" do + File.open(context) do |ctx_io| + File.open(filename) do |file| + jld = described_class.compact(file, ctx_io, adapter: adapter, logger: logger) + expect(jld).to produce_jsonld(JSON.parse(File.read(compacted)), logger) + end + end + end + + it "compacts with serializer" do + File.open(context) do |ctx_io| + File.open(filename) do |file| + jld = described_class.compact(file, ctx_io, serializer: JSON::LD::API.method(:serializer), adapter: adapter, logger: logger) + expect(jld).to be_a(String) + expect(JSON.load(jld)).to produce_jsonld(JSON.parse(File.read(compacted)), logger) + end + end + end + end - it "frame" do - jld = described_class.frame(File.open(filename), File.open(frame), adapter: adapter, logger: logger) - expect(jld).to produce_jsonld(JSON.load(File.open(framed)), logger) - end if File.exist?(framed) && File.exist?(frame) + if File.exist?(framed) && File.exist?(frame) + it "frames" do + File.open(frame) do |frame_io| + File.open(filename) do |file| + jld = described_class.frame(file, frame_io, adapter: adapter, logger: logger) + expect(jld).to produce_jsonld(JSON.parse(File.read(framed)), logger) + end + end + end + + it "frames with serializer" do + File.open(frame) do |frame_io| + File.open(filename) do |file| + jld = described_class.frame(file, frame_io, serializer: JSON::LD::API.method(:serializer), adapter: adapter, logger: logger) + expect(jld).to be_a(String) + expect(JSON.load(jld)).to produce_jsonld(JSON.parse(File.read(framed)), logger) + end + end + end + end it "toRdf" do expect(RDF::Repository.load(filename, format: :jsonld, adapter: adapter, logger: logger)).to be_equivalent_graph(RDF::Repository.load(ttl), logger: logger) diff --git a/spec/suite_helper.rb b/spec/suite_helper.rb index 8d1e846..51b8314 100644 --- a/spec/suite_helper.rb +++ b/spec/suite_helper.rb @@ -60,6 +60,7 @@ def self.open_file(filename_or_url, **options, &block) document_options[:headers][:content_type] = options[:contentType] if options[:contentType] remote_document = RDF::Util::File::RemoteDocument.new(response.read, **document_options) + response.close if block_given? return yield remote_document else From c680d215f47c6c884816f9393c9eda2466201ed4 Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Sun, 31 Jul 2022 14:47:42 -0700 Subject: [PATCH 3/5] Don't serialize when API methods are used internally. --- README.md | 5 +- lib/json/ld.rb | 3 + lib/json/ld/api.rb | 22 +++-- lib/json/ld/reader.rb | 2 +- lib/json/ld/streaming_reader.rb | 3 +- lib/json/ld/writer.rb | 12 +-- spec/api_spec.rb | 82 +++++++++---------- spec/format_spec.rb | 4 +- ...compacted.json => test-1-compacted.jsonld} | 0 ...t-1-context.json => test-1-context.jsonld} | 0 ...1-expanded.json => test-1-expanded.jsonld} | 0 ...{test-1-input.json => test-1-input.jsonld} | 0 spec/test-files/test-1-normalized.json | 8 -- ...compacted.json => test-2-compacted.jsonld} | 0 ...t-2-context.json => test-2-context.jsonld} | 0 ...2-expanded.json => test-2-expanded.jsonld} | 0 ...{test-2-input.json => test-2-input.jsonld} | 0 spec/test-files/test-2-normalized.json | 32 -------- ...compacted.json => test-3-compacted.jsonld} | 0 ...t-3-context.json => test-3-context.jsonld} | 0 ...3-expanded.json => test-3-expanded.jsonld} | 0 ...{test-3-input.json => test-3-input.jsonld} | 0 spec/test-files/test-3-normalized.json | 13 --- ...compacted.json => test-4-compacted.jsonld} | 0 ...t-4-context.json => test-4-context.jsonld} | 0 ...4-expanded.json => test-4-expanded.jsonld} | 0 ...{test-4-input.json => test-4-input.jsonld} | 0 ...compacted.json => test-5-compacted.jsonld} | 0 ...t-5-context.json => test-5-context.jsonld} | 0 ...5-expanded.json => test-5-expanded.jsonld} | 0 ...{test-5-input.json => test-5-input.jsonld} | 0 ...compacted.json => test-6-compacted.jsonld} | 0 ...t-6-context.json => test-6-context.jsonld} | 0 ...6-expanded.json => test-6-expanded.jsonld} | 0 ...{test-6-input.json => test-6-input.jsonld} | 0 ...compacted.json => test-7-compacted.jsonld} | 0 ...t-7-context.json => test-7-context.jsonld} | 0 ...7-expanded.json => test-7-expanded.jsonld} | 0 ...{test-7-input.json => test-7-input.jsonld} | 0 ...compacted.json => test-8-compacted.jsonld} | 0 ...t-8-context.json => test-8-context.jsonld} | 0 ...8-expanded.json => test-8-expanded.jsonld} | 0 ...{test-8-frame.json => test-8-frame.jsonld} | 0 ...est-8-framed.json => test-8-framed.jsonld} | 0 ...{test-8-input.json => test-8-input.jsonld} | 0 ...compacted.json => test-9-compacted.jsonld} | 0 ...t-9-context.json => test-9-context.jsonld} | 0 ...9-expanded.json => test-9-expanded.jsonld} | 0 ...{test-9-input.json => test-9-input.jsonld} | 0 49 files changed, 68 insertions(+), 118 deletions(-) rename spec/test-files/{test-1-compacted.json => test-1-compacted.jsonld} (100%) rename spec/test-files/{test-1-context.json => test-1-context.jsonld} (100%) rename spec/test-files/{test-1-expanded.json => test-1-expanded.jsonld} (100%) rename spec/test-files/{test-1-input.json => test-1-input.jsonld} (100%) delete mode 100644 spec/test-files/test-1-normalized.json rename spec/test-files/{test-2-compacted.json => test-2-compacted.jsonld} (100%) rename spec/test-files/{test-2-context.json => test-2-context.jsonld} (100%) rename spec/test-files/{test-2-expanded.json => test-2-expanded.jsonld} (100%) rename spec/test-files/{test-2-input.json => test-2-input.jsonld} (100%) delete mode 100644 spec/test-files/test-2-normalized.json rename spec/test-files/{test-3-compacted.json => test-3-compacted.jsonld} (100%) rename spec/test-files/{test-3-context.json => test-3-context.jsonld} (100%) rename spec/test-files/{test-3-expanded.json => test-3-expanded.jsonld} (100%) rename spec/test-files/{test-3-input.json => test-3-input.jsonld} (100%) delete mode 100644 spec/test-files/test-3-normalized.json rename spec/test-files/{test-4-compacted.json => test-4-compacted.jsonld} (100%) rename spec/test-files/{test-4-context.json => test-4-context.jsonld} (100%) rename spec/test-files/{test-4-expanded.json => test-4-expanded.jsonld} (100%) rename spec/test-files/{test-4-input.json => test-4-input.jsonld} (100%) rename spec/test-files/{test-5-compacted.json => test-5-compacted.jsonld} (100%) rename spec/test-files/{test-5-context.json => test-5-context.jsonld} (100%) rename spec/test-files/{test-5-expanded.json => test-5-expanded.jsonld} (100%) rename spec/test-files/{test-5-input.json => test-5-input.jsonld} (100%) rename spec/test-files/{test-6-compacted.json => test-6-compacted.jsonld} (100%) rename spec/test-files/{test-6-context.json => test-6-context.jsonld} (100%) rename spec/test-files/{test-6-expanded.json => test-6-expanded.jsonld} (100%) rename spec/test-files/{test-6-input.json => test-6-input.jsonld} (100%) rename spec/test-files/{test-7-compacted.json => test-7-compacted.jsonld} (100%) rename spec/test-files/{test-7-context.json => test-7-context.jsonld} (100%) rename spec/test-files/{test-7-expanded.json => test-7-expanded.jsonld} (100%) rename spec/test-files/{test-7-input.json => test-7-input.jsonld} (100%) rename spec/test-files/{test-8-compacted.json => test-8-compacted.jsonld} (100%) rename spec/test-files/{test-8-context.json => test-8-context.jsonld} (100%) rename spec/test-files/{test-8-expanded.json => test-8-expanded.jsonld} (100%) rename spec/test-files/{test-8-frame.json => test-8-frame.jsonld} (100%) rename spec/test-files/{test-8-framed.json => test-8-framed.jsonld} (100%) rename spec/test-files/{test-8-input.json => test-8-input.jsonld} (100%) rename spec/test-files/{test-9-compacted.json => test-9-compacted.jsonld} (100%) rename spec/test-files/{test-9-context.json => test-9-context.jsonld} (100%) rename spec/test-files/{test-9-expanded.json => test-9-expanded.jsonld} (100%) rename spec/test-files/{test-9-input.json => test-9-input.jsonld} (100%) diff --git a/README.md b/README.md index 57fca0f..7229289 100755 --- a/README.md +++ b/README.md @@ -624,8 +624,7 @@ To get a local working copy of the development repository, do: which you will be asked to agree to on the first commit to a repo within the organization. Note that the agreement applies to all repos in the [Ruby RDF](https://github.com/ruby-rdf/) organization. -License -------- +## License This is free and unencumbered public domain software. For more information, see or the accompanying {file:UNLICENSE} file. @@ -641,7 +640,7 @@ see or the accompanying {file:UNLICENSE} file. [Backports]: https://rubygems.org/gems/backports [JSON-LD]: https://www.w3.org/TR/json-ld11/ "JSON-LD 1.1" [JSON-LD API]: https://www.w3.org/TR/json-ld11-api/ "JSON-LD 1.1 Processing Algorithms and API" -[JSON-LD Framing]: https://www.w3.org/TR/json-ld11-framing/ "JSON-LD Framing 1.1" +[JSON-LD Framing]: https://www.w3.org/TR/json-ld11-framing/ "JSON-LD 1.1 Framing" [Promises]: https://dom.spec.whatwg.org/#promises [jsonlint]: https://rubygems.org/gems/jsonlint [Sinatra]: https://www.sinatrarb.com/ diff --git a/lib/json/ld.rb b/lib/json/ld.rb index ef7ab5a..3b7caf0 100644 --- a/lib/json/ld.rb +++ b/lib/json/ld.rb @@ -46,6 +46,9 @@ module LD # Default context when compacting without one being specified DEFAULT_CONTEXT = "http://schema.org" + # Acceptable MultiJson adapters + MUTLI_JSON_ADAPTERS = %i(oj json_gem json_pure ok_json yajl nsjsonseerialization) + KEYWORDS = Set.new(%w( @annotation @base diff --git a/lib/json/ld/api.rb b/lib/json/ld/api.rb index d0a76c5..18d4d83 100644 --- a/lib/json/ld/api.rb +++ b/lib/json/ld/api.rb @@ -126,7 +126,8 @@ def initialize(input, context, **options, &block) case remote_doc.document when String - MultiJson.load(remote_doc.document, **options) + mj_opts = options.keep_if {|k,v| k != :adapter || MUTLI_JSON_ADAPTERS.include?(v)} + MultiJson.load(remote_doc.document, **mj_opts) else # Already parsed remote_doc.document @@ -391,7 +392,8 @@ def self.frame(input, frame, expanded: false, serializer: nil, **options) requestProfile: 'http://www.w3.org/ns/json-ld#frame', **options) if remote_doc.document.is_a?(String) - MultiJson.load(remote_doc.document) + mj_opts = options.keep_if {|k,v| k != :adapter || MUTLI_JSON_ADAPTERS.include?(v)} + MultiJson.load(remote_doc.document, **mj_opts) else remote_doc.document end @@ -665,7 +667,8 @@ def self.loadRemoteDocument(url, end else validate_input(remote_doc.document, url: remote_doc.documentUrl) if validate - MultiJson.load(remote_doc.document, **options) + mj_opts = options.keep_if {|k,v| k != :adapter || MUTLI_JSON_ADAPTERS.include?(v)} + MultiJson.load(remote_doc.document, **mj_opts) end end @@ -699,8 +702,8 @@ def self.documentLoader(url, extractAllScripts: false, profile: nil, requestProf base_uri ||= url.base_uri if url.respond_to?(:base_uri) content_type = options[:content_type] content_type ||= url.content_type if url.respond_to?(:content_type) - context_url = if url.respond_to?(:links) && url.links - (content_type == 'appliaction/json' || content_type.match?(%r(application/(^ld)+json))) + context_url = if url.respond_to?(:links) && url.links && + (content_type == 'application/json' || content_type.match?(%r(application/(^ld)+json))) link = url.links.find_link(LINK_REL_CONTEXT) link.href if link end @@ -776,7 +779,8 @@ def self.load_html(input, url:, raise JSON::LD::JsonLdError::LoadingDocumentFailed, "Script tag has type=#{element.attributes['type']}" unless element.attributes['type'].to_s.start_with?('application/ld+json') content = element.inner_html validate_input(content, url: url) if options[:validate] - MultiJson.load(content, **options) + mj_opts = options.keep_if {|k,v| k != :adapter || MUTLI_JSON_ADAPTERS.include?(v)} + MultiJson.load(content, **mj_opts) elsif extractAllScripts res = [] elements = if profile @@ -790,7 +794,8 @@ def self.load_html(input, url:, elements.each do |element| content = element.inner_html validate_input(content, url: url) if options[:validate] - r = MultiJson.load(content, **options) + mj_opts = options.keep_if {|k,v| k != :adapter || MUTLI_JSON_ADAPTERS.include?(v)} + r = MultiJson.load(content, **mj_opts) if r.is_a?(Hash) res << r elsif r.is_a?(Array) @@ -805,7 +810,8 @@ def self.load_html(input, url:, raise JSON::LD::JsonLdError::LoadingDocumentFailed, "No script tag found" unless element content = element.inner_html validate_input(content, url: url) if options[:validate] - MultiJson.load(content, **options) + mj_opts = options.keep_if {|k,v| k != :adapter || MUTLI_JSON_ADAPTERS.include?(v)} + MultiJson.load(content, **mj_opts) end rescue MultiJson::ParseError => e raise JSON::LD::JsonLdError::InvalidScriptElement, e.message diff --git a/lib/json/ld/reader.rb b/lib/json/ld/reader.rb index 92d84e6..f1c8988 100644 --- a/lib/json/ld/reader.rb +++ b/lib/json/ld/reader.rb @@ -57,7 +57,7 @@ def self.options end ## - # Initializes the RDF/JSON reader instance. + # Initializes the JSON-LD reader instance. # # @param [IO, File, String] input # @param [Hash{Symbol => Object}] options diff --git a/lib/json/ld/streaming_reader.rb b/lib/json/ld/streaming_reader.rb index 98429a5..6f60861 100644 --- a/lib/json/ld/streaming_reader.rb +++ b/lib/json/ld/streaming_reader.rb @@ -26,7 +26,8 @@ def stream_statement(&block) unique_bnodes, rename_bnodes = @options[:unique_bnodes], @options.fetch(:rename_bnodes, true) # FIXME: document loader doesn't stream @base = RDF::URI(@options[:base] || base_uri) - value = MultiJson.load(@doc, **@options) + mj_opts = @options.keep_if {|k,v| k != :adapter || MUTLI_JSON_ADAPTERS.include?(v)} + value = MultiJson.load(@doc, mj_opts) context_ref = @options[:expandContext] #context_ref = @options.fetch(:expandContext, remote_doc.contextUrl) context = Context.parse(context_ref, **@options) diff --git a/lib/json/ld/writer.rb b/lib/json/ld/writer.rb index 93c2af5..7d6f043 100644 --- a/lib/json/ld/writer.rb +++ b/lib/json/ld/writer.rb @@ -186,10 +186,6 @@ class << self # @return [Boolean] # @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1 def accept?(accept_params) - # Profiles that aren't specific IANA relations represent the URL - # of a context or frame that may be subject to black- or white-listing - profile = accept_params[:profile].to_s.split(/\s+/) - if block_given? yield(accept_params) else @@ -303,7 +299,7 @@ def write_epilogue else log_debug("writer") { "serialize #{@repo.count} statements, #{@options.inspect}"} - result = API.fromRdf(@repo, **@options) + result = API.fromRdf(@repo, **@options.merge(serializer: nil)) # Some options may be indicated from accept parameters profile = @options.fetch(:accept_params, {}).fetch(:profile, "").split(' ') @@ -325,17 +321,17 @@ def write_epilogue # Rename BNodes to uniquify them, if necessary if options[:unique_bnodes] - result = API.flatten(result, context, **@options) + result = API.flatten(result, context, **@options.merge(serializer: nil)) end if frame = @options[:frame] # Perform framing, if given a frame log_debug("writer") { "frame result"} - result = API.frame(result, frame, **@options) + result = API.frame(result, frame, **@options.merge(serializer: nil)) elsif context # Perform compaction, if we have a context log_debug("writer") { "compact result"} - result = API.compact(result, context, **@options) + result = API.compact(result, context, **@options.merge(serializer: nil)) end @output.write(@serializer.call(result)) diff --git a/spec/api_spec.rb b/spec/api_spec.rb index d574f65..6269022 100644 --- a/spec/api_spec.rb +++ b/spec/api_spec.rb @@ -48,77 +48,75 @@ context "with MultiJson adapter #{adapter.inspect}" do Dir.glob(File.expand_path(File.join(File.dirname(__FILE__), 'test-files/*-input.*'))) do |filename| test = File.basename(filename).sub(/-input\..*$/, '') - frame = filename.sub(/-input\..*$/, '-frame.json') - framed = filename.sub(/-input\..*$/, '-framed.json') - compacted = filename.sub(/-input\..*$/, '-compacted.json') - context = filename.sub(/-input\..*$/, '-context.json') - expanded = filename.sub(/-input\..*$/, '-expanded.json') + frame = filename.sub(/-input\..*$/, '-frame.jsonld') + framed = filename.sub(/-input\..*$/, '-framed.jsonld') + compacted = filename.sub(/-input\..*$/, '-compacted.jsonld') + context = filename.sub(/-input\..*$/, '-context.jsonld') + expanded = filename.sub(/-input\..*$/, '-expanded.jsonld') ttl = filename.sub(/-input\..*$/, '-rdf.ttl') context test, skip: ("Not supported in JRuby" if RUBY_ENGINE == "jruby" && %w(oj yajl).include?(adapter.to_s)) do + around do |example| + @file = File.open(filename) + case filename + when /.jsonld$/ + @file.define_singleton_method(:content_type) {'application/ld+json'} + end + if context + @ctx_io = File.open(context) + case context + when /.jsonld$/ + @ctx_io.define_singleton_method(:content_type) {'application/ld+json'} + end + end + example.run + @file.close + @ctx_io.close if @ctx_io + end + if File.exist?(expanded) it "expands" do options = {logger: logger, adapter: adapter} - File.open(context) do |ctx_io| - File.open(filename) do |file| - options[:expandContext] = ctx_io if context - jld = described_class.expand(file, **options) - expect(jld).to produce_jsonld(JSON.parse(File.read(expanded)), logger) - end - end + options[:expandContext] = @ctx_io if context + jld = described_class.expand(@file, **options) + expect(jld).to produce_jsonld(JSON.parse(File.read(expanded)), logger) end it "expands with serializer" do options = {logger: logger, adapter: adapter} - File.open(context) do |ctx_io| - File.open(filename) do |file| - options[:expandContext] = ctx_io if context - jld = described_class.expand(file, serializer: JSON::LD::API.method(:serializer), **options) - expect(jld).to be_a(String) - expect(JSON.load(jld)).to produce_jsonld(JSON.parse(File.read(expanded)), logger) - end - end + options[:expandContext] = @ctx_io if context + jld = described_class.expand(@file, serializer: JSON::LD::API.method(:serializer), **options) + expect(jld).to be_a(String) + expect(JSON.load(jld)).to produce_jsonld(JSON.parse(File.read(expanded)), logger) end end if File.exist?(compacted) && File.exist?(context) it "compacts" do - File.open(context) do |ctx_io| - File.open(filename) do |file| - jld = described_class.compact(file, ctx_io, adapter: adapter, logger: logger) - expect(jld).to produce_jsonld(JSON.parse(File.read(compacted)), logger) - end - end + jld = described_class.compact(@file, @ctx_io, adapter: adapter, logger: logger) + expect(jld).to produce_jsonld(JSON.parse(File.read(compacted)), logger) end it "compacts with serializer" do - File.open(context) do |ctx_io| - File.open(filename) do |file| - jld = described_class.compact(file, ctx_io, serializer: JSON::LD::API.method(:serializer), adapter: adapter, logger: logger) - expect(jld).to be_a(String) - expect(JSON.load(jld)).to produce_jsonld(JSON.parse(File.read(compacted)), logger) - end - end + jld = described_class.compact(@file, @ctx_io, serializer: JSON::LD::API.method(:serializer), adapter: adapter, logger: logger) + expect(jld).to be_a(String) + expect(JSON.load(jld)).to produce_jsonld(JSON.parse(File.read(compacted)), logger) end end if File.exist?(framed) && File.exist?(frame) it "frames" do File.open(frame) do |frame_io| - File.open(filename) do |file| - jld = described_class.frame(file, frame_io, adapter: adapter, logger: logger) - expect(jld).to produce_jsonld(JSON.parse(File.read(framed)), logger) - end + jld = described_class.frame(@file, frame_io, adapter: adapter, logger: logger) + expect(jld).to produce_jsonld(JSON.parse(File.read(framed)), logger) end end it "frames with serializer" do File.open(frame) do |frame_io| - File.open(filename) do |file| - jld = described_class.frame(file, frame_io, serializer: JSON::LD::API.method(:serializer), adapter: adapter, logger: logger) - expect(jld).to be_a(String) - expect(JSON.load(jld)).to produce_jsonld(JSON.parse(File.read(framed)), logger) - end + jld = described_class.frame(@file, frame_io, serializer: JSON::LD::API.method(:serializer), adapter: adapter, logger: logger) + expect(jld).to be_a(String) + expect(JSON.load(jld)).to produce_jsonld(JSON.parse(File.read(framed)), logger) end end end diff --git a/spec/format_spec.rb b/spec/format_spec.rb index 812f07d..f23cb97 100644 --- a/spec/format_spec.rb +++ b/spec/format_spec.rb @@ -73,8 +73,8 @@ describe ".cli_commands", skip: Gem.win_platform? do require 'rdf/cli' let(:ttl) {File.expand_path("../test-files/test-1-rdf.ttl", __FILE__)} - let(:json) {File.expand_path("../test-files/test-1-input.json", __FILE__)} - let(:context) {File.expand_path("../test-files/test-1-context.json", __FILE__)} + let(:json) {File.expand_path("../test-files/test-1-input.jsonld", __FILE__)} + let(:context) {File.expand_path("../test-files/test-1-context.jsonld", __FILE__)} describe "#expand" do it "expands RDF" do diff --git a/spec/test-files/test-1-compacted.json b/spec/test-files/test-1-compacted.jsonld similarity index 100% rename from spec/test-files/test-1-compacted.json rename to spec/test-files/test-1-compacted.jsonld diff --git a/spec/test-files/test-1-context.json b/spec/test-files/test-1-context.jsonld similarity index 100% rename from spec/test-files/test-1-context.json rename to spec/test-files/test-1-context.jsonld diff --git a/spec/test-files/test-1-expanded.json b/spec/test-files/test-1-expanded.jsonld similarity index 100% rename from spec/test-files/test-1-expanded.json rename to spec/test-files/test-1-expanded.jsonld diff --git a/spec/test-files/test-1-input.json b/spec/test-files/test-1-input.jsonld similarity index 100% rename from spec/test-files/test-1-input.json rename to spec/test-files/test-1-input.jsonld diff --git a/spec/test-files/test-1-normalized.json b/spec/test-files/test-1-normalized.json deleted file mode 100644 index 0995f56..0000000 --- a/spec/test-files/test-1-normalized.json +++ /dev/null @@ -1,8 +0,0 @@ -[{ - "@id": { - "@id": "_:c14n0" - }, - "http://xmlns.com/foaf/0.1/avatar": "http://twitter.com/account/profile_image/manusporny", - "http://xmlns.com/foaf/0.1/homepage": "http://manu.sporny.org/", - "http://xmlns.com/foaf/0.1/name": "Manu Sporny" -}] diff --git a/spec/test-files/test-2-compacted.json b/spec/test-files/test-2-compacted.jsonld similarity index 100% rename from spec/test-files/test-2-compacted.json rename to spec/test-files/test-2-compacted.jsonld diff --git a/spec/test-files/test-2-context.json b/spec/test-files/test-2-context.jsonld similarity index 100% rename from spec/test-files/test-2-context.json rename to spec/test-files/test-2-context.jsonld diff --git a/spec/test-files/test-2-expanded.json b/spec/test-files/test-2-expanded.jsonld similarity index 100% rename from spec/test-files/test-2-expanded.json rename to spec/test-files/test-2-expanded.jsonld diff --git a/spec/test-files/test-2-input.json b/spec/test-files/test-2-input.jsonld similarity index 100% rename from spec/test-files/test-2-input.json rename to spec/test-files/test-2-input.jsonld diff --git a/spec/test-files/test-2-normalized.json b/spec/test-files/test-2-normalized.json deleted file mode 100644 index a6b9c6f..0000000 --- a/spec/test-files/test-2-normalized.json +++ /dev/null @@ -1,32 +0,0 @@ -[{ - "@id": { - "@id": "http://example.org/library" - }, - "http://example.org/vocab#contains": { - "@id": "http://example.org/library/the-republic" - }, - "http://www.w3.org/1999/02/22-rdf-syntax-ns#type": { - "@id": "http://example.org/vocab#Library" - } -}, { - "@id": { - "@id": "http://example.org/library/the-republic" - }, - "http://example.org/vocab#contains": { - "@id": "http://example.org/library/the-republic#introduction" - }, - "http://purl.org/dc/elements/1.1/creator": "Plato", - "http://purl.org/dc/elements/1.1/title": "The Republic", - "@type": { - "@id": "http://example.org/vocab#Book" - } -}, { - "@id": { - "@id": "http://example.org/library/the-republic#introduction" - }, - "http://purl.org/dc/elements/1.1/description": "An introductory chapter on The Republic.", - "http://purl.org/dc/elements/1.1/title": "The Introduction", - "@type": { - "@id": "http://example.org/vocab#Chapter" - } -}] diff --git a/spec/test-files/test-3-compacted.json b/spec/test-files/test-3-compacted.jsonld similarity index 100% rename from spec/test-files/test-3-compacted.json rename to spec/test-files/test-3-compacted.jsonld diff --git a/spec/test-files/test-3-context.json b/spec/test-files/test-3-context.jsonld similarity index 100% rename from spec/test-files/test-3-context.json rename to spec/test-files/test-3-context.jsonld diff --git a/spec/test-files/test-3-expanded.json b/spec/test-files/test-3-expanded.jsonld similarity index 100% rename from spec/test-files/test-3-expanded.json rename to spec/test-files/test-3-expanded.jsonld diff --git a/spec/test-files/test-3-input.json b/spec/test-files/test-3-input.jsonld similarity index 100% rename from spec/test-files/test-3-input.json rename to spec/test-files/test-3-input.jsonld diff --git a/spec/test-files/test-3-normalized.json b/spec/test-files/test-3-normalized.json deleted file mode 100644 index 629da91..0000000 --- a/spec/test-files/test-3-normalized.json +++ /dev/null @@ -1,13 +0,0 @@ -[{ - "@id": { - "@id": "_:c14n0" - }, - "http://xmlns.com/foaf/0.1/age": { - "@type": "http://www.w3.org/2001/XMLSchema#integer", - "@value": "41" - }, - "http://xmlns.com/foaf/0.1/homepage": { - "@id": "http://manu.sporny.org/" - }, - "http://xmlns.com/foaf/0.1/name": "Manu Sporny" -}] diff --git a/spec/test-files/test-4-compacted.json b/spec/test-files/test-4-compacted.jsonld similarity index 100% rename from spec/test-files/test-4-compacted.json rename to spec/test-files/test-4-compacted.jsonld diff --git a/spec/test-files/test-4-context.json b/spec/test-files/test-4-context.jsonld similarity index 100% rename from spec/test-files/test-4-context.json rename to spec/test-files/test-4-context.jsonld diff --git a/spec/test-files/test-4-expanded.json b/spec/test-files/test-4-expanded.jsonld similarity index 100% rename from spec/test-files/test-4-expanded.json rename to spec/test-files/test-4-expanded.jsonld diff --git a/spec/test-files/test-4-input.json b/spec/test-files/test-4-input.jsonld similarity index 100% rename from spec/test-files/test-4-input.json rename to spec/test-files/test-4-input.jsonld diff --git a/spec/test-files/test-5-compacted.json b/spec/test-files/test-5-compacted.jsonld similarity index 100% rename from spec/test-files/test-5-compacted.json rename to spec/test-files/test-5-compacted.jsonld diff --git a/spec/test-files/test-5-context.json b/spec/test-files/test-5-context.jsonld similarity index 100% rename from spec/test-files/test-5-context.json rename to spec/test-files/test-5-context.jsonld diff --git a/spec/test-files/test-5-expanded.json b/spec/test-files/test-5-expanded.jsonld similarity index 100% rename from spec/test-files/test-5-expanded.json rename to spec/test-files/test-5-expanded.jsonld diff --git a/spec/test-files/test-5-input.json b/spec/test-files/test-5-input.jsonld similarity index 100% rename from spec/test-files/test-5-input.json rename to spec/test-files/test-5-input.jsonld diff --git a/spec/test-files/test-6-compacted.json b/spec/test-files/test-6-compacted.jsonld similarity index 100% rename from spec/test-files/test-6-compacted.json rename to spec/test-files/test-6-compacted.jsonld diff --git a/spec/test-files/test-6-context.json b/spec/test-files/test-6-context.jsonld similarity index 100% rename from spec/test-files/test-6-context.json rename to spec/test-files/test-6-context.jsonld diff --git a/spec/test-files/test-6-expanded.json b/spec/test-files/test-6-expanded.jsonld similarity index 100% rename from spec/test-files/test-6-expanded.json rename to spec/test-files/test-6-expanded.jsonld diff --git a/spec/test-files/test-6-input.json b/spec/test-files/test-6-input.jsonld similarity index 100% rename from spec/test-files/test-6-input.json rename to spec/test-files/test-6-input.jsonld diff --git a/spec/test-files/test-7-compacted.json b/spec/test-files/test-7-compacted.jsonld similarity index 100% rename from spec/test-files/test-7-compacted.json rename to spec/test-files/test-7-compacted.jsonld diff --git a/spec/test-files/test-7-context.json b/spec/test-files/test-7-context.jsonld similarity index 100% rename from spec/test-files/test-7-context.json rename to spec/test-files/test-7-context.jsonld diff --git a/spec/test-files/test-7-expanded.json b/spec/test-files/test-7-expanded.jsonld similarity index 100% rename from spec/test-files/test-7-expanded.json rename to spec/test-files/test-7-expanded.jsonld diff --git a/spec/test-files/test-7-input.json b/spec/test-files/test-7-input.jsonld similarity index 100% rename from spec/test-files/test-7-input.json rename to spec/test-files/test-7-input.jsonld diff --git a/spec/test-files/test-8-compacted.json b/spec/test-files/test-8-compacted.jsonld similarity index 100% rename from spec/test-files/test-8-compacted.json rename to spec/test-files/test-8-compacted.jsonld diff --git a/spec/test-files/test-8-context.json b/spec/test-files/test-8-context.jsonld similarity index 100% rename from spec/test-files/test-8-context.json rename to spec/test-files/test-8-context.jsonld diff --git a/spec/test-files/test-8-expanded.json b/spec/test-files/test-8-expanded.jsonld similarity index 100% rename from spec/test-files/test-8-expanded.json rename to spec/test-files/test-8-expanded.jsonld diff --git a/spec/test-files/test-8-frame.json b/spec/test-files/test-8-frame.jsonld similarity index 100% rename from spec/test-files/test-8-frame.json rename to spec/test-files/test-8-frame.jsonld diff --git a/spec/test-files/test-8-framed.json b/spec/test-files/test-8-framed.jsonld similarity index 100% rename from spec/test-files/test-8-framed.json rename to spec/test-files/test-8-framed.jsonld diff --git a/spec/test-files/test-8-input.json b/spec/test-files/test-8-input.jsonld similarity index 100% rename from spec/test-files/test-8-input.json rename to spec/test-files/test-8-input.jsonld diff --git a/spec/test-files/test-9-compacted.json b/spec/test-files/test-9-compacted.jsonld similarity index 100% rename from spec/test-files/test-9-compacted.json rename to spec/test-files/test-9-compacted.jsonld diff --git a/spec/test-files/test-9-context.json b/spec/test-files/test-9-context.jsonld similarity index 100% rename from spec/test-files/test-9-context.json rename to spec/test-files/test-9-context.jsonld diff --git a/spec/test-files/test-9-expanded.json b/spec/test-files/test-9-expanded.jsonld similarity index 100% rename from spec/test-files/test-9-expanded.json rename to spec/test-files/test-9-expanded.jsonld diff --git a/spec/test-files/test-9-input.json b/spec/test-files/test-9-input.jsonld similarity index 100% rename from spec/test-files/test-9-input.json rename to spec/test-files/test-9-input.jsonld From 18e417dfb4a98560cbe32ea86085b52a5c577ab9 Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Thu, 4 Aug 2022 13:21:47 -0700 Subject: [PATCH 4/5] Allo for extra arguments and options to the serializer interface. --- README.md | 4 ++-- lib/json/ld/api.rb | 16 ++++++++++------ lib/json/ld/writer.rb | 2 +- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 7229289..cef60d9 100755 --- a/README.md +++ b/README.md @@ -32,10 +32,10 @@ This gem also implements an optimized streaming writer used for generating JSON- * Each statement written as a separate node in expanded/flattened form. * `RDF List`s are written as separate nodes using `rdf:first` and `rdf:rest` properties. -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_. +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_. ### MultiJson parser -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. +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. ### JSON-LD-star (RDFStar) diff --git a/lib/json/ld/api.rb b/lib/json/ld/api.rb index 18d4d83..af0266e 100644 --- a/lib/json/ld/api.rb +++ b/lib/json/ld/api.rb @@ -184,7 +184,7 @@ def self.expand(input, framing: false, serializer: nil, **options, &block) # Finally, if element is a JSON object, it is wrapped into an array. result = [result].compact unless result.is_a?(Array) - result = serializer.call(result) if serializer + result = serializer.call(result, **options) if serializer if block_given? case block.arity @@ -246,7 +246,7 @@ def self.compact(input, context, expanded: false, serializer: nil, **options) end result = ctx.merge(result) unless ctx.fetch('@context', {}).empty? end - result = serializer.call(result) if serializer + result = serializer.call(result, **options) if serializer block_given? ? yield(result) : result end @@ -330,7 +330,7 @@ def self.flatten(input, context, expanded: false, serializer: nil, **options) end end - flattened = serializer.call(flattened) if serializer + flattened = serializer.call(flattened, **options) if serializer block_given? ? yield(flattened) : flattened end @@ -481,7 +481,7 @@ def self.frame(input, frame, expanded: false, serializer: nil, **options) result end - result = serializer.call(result) if serializer + result = serializer.call(result, **options) if serializer block_given? ? yield(result) : result end @@ -566,7 +566,7 @@ def self.fromRdf(input, useRdfType: false, useNativeTypes: false, serializer: ni useNativeTypes: useNativeTypes) end - result = serializer.call(result) if serializer + result = serializer.call(result, **options) if serializer block_given? ? yield(result) : result end @@ -823,7 +823,11 @@ def self.load_html(input, url:, # Defaults to `MultiJson.dump` # # @param [Object] object - def self.serializer(object) + # @param [Array] args + # other arguments that may be passed for some specific implementation. + # @param [Hash] options + # options passed from the invoking context. + def self.serializer(object, *args, **options) MultiJson.dump(object, JSON_STATE) end diff --git a/lib/json/ld/writer.rb b/lib/json/ld/writer.rb index 7d6f043..ec681bf 100644 --- a/lib/json/ld/writer.rb +++ b/lib/json/ld/writer.rb @@ -334,7 +334,7 @@ def write_epilogue result = API.compact(result, context, **@options.merge(serializer: nil)) end - @output.write(@serializer.call(result)) + @output.write(@serializer.call(result, **@options)) end super From 6b73ffee3d41b09a9085041eb8497139d8cb5080 Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Thu, 4 Aug 2022 13:49:44 -0700 Subject: [PATCH 5/5] Version 3.2.2. --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index e4604e3..be94e6f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.2.1 +3.2.2