json-ld 2.2.1 → 3.0.0
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 +5 -5
 - data/README.md +55 -55
 - data/VERSION +1 -1
 - data/lib/json/ld.rb +4 -2
 - data/lib/json/ld/api.rb +49 -59
 - data/lib/json/ld/compact.rb +60 -56
 - data/lib/json/ld/context.rb +52 -40
 - data/lib/json/ld/expand.rb +53 -61
 - data/lib/json/ld/extensions.rb +31 -16
 - data/lib/json/ld/flatten.rb +99 -90
 - data/lib/json/ld/format.rb +2 -2
 - data/lib/json/ld/frame.rb +47 -30
 - data/lib/json/ld/from_rdf.rb +31 -23
 - data/lib/json/ld/resource.rb +1 -1
 - data/lib/json/ld/to_rdf.rb +4 -2
 - data/lib/json/ld/utils.rb +25 -35
 - data/lib/json/ld/writer.rb +25 -1
 - data/spec/api_spec.rb +1 -0
 - data/spec/compact_spec.rb +536 -31
 - data/spec/context_spec.rb +109 -43
 - data/spec/expand_spec.rb +413 -18
 - data/spec/flatten_spec.rb +107 -27
 - data/spec/frame_spec.rb +255 -34
 - data/spec/from_rdf_spec.rb +102 -3
 - data/spec/streaming_writer_spec.rb +8 -9
 - data/spec/suite_compact_spec.rb +2 -2
 - data/spec/suite_expand_spec.rb +2 -2
 - data/spec/suite_flatten_spec.rb +2 -2
 - data/spec/suite_frame_spec.rb +2 -2
 - data/spec/suite_from_rdf_spec.rb +2 -3
 - data/spec/suite_helper.rb +57 -61
 - data/spec/suite_remote_doc_spec.rb +2 -2
 - data/spec/suite_to_rdf_spec.rb +4 -4
 - data/spec/to_rdf_spec.rb +88 -1
 - data/spec/writer_spec.rb +5 -6
 - metadata +5 -7
 - data/spec/suite_error_spec.rb +0 -16
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 2 
     | 
    
         
            +
            SHA256:
         
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 33d72fb295b05e075532454ade144d79cf15458946492639f9a941a62668c510
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: a382b3bdf08bc1b377d5d01f8d2bae93631e7f9077161fd6bbddfd7477a4c775
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: fea935d4ce21a779b4d6eb2bd38eaf8f0859b4e312b8baa509e3325663597cffcef934e3210dda62e339b08d86dc689458fc331b5edf86e500b28ffbe4679548
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 1d589f193efd2725ac4ac4d200de04fea6d13296fa7ad3989cf40cfed30424dd91dfb27ced0eda4ce88d0f5676e90b36e5b4cff8185afac9644fd3cc7edd7c0a
         
     | 
    
        data/README.md
    CHANGED
    
    | 
         @@ -28,13 +28,13 @@ This gem implements an optimized streaming writer used for generating JSON-LD fr 
     | 
|
| 
       28 
28 
     | 
    
         
             
            * RDF Lists are written as separate nodes using `rdf:first` and `rdf:rest` properties.
         
     | 
| 
       29 
29 
     | 
    
         | 
| 
       30 
30 
     | 
    
         
             
            ## Examples
         
     | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
      
 31 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 32 
     | 
    
         
            +
            require 'rubygems'
         
     | 
| 
      
 33 
     | 
    
         
            +
            require 'json/ld'
         
     | 
| 
      
 34 
     | 
    
         
            +
             ```
         
     | 
| 
       35 
35 
     | 
    
         
             
            ### Expand a Document
         
     | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
       37 
     | 
    
         
            -
             
     | 
| 
      
 36 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 37 
     | 
    
         
            +
               input = JSON.parse %({
         
     | 
| 
       38 
38 
     | 
    
         
             
                  "@context": {
         
     | 
| 
       39 
39 
     | 
    
         
             
                    "name": "http://xmlns.com/foaf/0.1/name",
         
     | 
| 
       40 
40 
     | 
    
         
             
                    "homepage": "http://xmlns.com/foaf/0.1/homepage",
         
     | 
| 
         @@ -51,9 +51,9 @@ This gem implements an optimized streaming writer used for generating JSON-LD fr 
     | 
|
| 
       51 
51 
     | 
    
         
             
                    "http://xmlns.com/foaf/0.1/homepage": [{"@value"=>"http://manu.sporny.org/"}], 
         
     | 
| 
       52 
52 
     | 
    
         
             
                    "http://xmlns.com/foaf/0.1/avatar": [{"@value": "http://twitter.com/account/profile_image/manusporny"}]
         
     | 
| 
       53 
53 
     | 
    
         
             
                }]
         
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
      
 54 
     | 
    
         
            +
            ```
         
     | 
| 
       55 
55 
     | 
    
         
             
            ### Compact a Document
         
     | 
| 
       56 
     | 
    
         
            -
             
     | 
| 
      
 56 
     | 
    
         
            +
            ```ruby
         
     | 
| 
       57 
57 
     | 
    
         
             
                input = JSON.parse %([{
         
     | 
| 
       58 
58 
     | 
    
         
             
                    "http://xmlns.com/foaf/0.1/name": ["Manu Sporny"],
         
     | 
| 
       59 
59 
     | 
    
         
             
                    "http://xmlns.com/foaf/0.1/homepage": [{"@id": "http://manu.sporny.org/"}],
         
     | 
| 
         @@ -79,9 +79,9 @@ This gem implements an optimized streaming writer used for generating JSON-LD fr 
     | 
|
| 
       79 
79 
     | 
    
         
             
                    "homepage": "http://manu.sporny.org/",
         
     | 
| 
       80 
80 
     | 
    
         
             
                    "name": "Manu Sporny"
         
     | 
| 
       81 
81 
     | 
    
         
             
                }
         
     | 
| 
       82 
     | 
    
         
            -
             
     | 
| 
      
 82 
     | 
    
         
            +
            ```
         
     | 
| 
       83 
83 
     | 
    
         
             
            ### Frame a Document
         
     | 
| 
       84 
     | 
    
         
            -
             
     | 
| 
      
 84 
     | 
    
         
            +
            ```ruby
         
     | 
| 
       85 
85 
     | 
    
         
             
                input = JSON.parse %({
         
     | 
| 
       86 
86 
     | 
    
         
             
                  "@context": {
         
     | 
| 
       87 
87 
     | 
    
         
             
                    "Book":         "http://example.org/vocab#Book",
         
     | 
| 
         @@ -162,9 +162,9 @@ This gem implements an optimized streaming writer used for generating JSON-LD fr 
     | 
|
| 
       162 
162 
     | 
    
         
             
                    }
         
     | 
| 
       163 
163 
     | 
    
         
             
                  ]
         
     | 
| 
       164 
164 
     | 
    
         
             
                }
         
     | 
| 
       165 
     | 
    
         
            -
             
     | 
| 
      
 165 
     | 
    
         
            +
            ```
         
     | 
| 
       166 
166 
     | 
    
         
             
            ### Turn JSON-LD into RDF (Turtle)
         
     | 
| 
       167 
     | 
    
         
            -
             
     | 
| 
      
 167 
     | 
    
         
            +
            ```ruby
         
     | 
| 
       168 
168 
     | 
    
         
             
                input = JSON.parse %({
         
     | 
| 
       169 
169 
     | 
    
         
             
                  "@context": {
         
     | 
| 
       170 
170 
     | 
    
         
             
                    "":       "http://manu.sporny.org/",
         
     | 
| 
         @@ -185,9 +185,9 @@ This gem implements an optimized streaming writer used for generating JSON-LD fr 
     | 
|
| 
       185 
185 
     | 
    
         
             
                <http://example.org/people#joebob> a foaf:Person;
         
     | 
| 
       186 
186 
     | 
    
         
             
                   foaf:name "Joe Bob";
         
     | 
| 
       187 
187 
     | 
    
         
             
                   foaf:nick ("joe" "bob" "jaybe") .
         
     | 
| 
       188 
     | 
    
         
            -
             
     | 
| 
      
 188 
     | 
    
         
            +
            ```
         
     | 
| 
       189 
189 
     | 
    
         
             
            ### Turn RDF into JSON-LD
         
     | 
| 
       190 
     | 
    
         
            -
             
     | 
| 
      
 190 
     | 
    
         
            +
            ```ruby
         
     | 
| 
       191 
191 
     | 
    
         
             
                require 'rdf/turtle'
         
     | 
| 
       192 
192 
     | 
    
         
             
                input = RDF::Graph.new << RDF::Turtle::Reader.new(%(
         
     | 
| 
       193 
193 
     | 
    
         
             
                  @prefix foaf: <http://xmlns.com/foaf/0.1/> .
         
     | 
| 
         @@ -223,12 +223,12 @@ This gem implements an optimized streaming writer used for generating JSON-LD fr 
     | 
|
| 
       223 
223 
     | 
    
         
             
                      "http://xmlns.com/foaf/0.1/name": [{"@value": "Manu Sporny"}]
         
     | 
| 
       224 
224 
     | 
    
         
             
                    }
         
     | 
| 
       225 
225 
     | 
    
         
             
                  ]
         
     | 
| 
       226 
     | 
    
         
            -
             
     | 
| 
      
 226 
     | 
    
         
            +
            ```
         
     | 
| 
       227 
227 
     | 
    
         
             
            ## Use a custom Document Loader
         
     | 
| 
       228 
228 
     | 
    
         
             
            In some cases, the built-in document loader {JSON::LD::API.documentLoader} is inadequate; for example, when using `http://schema.org` as a remote context, it will be re-loaded every time.
         
     | 
| 
       229 
229 
     | 
    
         | 
| 
       230 
230 
     | 
    
         
             
            All entries into the {JSON::LD::API} accept a `:documentLoader` option, which can be used to provide an alternative method to use when loading remote documents. For example:
         
     | 
| 
       231 
     | 
    
         
            -
             
     | 
| 
      
 231 
     | 
    
         
            +
            ```ruby
         
     | 
| 
       232 
232 
     | 
    
         
             
                def load_document_local(url, options={}, &block)
         
     | 
| 
       233 
233 
     | 
    
         
             
                  if RDF::URI(url, canonicalize: true) == RDF::URI('http://schema.org/')
         
     | 
| 
       234 
234 
     | 
    
         
             
                    remote_document = JSON::LD::API::RemoteDocument.new(url, File.read("etc/schema.org.jsonld"))
         
     | 
| 
         @@ -237,28 +237,28 @@ All entries into the {JSON::LD::API} accept a `:documentLoader` option, which ca 
     | 
|
| 
       237 
237 
     | 
    
         
             
                    JSON::LD::API.documentLoader(url, options, &block)
         
     | 
| 
       238 
238 
     | 
    
         
             
                  end
         
     | 
| 
       239 
239 
     | 
    
         
             
                end
         
     | 
| 
       240 
     | 
    
         
            -
             
     | 
| 
      
 240 
     | 
    
         
            +
            ```
         
     | 
| 
       241 
241 
     | 
    
         
             
            Then, when performing something like expansion:
         
     | 
| 
       242 
     | 
    
         
            -
             
     | 
| 
      
 242 
     | 
    
         
            +
            ```ruby
         
     | 
| 
       243 
243 
     | 
    
         
             
                JSON::LD::API.expand(input, documentLoader: load_document_local)
         
     | 
| 
       244 
     | 
    
         
            -
             
     | 
| 
      
 244 
     | 
    
         
            +
            ```
         
     | 
| 
       245 
245 
     | 
    
         | 
| 
       246 
246 
     | 
    
         
             
            ## Preloading contexts
         
     | 
| 
       247 
247 
     | 
    
         
             
            In many cases, for small documents, processing time can be dominated by loading and parsing remote contexts. In particular, a small schema.org example may need to download a large context and turn it into an internal representation, before the actual document can be expanded for processing. Using {JSON::LD::Context.add_preloaded}, an implementation can perform this loading up-front, and make it available to the processor.
         
     | 
| 
       248 
     | 
    
         
            -
             
     | 
| 
      
 248 
     | 
    
         
            +
            ```ruby
         
     | 
| 
       249 
249 
     | 
    
         
             
                ctx = JSON::LD::Context.new().parse('http://schema.org/')
         
     | 
| 
       250 
250 
     | 
    
         
             
                JSON::LD::Context.add_preloaded('http://schema.org/', ctx)
         
     | 
| 
       251 
     | 
    
         
            -
             
     | 
| 
      
 251 
     | 
    
         
            +
             ```
         
     | 
| 
       252 
252 
     | 
    
         
             
            On lookup, URIs with an `https` prefix are normalized to `http`.
         
     | 
| 
       253 
253 
     | 
    
         | 
| 
       254 
254 
     | 
    
         
             
            A context may be serialized to Ruby to speed this process using `Context#to_rb`. When loaded, this generated file will add entries to the {JSON::LD::Context::PRELOADED}.
         
     | 
| 
       255 
255 
     | 
    
         | 
| 
       256 
256 
     | 
    
         
             
            ## RDF Reader and Writer
         
     | 
| 
       257 
257 
     | 
    
         
             
            {JSON::LD} also acts as a normal RDF reader and writer, using the standard RDF.rb reader/writer interfaces:
         
     | 
| 
       258 
     | 
    
         
            -
             
     | 
| 
      
 258 
     | 
    
         
            +
            ```ruby
         
     | 
| 
       259 
259 
     | 
    
         
             
                graph = RDF::Graph.load("etc/doap.jsonld", format: :jsonld)
         
     | 
| 
       260 
260 
     | 
    
         
             
                graph.dump(:jsonld, standard_prefixes: true)
         
     | 
| 
       261 
     | 
    
         
            -
             
     | 
| 
      
 261 
     | 
    
         
            +
            ```
         
     | 
| 
       262 
262 
     | 
    
         
             
            `RDF::GRAPH#dump` can also take a `:context` option to use a separately defined context
         
     | 
| 
       263 
263 
     | 
    
         | 
| 
       264 
264 
     | 
    
         
             
            As JSON-LD may come from many different sources, included as an embedded script tag within an HTML document, the RDF Reader will strip input before the leading `{` or `[` and after the trailing `}` or `]`.
         
     | 
| 
         @@ -268,7 +268,7 @@ This implementation is being used as a test-bed for features planned for an upco 
     | 
|
| 
       268 
268 
     | 
    
         | 
| 
       269 
269 
     | 
    
         
             
            ### Scoped Contexts
         
     | 
| 
       270 
270 
     | 
    
         
             
            A term definition can include `@context`, which is applied to values of that object. This is also used when compacting. Taken together, this allows framing to effectively include context definitions more deeply within the framed structure.
         
     | 
| 
       271 
     | 
    
         
            -
             
     | 
| 
      
 271 
     | 
    
         
            +
            ```ruby
         
     | 
| 
       272 
272 
     | 
    
         
             
                {
         
     | 
| 
       273 
273 
     | 
    
         
             
                  "@context": {
         
     | 
| 
       274 
274 
     | 
    
         
             
                    "ex": "http://example.com/",
         
     | 
| 
         @@ -283,10 +283,10 @@ A term definition can include `@context`, which is applied to values of that obj 
     | 
|
| 
       283 
283 
     | 
    
         
             
                  },
         
     | 
| 
       284 
284 
     | 
    
         
             
                  "foo": "Bar"
         
     | 
| 
       285 
285 
     | 
    
         
             
                }
         
     | 
| 
       286 
     | 
    
         
            -
             
     | 
| 
      
 286 
     | 
    
         
            +
            ```
         
     | 
| 
       287 
287 
     | 
    
         
             
            ### @id and @type maps
         
     | 
| 
       288 
288 
     | 
    
         
             
            The value of `@container` in a term definition can include `@id` or `@type`, in addition to `@set`, `@list`, `@language`, and `@index`. This allows value indexing based on either the `@id` or `@type` of associated objects.
         
     | 
| 
       289 
     | 
    
         
            -
             
     | 
| 
      
 289 
     | 
    
         
            +
            ```ruby
         
     | 
| 
       290 
290 
     | 
    
         
             
                {
         
     | 
| 
       291 
291 
     | 
    
         
             
                  "@context": {
         
     | 
| 
       292 
292 
     | 
    
         
             
                    "@vocab": "http://example/",
         
     | 
| 
         @@ -297,10 +297,10 @@ The value of `@container` in a term definition can include `@id` or `@type`, in 
     | 
|
| 
       297 
297 
     | 
    
         
             
                    "_:bar": {"label": "Object with @id _:bar"}
         
     | 
| 
       298 
298 
     | 
    
         
             
                  }
         
     | 
| 
       299 
299 
     | 
    
         
             
                }
         
     | 
| 
       300 
     | 
    
         
            -
             
     | 
| 
      
 300 
     | 
    
         
            +
            ```
         
     | 
| 
       301 
301 
     | 
    
         
             
            ### @graph containers and maps
         
     | 
| 
       302 
302 
     | 
    
         
             
            A term can have `@container` set to include `@graph` optionally including `@id` or `@index` and `@set`. In the first form, with `@container` set to `@graph`, the value of a property is treated as a _simple graph object_, meaning that values treated as if they were contained in an object with `@graph`, creating _named graph_ with an anonymous name.
         
     | 
| 
       303 
     | 
    
         
            -
             
     | 
| 
      
 303 
     | 
    
         
            +
            ```ruby
         
     | 
| 
       304 
304 
     | 
    
         
             
                {
         
     | 
| 
       305 
305 
     | 
    
         
             
                  "@context": {
         
     | 
| 
       306 
306 
     | 
    
         
             
                    "@vocab": "http://example.org/",
         
     | 
| 
         @@ -310,9 +310,9 @@ A term can have `@container` set to include `@graph` optionally including `@id` 
     | 
|
| 
       310 
310 
     | 
    
         
             
                    "value": "x"
         
     | 
| 
       311 
311 
     | 
    
         
             
                  }
         
     | 
| 
       312 
312 
     | 
    
         
             
                }
         
     | 
| 
       313 
     | 
    
         
            -
             
     | 
| 
      
 313 
     | 
    
         
            +
            ```
         
     | 
| 
       314 
314 
     | 
    
         
             
            which expands to the following:
         
     | 
| 
       315 
     | 
    
         
            -
             
     | 
| 
      
 315 
     | 
    
         
            +
            ```ruby
         
     | 
| 
       316 
316 
     | 
    
         
             
                [{
         
     | 
| 
       317 
317 
     | 
    
         
             
                  "http://example.org/input": [{
         
     | 
| 
       318 
318 
     | 
    
         
             
                    "@graph": [{
         
     | 
| 
         @@ -320,18 +320,18 @@ which expands to the following: 
     | 
|
| 
       320 
320 
     | 
    
         
             
                    }]
         
     | 
| 
       321 
321 
     | 
    
         
             
                  }]
         
     | 
| 
       322 
322 
     | 
    
         
             
                }]
         
     | 
| 
       323 
     | 
    
         
            -
             
     | 
| 
      
 323 
     | 
    
         
            +
            ```
         
     | 
| 
       324 
324 
     | 
    
         
             
            Compaction reverses this process, optionally ensuring that a single value is contained within an array of `@container` also includes `@set`:
         
     | 
| 
       325 
     | 
    
         
            -
             
     | 
| 
      
 325 
     | 
    
         
            +
            ```ruby
         
     | 
| 
       326 
326 
     | 
    
         
             
                {
         
     | 
| 
       327 
327 
     | 
    
         
             
                  "@context": {
         
     | 
| 
       328 
328 
     | 
    
         
             
                    "@vocab": "http://example.org/",
         
     | 
| 
       329 
329 
     | 
    
         
             
                    "input": {"@container": ["@graph", "@set"]}
         
     | 
| 
       330 
330 
     | 
    
         
             
                  }
         
     | 
| 
       331 
331 
     | 
    
         
             
                }
         
     | 
| 
       332 
     | 
    
         
            -
             
     | 
| 
      
 332 
     | 
    
         
            +
            ```
         
     | 
| 
       333 
333 
     | 
    
         
             
            A graph map uses the map form already existing for `@index`, `@language`, `@type`, and `@id` where the index is either an index value or an id.
         
     | 
| 
       334 
     | 
    
         
            -
             
     | 
| 
      
 334 
     | 
    
         
            +
            ```ruby
         
     | 
| 
       335 
335 
     | 
    
         
             
                {
         
     | 
| 
       336 
336 
     | 
    
         
             
                  "@context": {
         
     | 
| 
       337 
337 
     | 
    
         
             
                    "@vocab": "http://example.org/",
         
     | 
| 
         @@ -341,9 +341,9 @@ A graph map uses the map form already existing for `@index`, `@language`, `@type 
     | 
|
| 
       341 
341 
     | 
    
         
             
                    "g1": {"value": "x"}
         
     | 
| 
       342 
342 
     | 
    
         
             
                  }
         
     | 
| 
       343 
343 
     | 
    
         
             
                }
         
     | 
| 
       344 
     | 
    
         
            -
             
     | 
| 
      
 344 
     | 
    
         
            +
            ```
         
     | 
| 
       345 
345 
     | 
    
         
             
            treats "g1" as an index, and expands to the following:
         
     | 
| 
       346 
     | 
    
         
            -
             
     | 
| 
      
 346 
     | 
    
         
            +
            ```ruby
         
     | 
| 
       347 
347 
     | 
    
         
             
                [{
         
     | 
| 
       348 
348 
     | 
    
         
             
                  "http://example.org/input": [{
         
     | 
| 
       349 
349 
     | 
    
         
             
                    "@index": "g1",
         
     | 
| 
         @@ -352,11 +352,11 @@ treats "g1" as an index, and expands to the following: 
     | 
|
| 
       352 
352 
     | 
    
         
             
                    }]
         
     | 
| 
       353 
353 
     | 
    
         
             
                  }]
         
     | 
| 
       354 
354 
     | 
    
         
             
                }])
         
     | 
| 
       355 
     | 
    
         
            -
             
     | 
| 
      
 355 
     | 
    
         
            +
            ```
         
     | 
| 
       356 
356 
     | 
    
         
             
            This can also include `@set` to ensure that, when compacting, a single value of an index will be in array form.
         
     | 
| 
       357 
357 
     | 
    
         | 
| 
       358 
358 
     | 
    
         
             
            The _id_ version is similar:
         
     | 
| 
       359 
     | 
    
         
            -
             
     | 
| 
      
 359 
     | 
    
         
            +
            ```ruby
         
     | 
| 
       360 
360 
     | 
    
         
             
                {
         
     | 
| 
       361 
361 
     | 
    
         
             
                  "@context": {
         
     | 
| 
       362 
362 
     | 
    
         
             
                    "@vocab": "http://example.org/",
         
     | 
| 
         @@ -366,9 +366,9 @@ The _id_ version is similar: 
     | 
|
| 
       366 
366 
     | 
    
         
             
                    "http://example.com/g1": {"value": "x"}
         
     | 
| 
       367 
367 
     | 
    
         
             
                  }
         
     | 
| 
       368 
368 
     | 
    
         
             
                }
         
     | 
| 
       369 
     | 
    
         
            -
             
     | 
| 
      
 369 
     | 
    
         
            +
            ```
         
     | 
| 
       370 
370 
     | 
    
         
             
            which expands to:
         
     | 
| 
       371 
     | 
    
         
            -
             
     | 
| 
      
 371 
     | 
    
         
            +
            ```ruby
         
     | 
| 
       372 
372 
     | 
    
         
             
                [{
         
     | 
| 
       373 
373 
     | 
    
         
             
                  "http://example.org/input": [{
         
     | 
| 
       374 
374 
     | 
    
         
             
                    "@id": "http://example.com/g1",
         
     | 
| 
         @@ -377,10 +377,10 @@ which expands to: 
     | 
|
| 
       377 
377 
     | 
    
         
             
                    }]
         
     | 
| 
       378 
378 
     | 
    
         
             
                  }]
         
     | 
| 
       379 
379 
     | 
    
         
             
                }])
         
     | 
| 
       380 
     | 
    
         
            -
             
     | 
| 
      
 380 
     | 
    
         
            +
            ```
         
     | 
| 
       381 
381 
     | 
    
         
             
            ### Transparent Nesting
         
     | 
| 
       382 
382 
     | 
    
         
             
            Many JSON APIs separate properties from their entities using an intermediate object. For example, a set of possible labels may be grouped under a common property:
         
     | 
| 
       383 
     | 
    
         
            -
             
     | 
| 
      
 383 
     | 
    
         
            +
            ```json
         
     | 
| 
       384 
384 
     | 
    
         
             
                {
         
     | 
| 
       385 
385 
     | 
    
         
             
                  "@context": {
         
     | 
| 
       386 
386 
     | 
    
         
             
                    "skos": "http://www.w3.org/2004/02/skos/core#",
         
     | 
| 
         @@ -396,9 +396,9 @@ Many JSON APIs separate properties from their entities using an intermediate obj 
     | 
|
| 
       396 
396 
     | 
    
         
             
                     "other_label": "This is the other label"
         
     | 
| 
       397 
397 
     | 
    
         
             
                  }
         
     | 
| 
       398 
398 
     | 
    
         
             
                }
         
     | 
| 
       399 
     | 
    
         
            -
             
         
     | 
| 
      
 399 
     | 
    
         
            +
             ```
         
     | 
| 
       400 
400 
     | 
    
         
             
             In this case, the `labels` property is semantically meaningless. Defining it as equivalent to `@nest` causes it to be ignored when expanding, making it equivalent to the following:
         
     | 
| 
       401 
     | 
    
         
            -
             
     | 
| 
      
 401 
     | 
    
         
            +
            ```json
         
     | 
| 
       402 
402 
     | 
    
         
             
                {
         
     | 
| 
       403 
403 
     | 
    
         
             
                  "@context": {
         
     | 
| 
       404 
404 
     | 
    
         
             
                    "skos": "http://www.w3.org/2004/02/skos/core#",
         
     | 
| 
         @@ -412,9 +412,9 @@ Many JSON APIs separate properties from their entities using an intermediate obj 
     | 
|
| 
       412 
412 
     | 
    
         
             
                  "main_label": "This is the main label for my resource",
         
     | 
| 
       413 
413 
     | 
    
         
             
                  "other_label": "This is the other label"
         
     | 
| 
       414 
414 
     | 
    
         
             
                }
         
     | 
| 
       415 
     | 
    
         
            -
             
         
     | 
| 
      
 415 
     | 
    
         
            +
             ```
         
     | 
| 
       416 
416 
     | 
    
         
             
             Similarly, properties may be marked with "@nest": "nest-term", to cause them to be nested. Note that the `@nest` keyword can also be aliased in the context.
         
     | 
| 
       417 
     | 
    
         
            -
             
     | 
| 
      
 417 
     | 
    
         
            +
            ```json
         
     | 
| 
       418 
418 
     | 
    
         
             
                 {
         
     | 
| 
       419 
419 
     | 
    
         
             
                   "@context": {
         
     | 
| 
       420 
420 
     | 
    
         
             
                     "skos": "http://www.w3.org/2004/02/skos/core#",
         
     | 
| 
         @@ -430,7 +430,7 @@ Many JSON APIs separate properties from their entities using an intermediate obj 
     | 
|
| 
       430 
430 
     | 
    
         
             
                      "other_label": "This is the other label"
         
     | 
| 
       431 
431 
     | 
    
         
             
                   }
         
     | 
| 
       432 
432 
     | 
    
         
             
                 }
         
     | 
| 
       433 
     | 
    
         
            -
             
     | 
| 
      
 433 
     | 
    
         
            +
            ```
         
     | 
| 
       434 
434 
     | 
    
         
             
            In this way, nesting survives round-tripping through expansion, and framed output can include nested properties.
         
     | 
| 
       435 
435 
     | 
    
         | 
| 
       436 
436 
     | 
    
         
             
            ### Framing Updates
         
     | 
| 
         @@ -469,20 +469,20 @@ Note, the API method signatures differed in versions before 1.0, in that they al 
     | 
|
| 
       469 
469 
     | 
    
         | 
| 
       470 
470 
     | 
    
         
             
            ## Dependencies
         
     | 
| 
       471 
471 
     | 
    
         
             
            * [Ruby](http://ruby-lang.org/) (>= 2.2.2)
         
     | 
| 
       472 
     | 
    
         
            -
            * [RDF.rb](http://rubygems.org/gems/rdf) ( 
     | 
| 
       473 
     | 
    
         
            -
            * [JSON](https://rubygems.org/gems/json) (>= 1 
     | 
| 
      
 472 
     | 
    
         
            +
            * [RDF.rb](http://rubygems.org/gems/rdf) (~> 3.0)
         
     | 
| 
      
 473 
     | 
    
         
            +
            * [JSON](https://rubygems.org/gems/json) (>= 2.1)
         
     | 
| 
       474 
474 
     | 
    
         | 
| 
       475 
475 
     | 
    
         
             
            ## Installation
         
     | 
| 
       476 
476 
     | 
    
         
             
            The recommended installation method is via [RubyGems](http://rubygems.org/).
         
     | 
| 
       477 
477 
     | 
    
         
             
            To install the latest official release of the `JSON-LD` gem, do:
         
     | 
| 
       478 
     | 
    
         
            -
             
     | 
| 
       479 
     | 
    
         
            -
             
     | 
| 
       480 
     | 
    
         
            -
             
     | 
| 
      
 478 
     | 
    
         
            +
            ```bash
         
     | 
| 
      
 479 
     | 
    
         
            +
             % [sudo] gem install json-ld
         
     | 
| 
      
 480 
     | 
    
         
            +
            ```
         
     | 
| 
       481 
481 
     | 
    
         
             
            ## Download
         
     | 
| 
       482 
482 
     | 
    
         
             
            To get a local working copy of the development repository, do:
         
     | 
| 
       483 
     | 
    
         
            -
             
     | 
| 
       484 
     | 
    
         
            -
             
     | 
| 
       485 
     | 
    
         
            -
             
     | 
| 
      
 483 
     | 
    
         
            +
            ```bash
         
     | 
| 
      
 484 
     | 
    
         
            +
             % git clone git://github.com/ruby-rdf/json-ld.git
         
     | 
| 
      
 485 
     | 
    
         
            +
            ```
         
     | 
| 
       486 
486 
     | 
    
         
             
            ## Mailing List
         
     | 
| 
       487 
487 
     | 
    
         
             
            * <http://lists.w3.org/Archives/Public/public-rdf-ruby/>
         
     | 
| 
       488 
488 
     | 
    
         | 
    
        data/VERSION
    CHANGED
    
    | 
         @@ -1 +1 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
             
     | 
| 
      
 1 
     | 
    
         
            +
            3.0.0
         
     | 
    
        data/lib/json/ld.rb
    CHANGED
    
    | 
         @@ -55,6 +55,7 @@ module JSON 
     | 
|
| 
       55 
55 
     | 
    
         
             
                  @language
         
     | 
| 
       56 
56 
     | 
    
         
             
                  @list
         
     | 
| 
       57 
57 
     | 
    
         
             
                  @nest
         
     | 
| 
      
 58 
     | 
    
         
            +
                  @none
         
     | 
| 
       58 
59 
     | 
    
         
             
                  @omitDefault
         
     | 
| 
       59 
60 
     | 
    
         
             
                  @requireAll
         
     | 
| 
       60 
61 
     | 
    
         
             
                  @reverse
         
     | 
| 
         @@ -90,6 +91,8 @@ module JSON 
     | 
|
| 
       90 
91 
     | 
    
         
             
                  array_nl:     "\n"
         
     | 
| 
       91 
92 
     | 
    
         
             
                )
         
     | 
| 
       92 
93 
     | 
    
         | 
| 
      
 94 
     | 
    
         
            +
                MAX_CONTEXTS_LOADED = 50
         
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
       93 
96 
     | 
    
         
             
                class JsonLdError < StandardError
         
     | 
| 
       94 
97 
     | 
    
         
             
                  def to_s
         
     | 
| 
       95 
98 
     | 
    
         
             
                    "#{self.class.instance_variable_get :@code}: #{super}"
         
     | 
| 
         @@ -99,7 +102,6 @@ module JSON 
     | 
|
| 
       99 
102 
     | 
    
         
             
                  end
         
     | 
| 
       100 
103 
     | 
    
         | 
| 
       101 
104 
     | 
    
         
             
                  class CollidingKeywords < JsonLdError; @code = "colliding keywords"; end
         
     | 
| 
       102 
     | 
    
         
            -
                  class CompactionToListOfLists < JsonLdError; @code = "compaction to list of lists"; end
         
     | 
| 
       103 
105 
     | 
    
         
             
                  class ConflictingIndexes < JsonLdError; @code = "conflicting indexes"; end
         
     | 
| 
       104 
106 
     | 
    
         
             
                  class CyclicIRIMapping < JsonLdError; @code = "cyclic IRI mapping"; end
         
     | 
| 
       105 
107 
     | 
    
         
             
                  class InvalidBaseIRI < JsonLdError; @code = "invalid base IRI"; end
         
     | 
| 
         @@ -132,9 +134,9 @@ module JSON 
     | 
|
| 
       132 
134 
     | 
    
         
             
                  class InvalidValueObjectValue < JsonLdError; @code = "invalid value object value"; end
         
     | 
| 
       133 
135 
     | 
    
         
             
                  class InvalidVocabMapping < JsonLdError; @code = "invalid vocab mapping"; end
         
     | 
| 
       134 
136 
     | 
    
         
             
                  class KeywordRedefinition < JsonLdError; @code = "keyword redefinition"; end
         
     | 
| 
       135 
     | 
    
         
            -
                  class ListOfLists < JsonLdError; @code = "list of lists"; end
         
     | 
| 
       136 
137 
     | 
    
         
             
                  class LoadingDocumentFailed < JsonLdError; @code = "loading document failed"; end
         
     | 
| 
       137 
138 
     | 
    
         
             
                  class LoadingRemoteContextFailed < JsonLdError; @code = "loading remote context failed"; end
         
     | 
| 
      
 139 
     | 
    
         
            +
                  class ContextOverflow < JsonLdError; @code = "maximum number of @context URLs exceeded"; end
         
     | 
| 
       138 
140 
     | 
    
         
             
                  class MultipleContextLinkHeaders < JsonLdError; @code = "multiple context link headers"; end
         
     | 
| 
       139 
141 
     | 
    
         
             
                  class ProcessingModeConflict < JsonLdError; @code = "processing mode conflict"; end
         
     | 
| 
       140 
142 
     | 
    
         
             
                  class RecursiveContextInclusion < JsonLdError; @code = "recursive context inclusion"; end
         
     | 
    
        data/lib/json/ld/api.rb
    CHANGED
    
    | 
         @@ -72,10 +72,7 @@ module JSON::LD 
     | 
|
| 
       72 
72 
     | 
    
         
             
                # @option options [Boolean, String, RDF::URI] :flatten
         
     | 
| 
       73 
73 
     | 
    
         
             
                #   If set to a value that is not `false`, the JSON-LD processor must modify the output of the Compaction Algorithm or the Expansion Algorithm by coalescing all properties associated with each subject via the Flattening Algorithm. The value of `flatten must` be either an _IRI_ value representing the name of the graph to flatten, or `true`. If the value is `true`, then the first graph encountered in the input document is selected and flattened.
         
     | 
| 
       74 
74 
     | 
    
         
             
                # @option options [String] :processingMode
         
     | 
| 
       75 
     | 
    
         
            -
                #   Processing mode, json-ld-1.0 or json-ld-1.1. 
     | 
| 
       76 
     | 
    
         
            -
                #
         
     | 
| 
       77 
     | 
    
         
            -
                #   * json-ld-1.1-expand-frame – special frame expansion mode.
         
     | 
| 
       78 
     | 
    
         
            -
                #
         
     | 
| 
      
 75 
     | 
    
         
            +
                #   Processing mode, json-ld-1.0 or json-ld-1.1.
         
     | 
| 
       79 
76 
     | 
    
         
             
                #   If `processingMode` is not specified, a mode of `json-ld-1.0` or `json-ld-1.1` is set, the context used for `expansion` or `compaction`.
         
     | 
| 
       80 
77 
     | 
    
         
             
                # @option options [Boolean] :rename_bnodes (true)
         
     | 
| 
       81 
78 
     | 
    
         
             
                #   Rename bnodes as part of expansion, or keep them the same.
         
     | 
| 
         @@ -86,16 +83,15 @@ module JSON::LD 
     | 
|
| 
       86 
83 
     | 
    
         
             
                # @yield [api]
         
     | 
| 
       87 
84 
     | 
    
         
             
                # @yieldparam [API]
         
     | 
| 
       88 
85 
     | 
    
         
             
                # @raise [JsonLdError]
         
     | 
| 
       89 
     | 
    
         
            -
                def initialize(input, context,  
     | 
| 
      
 86 
     | 
    
         
            +
                def initialize(input, context, rename_bnodes: true, unique_bnodes: false, **options, &block)
         
     | 
| 
       90 
87 
     | 
    
         
             
                  @options = {
         
     | 
| 
       91 
88 
     | 
    
         
             
                    compactArrays:      true,
         
     | 
| 
       92 
     | 
    
         
            -
                    rename_bnodes:      true,
         
     | 
| 
       93 
89 
     | 
    
         
             
                    documentLoader:     self.class.method(:documentLoader)
         
     | 
| 
       94 
90 
     | 
    
         
             
                  }.merge(options)
         
     | 
| 
       95 
     | 
    
         
            -
                  @namer =  
     | 
| 
      
 91 
     | 
    
         
            +
                  @namer = unique_bnodes ? BlankNodeUniqer.new : (rename_bnodes ? BlankNodeNamer.new("b") : BlankNodeMapper.new)
         
     | 
| 
       96 
92 
     | 
    
         | 
| 
       97 
93 
     | 
    
         
             
                  # For context via Link header
         
     | 
| 
       98 
     | 
    
         
            -
                   
     | 
| 
      
 94 
     | 
    
         
            +
                  _, context_ref = nil, nil
         
     | 
| 
       99 
95 
     | 
    
         | 
| 
       100 
96 
     | 
    
         
             
                  @value = case input
         
     | 
| 
       101 
97 
     | 
    
         
             
                  when Array, Hash then input.dup
         
     | 
| 
         @@ -115,7 +111,6 @@ module JSON::LD 
     | 
|
| 
       115 
111 
     | 
    
         
             
                  when String
         
     | 
| 
       116 
112 
     | 
    
         
             
                    remote_doc = @options[:documentLoader].call(input, @options)
         
     | 
| 
       117 
113 
     | 
    
         | 
| 
       118 
     | 
    
         
            -
                    remote_base = remote_doc.documentUrl
         
     | 
| 
       119 
114 
     | 
    
         
             
                    context_ref = remote_doc.contextUrl
         
     | 
| 
       120 
115 
     | 
    
         
             
                    @options = {base: remote_doc.documentUrl}.merge(@options) unless @options[:no_default_base]
         
     | 
| 
       121 
116 
     | 
    
         | 
| 
         @@ -166,10 +161,12 @@ module JSON::LD 
     | 
|
| 
       166 
161 
     | 
    
         
             
                # @return [Object, Array<Hash>]
         
     | 
| 
       167 
162 
     | 
    
         
             
                #   If a block is given, the result of evaluating the block is returned, otherwise, the expanded JSON-LD document
         
     | 
| 
       168 
163 
     | 
    
         
             
                # @see http://json-ld.org/spec/latest/json-ld-api/#expansion-algorithm
         
     | 
| 
       169 
     | 
    
         
            -
                def self.expand(input,  
     | 
| 
      
 164 
     | 
    
         
            +
                def self.expand(input, ordered: true, framing: false, **options, &block)
         
     | 
| 
       170 
165 
     | 
    
         
             
                  result, doc_base = nil
         
     | 
| 
       171 
166 
     | 
    
         
             
                  API.new(input, options[:expandContext], options) do
         
     | 
| 
       172 
     | 
    
         
            -
                    result = self.expand(self.value, nil, self.context, 
     | 
| 
      
 167 
     | 
    
         
            +
                    result = self.expand(self.value, nil, self.context,
         
     | 
| 
      
 168 
     | 
    
         
            +
                      ordered: ordered,
         
     | 
| 
      
 169 
     | 
    
         
            +
                      framing: framing)
         
     | 
| 
       173 
170 
     | 
    
         
             
                    doc_base = @options[:base]
         
     | 
| 
       174 
171 
     | 
    
         
             
                  end
         
     | 
| 
       175 
172 
     | 
    
         | 
| 
         @@ -213,18 +210,18 @@ module JSON::LD 
     | 
|
| 
       213 
210 
     | 
    
         
             
                #   If a block is given, the result of evaluating the block is returned, otherwise, the compacted JSON-LD document
         
     | 
| 
       214 
211 
     | 
    
         
             
                # @raise [JsonLdError]
         
     | 
| 
       215 
212 
     | 
    
         
             
                # @see http://json-ld.org/spec/latest/json-ld-api/#compaction-algorithm
         
     | 
| 
       216 
     | 
    
         
            -
                def self.compact(input, context,  
     | 
| 
      
 213 
     | 
    
         
            +
                def self.compact(input, context, expanded: false, **options)
         
     | 
| 
       217 
214 
     | 
    
         
             
                  result = nil
         
     | 
| 
       218 
215 
     | 
    
         
             
                  options = {compactToRelative:  true}.merge(options)
         
     | 
| 
       219 
216 
     | 
    
         | 
| 
       220 
217 
     | 
    
         
             
                  # 1) Perform the Expansion Algorithm on the JSON-LD input.
         
     | 
| 
       221 
218 
     | 
    
         
             
                  #    This removes any existing context to allow the given context to be cleanly applied.
         
     | 
| 
       222 
     | 
    
         
            -
                  expanded_input =  
     | 
| 
      
 219 
     | 
    
         
            +
                  expanded_input = expanded ? input : API.expand(input, options) do |res, base_iri|
         
     | 
| 
       223 
220 
     | 
    
         
             
                    options[:base] ||= base_iri if options[:compactToRelative]
         
     | 
| 
       224 
     | 
    
         
            -
                     
     | 
| 
      
 221 
     | 
    
         
            +
                    res
         
     | 
| 
       225 
222 
     | 
    
         
             
                  end
         
     | 
| 
       226 
223 
     | 
    
         | 
| 
       227 
     | 
    
         
            -
                  API.new(expanded_input, context,  
     | 
| 
      
 224 
     | 
    
         
            +
                  API.new(expanded_input, context, no_default_base: true, **options) do
         
     | 
| 
       228 
225 
     | 
    
         
             
                    log_debug(".compact") {"expanded input: #{expanded_input.to_json(JSON_STATE) rescue 'malformed json'}"}
         
     | 
| 
       229 
226 
     | 
    
         
             
                    result = compact(value)
         
     | 
| 
       230 
227 
     | 
    
         | 
| 
         @@ -258,18 +255,18 @@ module JSON::LD 
     | 
|
| 
       258 
255 
     | 
    
         
             
                # @return [Object, Hash]
         
     | 
| 
       259 
256 
     | 
    
         
             
                #   If a block is given, the result of evaluating the block is returned, otherwise, the flattened JSON-LD document
         
     | 
| 
       260 
257 
     | 
    
         
             
                # @see http://json-ld.org/spec/latest/json-ld-api/#framing-algorithm
         
     | 
| 
       261 
     | 
    
         
            -
                def self.flatten(input, context,  
     | 
| 
      
 258 
     | 
    
         
            +
                def self.flatten(input, context, expanded: false, **options)
         
     | 
| 
       262 
259 
     | 
    
         
             
                  flattened = []
         
     | 
| 
       263 
260 
     | 
    
         
             
                  options = {compactToRelative:  true}.merge(options)
         
     | 
| 
       264 
261 
     | 
    
         | 
| 
       265 
262 
     | 
    
         
             
                  # Expand input to simplify processing
         
     | 
| 
       266 
     | 
    
         
            -
                  expanded_input =  
     | 
| 
      
 263 
     | 
    
         
            +
                  expanded_input = expanded ? input : API.expand(input, options) do |result, base_iri|
         
     | 
| 
       267 
264 
     | 
    
         
             
                    options[:base] ||= base_iri if options[:compactToRelative]
         
     | 
| 
       268 
265 
     | 
    
         
             
                    result
         
     | 
| 
       269 
266 
     | 
    
         
             
                  end
         
     | 
| 
       270 
267 
     | 
    
         | 
| 
       271 
268 
     | 
    
         
             
                  # Initialize input using
         
     | 
| 
       272 
     | 
    
         
            -
                  API.new(expanded_input, context,  
     | 
| 
      
 269 
     | 
    
         
            +
                  API.new(expanded_input, context, no_default_base: true, **options) do
         
     | 
| 
       273 
270 
     | 
    
         
             
                    log_debug(".flatten") {"expanded input: #{value.to_json(JSON_STATE) rescue 'malformed json'}"}
         
     | 
| 
       274 
271 
     | 
    
         | 
| 
       275 
272 
     | 
    
         
             
                    # Initialize node map to a JSON object consisting of a single member whose key is @default and whose value is an empty JSON object.
         
     | 
| 
         @@ -277,24 +274,23 @@ module JSON::LD 
     | 
|
| 
       277 
274 
     | 
    
         
             
                    create_node_map(value, graph_maps)
         
     | 
| 
       278 
275 
     | 
    
         | 
| 
       279 
276 
     | 
    
         
             
                    default_graph = graph_maps['@default']
         
     | 
| 
       280 
     | 
    
         
            -
                    graph_maps.keys. 
     | 
| 
      
 277 
     | 
    
         
            +
                    graph_maps.keys.sort.each do |graph_name|
         
     | 
| 
       281 
278 
     | 
    
         
             
                      next if graph_name == '@default'
         
     | 
| 
       282 
279 
     | 
    
         | 
| 
       283 
280 
     | 
    
         
             
                      graph = graph_maps[graph_name]
         
     | 
| 
       284 
281 
     | 
    
         
             
                      entry = default_graph[graph_name] ||= {'@id' => graph_name}
         
     | 
| 
       285 
282 
     | 
    
         
             
                      nodes = entry['@graph'] ||= []
         
     | 
| 
       286 
     | 
    
         
            -
                      graph.keys. 
     | 
| 
      
 283 
     | 
    
         
            +
                      graph.keys.sort.each do |id|
         
     | 
| 
       287 
284 
     | 
    
         
             
                        nodes << graph[id] unless node_reference?(graph[id])
         
     | 
| 
       288 
285 
     | 
    
         
             
                      end
         
     | 
| 
       289 
286 
     | 
    
         
             
                    end
         
     | 
| 
       290 
     | 
    
         
            -
                    default_graph.keys. 
     | 
| 
      
 287 
     | 
    
         
            +
                    default_graph.keys.sort.each do |id|
         
     | 
| 
       291 
288 
     | 
    
         
             
                      flattened << default_graph[id] unless node_reference?(default_graph[id])
         
     | 
| 
       292 
289 
     | 
    
         
             
                    end
         
     | 
| 
       293 
290 
     | 
    
         | 
| 
       294 
291 
     | 
    
         
             
                    if context && !flattened.empty?
         
     | 
| 
       295 
292 
     | 
    
         
             
                      # Otherwise, return the result of compacting flattened according the Compaction algorithm passing context ensuring that the compaction result uses the @graph keyword (or its alias) at the top-level, even if the context is empty or if there is only one element to put in the @graph array. This ensures that the returned document has a deterministic structure.
         
     | 
| 
       296 
     | 
    
         
            -
                      compacted = compact(flattened)
         
     | 
| 
       297 
     | 
    
         
            -
                      compacted = [compacted] unless compacted.is_a?(Array)
         
     | 
| 
      
 293 
     | 
    
         
            +
                      compacted = as_array(compact(flattened))
         
     | 
| 
       298 
294 
     | 
    
         
             
                      kwgraph = self.context.compact_iri('@graph', quiet: true)
         
     | 
| 
       299 
295 
     | 
    
         
             
                      flattened = self.context.serialize.merge(kwgraph => compacted)
         
     | 
| 
       300 
296 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -322,7 +318,7 @@ module JSON::LD 
     | 
|
| 
       322 
318 
     | 
    
         
             
                # @option options [Boolean] :omitDefault (false)
         
     | 
| 
       323 
319 
     | 
    
         
             
                #   a flag specifying that properties that are missing from the JSON-LD input should be omitted from the output.
         
     | 
| 
       324 
320 
     | 
    
         
             
                # @option options [Boolean] :expanded Input is already expanded
         
     | 
| 
       325 
     | 
    
         
            -
                # @option options [Boolean] : 
     | 
| 
      
 321 
     | 
    
         
            +
                # @option options [Boolean] :omitGraph does not use `@graph` at top level unless necessary to describe multiple objects, defaults to `true` if processingMode is 1.1, otherwise `false`.
         
     | 
| 
       326 
322 
     | 
    
         
             
                # @yield jsonld
         
     | 
| 
       327 
323 
     | 
    
         
             
                # @yieldparam [Hash] jsonld
         
     | 
| 
       328 
324 
     | 
    
         
             
                #   The framed JSON-LD document
         
     | 
| 
         @@ -331,7 +327,7 @@ module JSON::LD 
     | 
|
| 
       331 
327 
     | 
    
         
             
                #   If a block is given, the result of evaluating the block is returned, otherwise, the framed JSON-LD document
         
     | 
| 
       332 
328 
     | 
    
         
             
                # @raise [InvalidFrame]
         
     | 
| 
       333 
329 
     | 
    
         
             
                # @see http://json-ld.org/spec/latest/json-ld-api/#framing-algorithm
         
     | 
| 
       334 
     | 
    
         
            -
                def self.frame(input, frame,  
     | 
| 
      
 330 
     | 
    
         
            +
                def self.frame(input, frame, expanded: false, **options)
         
     | 
| 
       335 
331 
     | 
    
         
             
                  result = nil
         
     | 
| 
       336 
332 
     | 
    
         
             
                  options = {
         
     | 
| 
       337 
333 
     | 
    
         
             
                    base:                       (input if input.is_a?(String)),
         
     | 
| 
         @@ -341,7 +337,7 @@ module JSON::LD 
     | 
|
| 
       341 
337 
     | 
    
         
             
                    explicit:                   false,
         
     | 
| 
       342 
338 
     | 
    
         
             
                    requireAll:                 true,
         
     | 
| 
       343 
339 
     | 
    
         
             
                    omitDefault:                false,
         
     | 
| 
       344 
     | 
    
         
            -
                     
     | 
| 
      
 340 
     | 
    
         
            +
                    omitGraph:                  false,
         
     | 
| 
       345 
341 
     | 
    
         
             
                    documentLoader:             method(:documentLoader)
         
     | 
| 
       346 
342 
     | 
    
         
             
                  }.merge(options)
         
     | 
| 
       347 
343 
     | 
    
         | 
| 
         @@ -365,20 +361,21 @@ module JSON::LD 
     | 
|
| 
       365 
361 
     | 
    
         
             
                  end
         
     | 
| 
       366 
362 
     | 
    
         | 
| 
       367 
363 
     | 
    
         
             
                  # Expand input to simplify processing
         
     | 
| 
       368 
     | 
    
         
            -
                  expanded_input =  
     | 
| 
      
 364 
     | 
    
         
            +
                  expanded_input = expanded ? input : API.expand(input, options) do |res, base_iri|
         
     | 
| 
       369 
365 
     | 
    
         
             
                    options[:base] ||= base_iri if options[:compactToRelative]
         
     | 
| 
       370 
     | 
    
         
            -
                     
     | 
| 
      
 366 
     | 
    
         
            +
                    res
         
     | 
| 
       371 
367 
     | 
    
         
             
                  end
         
     | 
| 
       372 
368 
     | 
    
         | 
| 
       373 
369 
     | 
    
         
             
                  # Expand frame to simplify processing
         
     | 
| 
       374 
     | 
    
         
            -
                  expanded_frame = API.expand(frame,  
     | 
| 
      
 370 
     | 
    
         
            +
                  expanded_frame = API.expand(frame, framing: true, **options)
         
     | 
| 
       375 
371 
     | 
    
         | 
| 
       376 
372 
     | 
    
         
             
                  # Initialize input using frame as context
         
     | 
| 
       377 
     | 
    
         
            -
                  API.new(expanded_input,  
     | 
| 
      
 373 
     | 
    
         
            +
                  API.new(expanded_input, frame['@context'], no_default_base: true, **options) do
         
     | 
| 
      
 374 
     | 
    
         
            +
                    log_debug(".frame") {"expanded input: #{expanded_input.to_json(JSON_STATE) rescue 'malformed json'}"}
         
     | 
| 
       378 
375 
     | 
    
         
             
                    log_debug(".frame") {"expanded frame: #{expanded_frame.to_json(JSON_STATE) rescue 'malformed json'}"}
         
     | 
| 
       379 
376 
     | 
    
         | 
| 
       380 
377 
     | 
    
         
             
                    # Get framing nodes from expanded input, replacing Blank Node identifiers as necessary
         
     | 
| 
       381 
     | 
    
         
            -
                    create_node_map(value, framing_state[:graphMap],  
     | 
| 
      
 378 
     | 
    
         
            +
                    create_node_map(value, framing_state[:graphMap], active_graph: '@default')
         
     | 
| 
       382 
379 
     | 
    
         | 
| 
       383 
380 
     | 
    
         
             
                    frame_keys = frame.keys.map {|k| context.expand_iri(k, vocab: true, quiet: true)}
         
     | 
| 
       384 
381 
     | 
    
         
             
                    if frame_keys.include?('@graph')
         
     | 
| 
         @@ -394,24 +391,29 @@ module JSON::LD 
     | 
|
| 
       394 
391 
     | 
    
         
             
                    framing_state[:subjects] = framing_state[:graphMap][framing_state[:graph]]
         
     | 
| 
       395 
392 
     | 
    
         | 
| 
       396 
393 
     | 
    
         
             
                    result = []
         
     | 
| 
       397 
     | 
    
         
            -
                    frame(framing_state, framing_state[:subjects].keys.sort, (expanded_frame.first || {}),  
     | 
| 
      
 394 
     | 
    
         
            +
                    frame(framing_state, framing_state[:subjects].keys.sort, (expanded_frame.first || {}), parent: result, **options)
         
     | 
| 
       398 
395 
     | 
    
         | 
| 
       399 
396 
     | 
    
         
             
                    # Count blank node identifiers used in the document, if pruning
         
     | 
| 
       400 
     | 
    
         
            -
                     
     | 
| 
       401 
     | 
    
         
            -
                      count_blank_node_identifiers(result).collect {|k, v| k if v == 1}.compact
         
     | 
| 
      
 397 
     | 
    
         
            +
                    unless @options[:processingMode] == 'json-ld-1.0'
         
     | 
| 
      
 398 
     | 
    
         
            +
                      bnodes_to_clear = count_blank_node_identifiers(result).collect {|k, v| k if v == 1}.compact
         
     | 
| 
      
 399 
     | 
    
         
            +
                      result = prune_bnodes(result, bnodes_to_clear)
         
     | 
| 
       402 
400 
     | 
    
         
             
                    end
         
     | 
| 
       403 
401 
     | 
    
         | 
| 
       404 
402 
     | 
    
         
             
                    # Initalize context from frame
         
     | 
| 
       405 
403 
     | 
    
         
             
                    @context = @context.parse(frame['@context'])
         
     | 
| 
       406 
404 
     | 
    
         
             
                    # Compact result
         
     | 
| 
       407 
405 
     | 
    
         
             
                    compacted = compact(result)
         
     | 
| 
       408 
     | 
    
         
            -
                    compacted = [compacted] unless compacted.is_a?(Array)
         
     | 
| 
      
 406 
     | 
    
         
            +
                    compacted = [compacted] unless options[:omitGraph] || compacted.is_a?(Array)
         
     | 
| 
       409 
407 
     | 
    
         | 
| 
       410 
408 
     | 
    
         
             
                    # Add the given context to the output
         
     | 
| 
       411 
     | 
    
         
            -
                     
     | 
| 
       412 
     | 
    
         
            -
             
     | 
| 
      
 409 
     | 
    
         
            +
                    result = if !compacted.is_a?(Array)
         
     | 
| 
      
 410 
     | 
    
         
            +
                      context.serialize.merge(compacted)
         
     | 
| 
      
 411 
     | 
    
         
            +
                    else
         
     | 
| 
      
 412 
     | 
    
         
            +
                      kwgraph = context.compact_iri('@graph', quiet: true)
         
     | 
| 
      
 413 
     | 
    
         
            +
                      context.serialize.merge({kwgraph => compacted})
         
     | 
| 
      
 414 
     | 
    
         
            +
                    end
         
     | 
| 
       413 
415 
     | 
    
         
             
                    log_debug(".frame") {"after compact: #{result.to_json(JSON_STATE) rescue 'malformed json'}"}
         
     | 
| 
       414 
     | 
    
         
            -
                    result = cleanup_preserve(result 
     | 
| 
      
 416 
     | 
    
         
            +
                    result = cleanup_preserve(result)
         
     | 
| 
       415 
417 
     | 
    
         
             
                  end
         
     | 
| 
       416 
418 
     | 
    
         | 
| 
       417 
419 
     | 
    
         
             
                  block_given? ? yield(result) : result
         
     | 
| 
         @@ -430,7 +432,7 @@ module JSON::LD 
     | 
|
| 
       430 
432 
     | 
    
         
             
                # @yield statement
         
     | 
| 
       431 
433 
     | 
    
         
             
                # @yieldparam [RDF::Statement] statement
         
     | 
| 
       432 
434 
     | 
    
         
             
                # @return [RDF::Enumerable] set of statements, unless a block is given.
         
     | 
| 
       433 
     | 
    
         
            -
                def self.toRdf(input,  
     | 
| 
      
 435 
     | 
    
         
            +
                def self.toRdf(input, expanded: false, **options, &block)
         
     | 
| 
       434 
436 
     | 
    
         
             
                  unless block_given?
         
     | 
| 
       435 
437 
     | 
    
         
             
                    results = []
         
     | 
| 
       436 
438 
     | 
    
         
             
                    results.extend(RDF::Enumerable)
         
     | 
| 
         @@ -441,7 +443,7 @@ module JSON::LD 
     | 
|
| 
       441 
443 
     | 
    
         
             
                  end
         
     | 
| 
       442 
444 
     | 
    
         | 
| 
       443 
445 
     | 
    
         
             
                  # Expand input to simplify processing
         
     | 
| 
       444 
     | 
    
         
            -
                  expanded_input =  
     | 
| 
      
 446 
     | 
    
         
            +
                  expanded_input = expanded ? input : API.expand(input, ordered: false, **options)
         
     | 
| 
       445 
447 
     | 
    
         | 
| 
       446 
448 
     | 
    
         
             
                  API.new(expanded_input, nil, options) do
         
     | 
| 
       447 
449 
     | 
    
         
             
                    # 1) Perform the Expansion Algorithm on the JSON-LD input.
         
     | 
| 
         @@ -453,19 +455,9 @@ module JSON::LD 
     | 
|
| 
       453 
455 
     | 
    
         
             
                      item_to_rdf(node) do |statement|
         
     | 
| 
       454 
456 
     | 
    
         
             
                        next if statement.predicate.node? && !options[:produceGeneralizedRdf]
         
     | 
| 
       455 
457 
     | 
    
         | 
| 
       456 
     | 
    
         
            -
                        # Drop  
     | 
| 
       457 
     | 
    
         
            -
                         
     | 
| 
       458 
     | 
    
         
            -
                           
     | 
| 
       459 
     | 
    
         
            -
                          when RDF::URI
         
     | 
| 
       460 
     | 
    
         
            -
                            r.relative?
         
     | 
| 
       461 
     | 
    
         
            -
                          when RDF::Literal
         
     | 
| 
       462 
     | 
    
         
            -
                            r.has_datatype? && r.datatype.relative?
         
     | 
| 
       463 
     | 
    
         
            -
                          else
         
     | 
| 
       464 
     | 
    
         
            -
                            false
         
     | 
| 
       465 
     | 
    
         
            -
                          end
         
     | 
| 
       466 
     | 
    
         
            -
                        end
         
     | 
| 
       467 
     | 
    
         
            -
                        if relative
         
     | 
| 
       468 
     | 
    
         
            -
                          log_debug(".toRdf") {"drop statement with relative IRIs: #{statement.to_ntriples}"}
         
     | 
| 
      
 458 
     | 
    
         
            +
                        # Drop invalid statements (other than IRIs)
         
     | 
| 
      
 459 
     | 
    
         
            +
                        unless statement.valid_extended?
         
     | 
| 
      
 460 
     | 
    
         
            +
                          log_debug(".toRdf") {"drop invalid statement: #{statement.to_nquads}"}
         
     | 
| 
       469 
461 
     | 
    
         
             
                          next
         
     | 
| 
       470 
462 
     | 
    
         
             
                        end
         
     | 
| 
       471 
463 
     | 
    
         | 
| 
         @@ -480,7 +472,7 @@ module JSON::LD 
     | 
|
| 
       480 
472 
     | 
    
         
             
                #
         
     | 
| 
       481 
473 
     | 
    
         
             
                # The resulting `Array` is either returned or yielded, if a block is given.
         
     | 
| 
       482 
474 
     | 
    
         
             
                #
         
     | 
| 
       483 
     | 
    
         
            -
                # @param [ 
     | 
| 
      
 475 
     | 
    
         
            +
                # @param [RDF::Enumerable] input
         
     | 
| 
       484 
476 
     | 
    
         
             
                # @param  [Hash{Symbol => Object}] options
         
     | 
| 
       485 
477 
     | 
    
         
             
                # @option options (see #initialize)
         
     | 
| 
       486 
478 
     | 
    
         
             
                # @option options [Boolean] :useRdfType (false)
         
     | 
| 
         @@ -492,9 +484,7 @@ module JSON::LD 
     | 
|
| 
       492 
484 
     | 
    
         
             
                # @yieldreturn [Object] returned object
         
     | 
| 
       493 
485 
     | 
    
         
             
                # @return [Object, Hash]
         
     | 
| 
       494 
486 
     | 
    
         
             
                #   If a block is given, the result of evaluating the block is returned, otherwise, the expanded JSON-LD document
         
     | 
| 
       495 
     | 
    
         
            -
                def self.fromRdf(input,  
     | 
| 
       496 
     | 
    
         
            -
                  useRdfType = options.fetch(:useRdfType, false)
         
     | 
| 
       497 
     | 
    
         
            -
                  useNativeTypes = options.fetch(:useNativeTypes, false)
         
     | 
| 
      
 487 
     | 
    
         
            +
                def self.fromRdf(input, useRdfType: false, useNativeTypes: false, **options, &block)
         
     | 
| 
       498 
488 
     | 
    
         
             
                  result = nil
         
     | 
| 
       499 
489 
     | 
    
         | 
| 
       500 
490 
     | 
    
         
             
                  API.new(nil, nil, options) do |api|
         
     | 
| 
         @@ -516,12 +506,12 @@ module JSON::LD 
     | 
|
| 
       516 
506 
     | 
    
         
             
                # @return [Object, RemoteDocument]
         
     | 
| 
       517 
507 
     | 
    
         
             
                #   If a block is given, the result of evaluating the block is returned, otherwise, the retrieved remote document and context information unless block given
         
     | 
| 
       518 
508 
     | 
    
         
             
                # @raise [JsonLdError]
         
     | 
| 
       519 
     | 
    
         
            -
                def self.documentLoader(url,  
     | 
| 
      
 509 
     | 
    
         
            +
                def self.documentLoader(url, validate: false, **options)
         
     | 
| 
       520 
510 
     | 
    
         
             
                  options = OPEN_OPTS.merge(options)
         
     | 
| 
       521 
511 
     | 
    
         
             
                  RDF::Util::File.open_file(url, options) do |remote_doc|
         
     | 
| 
       522 
512 
     | 
    
         
             
                    content_type = remote_doc.content_type if remote_doc.respond_to?(:content_type)
         
     | 
| 
       523 
513 
     | 
    
         
             
                    # If the passed input is a DOMString representing the IRI of a remote document, dereference it. If the retrieved document's content type is neither application/json, nor application/ld+json, nor any other media type using a +json suffix as defined in [RFC6839], reject the promise passing an loading document failed error.
         
     | 
| 
       524 
     | 
    
         
            -
                    if content_type &&  
     | 
| 
      
 514 
     | 
    
         
            +
                    if content_type && validate
         
     | 
| 
       525 
515 
     | 
    
         
             
                      main, sub = content_type.split("/")
         
     | 
| 
       526 
516 
     | 
    
         
             
                      raise JSON::LD::JsonLdError::LoadingDocumentFailed, "url: #{url}, content_type: #{content_type}" if
         
     | 
| 
       527 
517 
     | 
    
         
             
                        main != 'application' ||
         
     |