json-ld 3.2.4 → 3.3.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.
Files changed (100) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +4 -4
  3. data/VERSION +1 -1
  4. data/lib/json/ld/api.rb +807 -771
  5. data/lib/json/ld/compact.rb +304 -304
  6. data/lib/json/ld/conneg.rb +179 -161
  7. data/lib/json/ld/context.rb +2079 -1913
  8. data/lib/json/ld/expand.rb +745 -666
  9. data/lib/json/ld/extensions.rb +14 -13
  10. data/lib/json/ld/flatten.rb +257 -247
  11. data/lib/json/ld/format.rb +202 -194
  12. data/lib/json/ld/frame.rb +525 -502
  13. data/lib/json/ld/from_rdf.rb +223 -204
  14. data/lib/json/ld/html/nokogiri.rb +123 -121
  15. data/lib/json/ld/html/rexml.rb +151 -147
  16. data/lib/json/ld/reader.rb +107 -100
  17. data/lib/json/ld/resource.rb +224 -205
  18. data/lib/json/ld/streaming_reader.rb +574 -507
  19. data/lib/json/ld/streaming_writer.rb +93 -92
  20. data/lib/json/ld/to_rdf.rb +171 -169
  21. data/lib/json/ld/utils.rb +270 -264
  22. data/lib/json/ld/version.rb +24 -14
  23. data/lib/json/ld/writer.rb +334 -311
  24. data/lib/json/ld.rb +103 -96
  25. metadata +56 -225
  26. data/spec/api_spec.rb +0 -132
  27. data/spec/compact_spec.rb +0 -3482
  28. data/spec/conneg_spec.rb +0 -373
  29. data/spec/context_spec.rb +0 -2056
  30. data/spec/expand_spec.rb +0 -4496
  31. data/spec/flatten_spec.rb +0 -1203
  32. data/spec/format_spec.rb +0 -115
  33. data/spec/frame_spec.rb +0 -2541
  34. data/spec/from_rdf_spec.rb +0 -1072
  35. data/spec/matchers.rb +0 -20
  36. data/spec/rdfstar_spec.rb +0 -25
  37. data/spec/reader_spec.rb +0 -883
  38. data/spec/resource_spec.rb +0 -76
  39. data/spec/spec_helper.rb +0 -281
  40. data/spec/streaming_reader_spec.rb +0 -237
  41. data/spec/streaming_writer_spec.rb +0 -145
  42. data/spec/suite_compact_spec.rb +0 -22
  43. data/spec/suite_expand_spec.rb +0 -36
  44. data/spec/suite_flatten_spec.rb +0 -34
  45. data/spec/suite_frame_spec.rb +0 -29
  46. data/spec/suite_from_rdf_spec.rb +0 -22
  47. data/spec/suite_helper.rb +0 -411
  48. data/spec/suite_html_spec.rb +0 -22
  49. data/spec/suite_http_spec.rb +0 -35
  50. data/spec/suite_remote_doc_spec.rb +0 -22
  51. data/spec/suite_to_rdf_spec.rb +0 -30
  52. data/spec/support/extensions.rb +0 -44
  53. data/spec/test-files/test-1-compacted.jsonld +0 -10
  54. data/spec/test-files/test-1-context.jsonld +0 -7
  55. data/spec/test-files/test-1-expanded.jsonld +0 -5
  56. data/spec/test-files/test-1-input.jsonld +0 -10
  57. data/spec/test-files/test-1-rdf.ttl +0 -8
  58. data/spec/test-files/test-2-compacted.jsonld +0 -20
  59. data/spec/test-files/test-2-context.jsonld +0 -7
  60. data/spec/test-files/test-2-expanded.jsonld +0 -16
  61. data/spec/test-files/test-2-input.jsonld +0 -20
  62. data/spec/test-files/test-2-rdf.ttl +0 -14
  63. data/spec/test-files/test-3-compacted.jsonld +0 -11
  64. data/spec/test-files/test-3-context.jsonld +0 -8
  65. data/spec/test-files/test-3-expanded.jsonld +0 -10
  66. data/spec/test-files/test-3-input.jsonld +0 -11
  67. data/spec/test-files/test-3-rdf.ttl +0 -8
  68. data/spec/test-files/test-4-compacted.jsonld +0 -10
  69. data/spec/test-files/test-4-context.jsonld +0 -7
  70. data/spec/test-files/test-4-expanded.jsonld +0 -6
  71. data/spec/test-files/test-4-input.jsonld +0 -10
  72. data/spec/test-files/test-4-rdf.ttl +0 -5
  73. data/spec/test-files/test-5-compacted.jsonld +0 -13
  74. data/spec/test-files/test-5-context.jsonld +0 -7
  75. data/spec/test-files/test-5-expanded.jsonld +0 -9
  76. data/spec/test-files/test-5-input.jsonld +0 -13
  77. data/spec/test-files/test-5-rdf.ttl +0 -7
  78. data/spec/test-files/test-6-compacted.jsonld +0 -10
  79. data/spec/test-files/test-6-context.jsonld +0 -7
  80. data/spec/test-files/test-6-expanded.jsonld +0 -10
  81. data/spec/test-files/test-6-input.jsonld +0 -10
  82. data/spec/test-files/test-6-rdf.ttl +0 -6
  83. data/spec/test-files/test-7-compacted.jsonld +0 -23
  84. data/spec/test-files/test-7-context.jsonld +0 -4
  85. data/spec/test-files/test-7-expanded.jsonld +0 -20
  86. data/spec/test-files/test-7-input.jsonld +0 -23
  87. data/spec/test-files/test-7-rdf.ttl +0 -14
  88. data/spec/test-files/test-8-compacted.jsonld +0 -34
  89. data/spec/test-files/test-8-context.jsonld +0 -11
  90. data/spec/test-files/test-8-expanded.jsonld +0 -24
  91. data/spec/test-files/test-8-frame.jsonld +0 -18
  92. data/spec/test-files/test-8-framed.jsonld +0 -25
  93. data/spec/test-files/test-8-input.jsonld +0 -30
  94. data/spec/test-files/test-8-rdf.ttl +0 -15
  95. data/spec/test-files/test-9-compacted.jsonld +0 -20
  96. data/spec/test-files/test-9-context.jsonld +0 -13
  97. data/spec/test-files/test-9-expanded.jsonld +0 -14
  98. data/spec/test-files/test-9-input.jsonld +0 -12
  99. data/spec/to_rdf_spec.rb +0 -1684
  100. data/spec/writer_spec.rb +0 -427
@@ -1,215 +1,223 @@
1
- # -*- encoding: utf-8 -*-
2
1
  # frozen_string_literal: true
3
- module JSON::LD
4
- ##
5
- # JSON-LD format specification.
6
- #
7
- # @example Obtaining an JSON-LD format class
8
- # RDF::Format.for(:jsonld) #=> JSON::LD::Format
9
- # RDF::Format.for("etc/foaf.jsonld")
10
- # RDF::Format.for(:file_name => "etc/foaf.jsonld")
11
- # RDF::Format.for(file_extension: "jsonld")
12
- # RDF::Format.for(:content_type => "application/ld+json")
13
- #
14
- # @example Obtaining serialization format MIME types
15
- # RDF::Format.content_types #=> {"application/ld+json" => [JSON::LD::Format],
16
- # "application/x-ld+json" => [JSON::LD::Format]}
17
- #
18
- # @example Obtaining serialization format file extension mappings
19
- # RDF::Format.file_extensions #=> {:jsonld => [JSON::LD::Format] }
20
- #
21
- # @see https://www.w3.org/TR/json-ld11/
22
- # @see https://w3c.github.io/json-ld-api/tests/
23
- class Format < RDF::Format
24
- content_type 'application/ld+json',
25
- extension: :jsonld,
26
- alias: 'application/x-ld+json',
27
- uri: 'http://www.w3.org/ns/formats/JSON-LD'
28
- content_encoding 'utf-8'
29
-
30
- reader { JSON::LD::Reader }
31
- writer { JSON::LD::Writer }
32
2
 
3
+ module JSON
4
+ module LD
33
5
  ##
34
- # Sample detection to see if it matches JSON-LD
6
+ # JSON-LD format specification.
35
7
  #
36
- # Use a text sample to detect the format of an input file. Sub-classes implement
37
- # a matcher sufficient to detect probably format matches, including disambiguating
38
- # between other similar formats.
8
+ # @example Obtaining an JSON-LD format class
9
+ # RDF::Format.for(:jsonld) #=> JSON::LD::Format
10
+ # RDF::Format.for("etc/foaf.jsonld")
11
+ # RDF::Format.for(:file_name => "etc/foaf.jsonld")
12
+ # RDF::Format.for(file_extension: "jsonld")
13
+ # RDF::Format.for(:content_type => "application/ld+json")
39
14
  #
40
- # @param [String] sample Beginning several bytes (~ 1K) of input.
41
- # @return [Boolean]
42
- def self.detect(sample)
43
- !!sample.match(/\{\s*"@(id|context|type)"/m) &&
44
- # Exclude CSVW metadata
45
- !sample.include?("http://www.w3.org/ns/csvw")
46
- end
15
+ # @example Obtaining serialization format MIME types
16
+ # RDF::Format.content_types #=> {"application/ld+json" => [JSON::LD::Format],
17
+ # "application/x-ld+json" => [JSON::LD::Format]}
18
+ #
19
+ # @example Obtaining serialization format file extension mappings
20
+ # RDF::Format.file_extensions #=> {:jsonld => [JSON::LD::Format] }
21
+ #
22
+ # @see https://www.w3.org/TR/json-ld11/
23
+ # @see https://w3c.github.io/json-ld-api/tests/
24
+ class Format < RDF::Format
25
+ content_type 'application/ld+json',
26
+ extension: :jsonld,
27
+ alias: 'application/x-ld+json',
28
+ uri: 'http://www.w3.org/ns/formats/JSON-LD'
29
+ content_encoding 'utf-8'
30
+
31
+ reader { JSON::LD::Reader }
32
+ writer { JSON::LD::Writer }
33
+
34
+ ##
35
+ # Sample detection to see if it matches JSON-LD
36
+ #
37
+ # Use a text sample to detect the format of an input file. Sub-classes implement
38
+ # a matcher sufficient to detect probably format matches, including disambiguating
39
+ # between other similar formats.
40
+ #
41
+ # @param [String] sample Beginning several bytes (~ 1K) of input.
42
+ # @return [Boolean]
43
+ def self.detect(sample)
44
+ !!sample.match(/\{\s*"@(id|context|type)"/m) &&
45
+ # Exclude CSVW metadata
46
+ !sample.include?("http://www.w3.org/ns/csvw")
47
+ end
47
48
 
48
- # Specify how to execute CLI commands for each supported format.
49
- # Derived formats (e.g., YAML-LD) define their own entrypoints.
50
- LD_FORMATS = {
51
- jsonld: {
52
- expand: ->(input, **options) {
53
- JSON::LD::API.expand(input,
54
- serializer: JSON::LD::API.method(:serializer),
55
- **options)
56
- },
57
- compact: ->(input, **options) {
58
- JSON::LD::API.compact(input,
59
- options[:context],
60
- serializer: JSON::LD::API.method(:serializer),
61
- **options)
62
- },
63
- flatten: ->(input, **options) {
64
- JSON::LD::API.flatten(input,
65
- options[:context],
66
- serializer: JSON::LD::API.method(:serializer),
67
- **options)
68
- },
69
- frame: ->(input, **options) {
70
- JSON::LD::API.frame(input,
71
- options[:frame],
72
- serializer: JSON::LD::API.method(:serializer),
73
- **options)
74
- },
49
+ # Specify how to execute CLI commands for each supported format.
50
+ # Derived formats (e.g., YAML-LD) define their own entrypoints.
51
+ LD_FORMATS = {
52
+ jsonld: {
53
+ expand: lambda { |input, **options|
54
+ JSON::LD::API.expand(input,
55
+ serializer: JSON::LD::API.method(:serializer),
56
+ **options)
57
+ },
58
+ compact: lambda { |input, **options|
59
+ JSON::LD::API.compact(input,
60
+ options[:context],
61
+ serializer: JSON::LD::API.method(:serializer),
62
+ **options)
63
+ },
64
+ flatten: lambda { |input, **options|
65
+ JSON::LD::API.flatten(input,
66
+ options[:context],
67
+ serializer: JSON::LD::API.method(:serializer),
68
+ **options)
69
+ },
70
+ frame: lambda { |input, **options|
71
+ JSON::LD::API.frame(input,
72
+ options[:frame],
73
+ serializer: JSON::LD::API.method(:serializer),
74
+ **options)
75
+ }
76
+ }
75
77
  }
76
- }
77
78
 
78
- # Execute the body of a CLI command, generic for each different API method based on definitions on {LD_FORMATS}.
79
- #
80
- # Expands the input, or transforms from an RDF format based on the `:format` option, and then executes the appropriate command based on `:output_format` and does appropriate output serialization.
81
- # @private
82
- def self.cli_exec(command, files, output: $stdin, **options)
83
- output.set_encoding(Encoding::UTF_8) if output.respond_to?(:set_encoding) && RUBY_PLATFORM == "java"
84
- options[:base] ||= options[:base_uri]
79
+ # Execute the body of a CLI command, generic for each different API method based on definitions on {LD_FORMATS}.
80
+ #
81
+ # Expands the input, or transforms from an RDF format based on the `:format` option, and then executes the appropriate command based on `:output_format` and does appropriate output serialization.
82
+ # @private
83
+ def self.cli_exec(command, files, output: $stdin, **options)
84
+ output.set_encoding(Encoding::UTF_8) if output.respond_to?(:set_encoding) && RUBY_PLATFORM == "java"
85
+ options[:base] ||= options[:base_uri]
85
86
 
86
- # Parse using input format, serialize using output format
87
- in_fmt = LD_FORMATS[options.fetch(:format, :jsonld)]
88
- out_fmt = LD_FORMATS[options.fetch(:output_format, :jsonld)]
87
+ # Parse using input format, serialize using output format
88
+ in_fmt = LD_FORMATS[options.fetch(:format, :jsonld)]
89
+ out_fmt = LD_FORMATS[options.fetch(:output_format, :jsonld)]
89
90
 
90
- if in_fmt
91
- # Input is a JSON-LD based source (or derived)
92
- if files.empty?
93
- # If files are empty, either use options[:evaluate] or STDIN
94
- input = options[:evaluate] ? StringIO.new(options[:evaluate]) : STDIN
95
- input.set_encoding(options.fetch(:encoding, Encoding::UTF_8))
96
- expanded = in_fmt[:expand].call(input, serializer: nil, **options)
97
- output.puts out_fmt[command].call(expanded, expanded: true, **options)
98
- else
99
- files.each do |file|
100
- expanded = in_fmt[:expand].call(file, serializer: nil, **options)
91
+ if in_fmt
92
+ # Input is a JSON-LD based source (or derived)
93
+ if files.empty?
94
+ # If files are empty, either use options[:evaluate] or STDIN
95
+ input = options[:evaluate] ? StringIO.new(options[:evaluate]) : $stdin
96
+ input.set_encoding(options.fetch(:encoding, Encoding::UTF_8))
97
+ expanded = in_fmt[:expand].call(input, serializer: nil, **options)
101
98
  output.puts out_fmt[command].call(expanded, expanded: true, **options)
99
+ else
100
+ files.each do |file|
101
+ expanded = in_fmt[:expand].call(file, serializer: nil, **options)
102
+ output.puts out_fmt[command].call(expanded, expanded: true, **options)
103
+ end
102
104
  end
103
- end
104
- else
105
- # Turn RDF into JSON-LD first
106
- RDF::CLI.parse(files, **options) do |reader|
107
- JSON::LD::API.fromRdf(reader, serializer: nil, **options) do |expanded|
108
- output.puts out_fmt[command].call(expanded, expanded: true, **options)
105
+ else
106
+ # Turn RDF into JSON-LD first
107
+ RDF::CLI.parse(files, **options) do |reader|
108
+ JSON::LD::API.fromRdf(reader, serializer: nil, **options) do |expanded|
109
+ output.puts out_fmt[command].call(expanded, expanded: true, **options)
110
+ end
109
111
  end
110
112
  end
111
113
  end
112
- end
113
114
 
114
- ##
115
- # Hash of CLI commands appropriate for this format:
116
- #
117
- # * `expand` => {JSON::LD::API.expand}
118
- # * `compact` => {JSON::LD::API.compact}
119
- # * `flatten` => {JSON::LD::API.flatten}
120
- # * `frame` => {JSON::LD::API.frame}
121
- #
122
- # @return [Hash{Symbol => Hash}]
123
- def self.cli_commands
124
- {
125
- expand: {
126
- description: "Expand JSON-LD or parsed RDF",
127
- parse: false,
128
- help: "expand [--context <context-file>] files ...",
129
- filter: {output_format: LD_FORMATS.keys}, # Only shows output format set
130
- lambda: ->(files, **options) do
131
- options = options.merge(expandContext: options.delete(:context)) if options.key?(:context)
132
- cli_exec(:expand, files, **options)
133
- end,
134
- option_use: {context: :removed}
135
- },
136
- compact: {
137
- description: "Compact JSON-LD or parsed RDF",
138
- parse: false,
139
- filter: {output_format: LD_FORMATS.keys}, # Only shows output format set
140
- help: "compact --context <context-file> files ...",
141
- lambda: ->(files, **options) do
142
- raise ArgumentError, "Compacting requires a context" unless options[:context]
143
- cli_exec(:compact, files, **options)
144
- end,
145
- options: [
146
- RDF::CLI::Option.new(
147
- symbol: :context,
148
- datatype: RDF::URI,
149
- control: :url2,
150
- use: :required,
151
- on: ["--context CONTEXT"],
152
- description: "Context to use when compacting.") {|arg| RDF::URI(arg).absolute? ? RDF::URI(arg) : StringIO.new(File.read(arg))},
153
- ]
154
- },
155
- flatten: {
156
- description: "Flatten JSON-LD or parsed RDF",
157
- parse: false,
158
- help: "flatten [--context <context-file>] files ...",
159
- filter: {output_format: LD_FORMATS.keys}, # Only shows output format set
160
- lambda: ->(files, **options) do
161
- cli_exec(:compact, files, **options)
162
- end,
163
- options: [
164
- RDF::CLI::Option.new(
165
- symbol: :context,
166
- datatype: RDF::URI,
167
- control: :url2,
168
- use: :required,
169
- on: ["--context CONTEXT"],
170
- description: "Context to use when compacting.") {|arg| RDF::URI(arg)},
171
- RDF::CLI::Option.new(
172
- symbol: :createAnnotations,
173
- datatype: TrueClass,
174
- default: false,
175
- control: :checkbox,
176
- on: ["--[no-]create-annotations"],
177
- description: "Unfold embedded nodes which can be represented using `@annotation`."),
178
- ]
179
- },
180
- frame: {
181
- description: "Frame JSON-LD or parsed RDF",
182
- parse: false,
183
- help: "frame --frame <frame-file> files ...",
184
- filter: {output_format: LD_FORMATS.keys}, # Only shows output format set
185
- lambda: ->(files, **options) do
186
- raise ArgumentError, "Framing requires a frame" unless options[:frame]
187
- cli_exec(:compact, files, **options)
188
- end,
189
- option_use: {context: :removed},
190
- options: [
191
- RDF::CLI::Option.new(
192
- symbol: :frame,
193
- datatype: RDF::URI,
194
- control: :url2,
195
- use: :required,
196
- on: ["--frame FRAME"],
197
- description: "Frame to use when serializing.") {|arg| RDF::URI(arg).absolute? ? RDF::URI(arg) : StringIO.new(File.read(arg))}
198
- ]
199
- },
200
- }
201
- end
115
+ ##
116
+ # Hash of CLI commands appropriate for this format:
117
+ #
118
+ # * `expand` => {JSON::LD::API.expand}
119
+ # * `compact` => {JSON::LD::API.compact}
120
+ # * `flatten` => {JSON::LD::API.flatten}
121
+ # * `frame` => {JSON::LD::API.frame}
122
+ #
123
+ # @return [Hash{Symbol => Hash}]
124
+ def self.cli_commands
125
+ {
126
+ expand: {
127
+ description: "Expand JSON-LD or parsed RDF",
128
+ parse: false,
129
+ help: "expand [--context <context-file>] files ...",
130
+ filter: { output_format: LD_FORMATS.keys }, # Only shows output format set
131
+ lambda: lambda do |files, **options|
132
+ options = options.merge(expandContext: options.delete(:context)) if options.key?(:context)
133
+ cli_exec(:expand, files, **options)
134
+ end,
135
+ option_use: { context: :removed }
136
+ },
137
+ compact: {
138
+ description: "Compact JSON-LD or parsed RDF",
139
+ parse: false,
140
+ filter: { output_format: LD_FORMATS.keys }, # Only shows output format set
141
+ help: "compact --context <context-file> files ...",
142
+ lambda: lambda do |files, **options|
143
+ raise ArgumentError, "Compacting requires a context" unless options[:context]
202
144
 
203
- ##
204
- # Override normal symbol generation
205
- def self.to_sym
206
- :jsonld
207
- end
145
+ cli_exec(:compact, files, **options)
146
+ end,
147
+ options: [
148
+ RDF::CLI::Option.new(
149
+ symbol: :context,
150
+ datatype: RDF::URI,
151
+ control: :url2,
152
+ use: :required,
153
+ on: ["--context CONTEXT"],
154
+ description: "Context to use when compacting."
155
+ ) { |arg| RDF::URI(arg).absolute? ? RDF::URI(arg) : StringIO.new(File.read(arg)) }
156
+ ]
157
+ },
158
+ flatten: {
159
+ description: "Flatten JSON-LD or parsed RDF",
160
+ parse: false,
161
+ help: "flatten [--context <context-file>] files ...",
162
+ filter: { output_format: LD_FORMATS.keys }, # Only shows output format set
163
+ lambda: lambda do |files, **options|
164
+ cli_exec(:compact, files, **options)
165
+ end,
166
+ options: [
167
+ RDF::CLI::Option.new(
168
+ symbol: :context,
169
+ datatype: RDF::URI,
170
+ control: :url2,
171
+ use: :required,
172
+ on: ["--context CONTEXT"],
173
+ description: "Context to use when compacting."
174
+ ) { |arg| RDF::URI(arg) },
175
+ RDF::CLI::Option.new(
176
+ symbol: :createAnnotations,
177
+ datatype: TrueClass,
178
+ default: false,
179
+ control: :checkbox,
180
+ on: ["--[no-]create-annotations"],
181
+ description: "Unfold embedded nodes which can be represented using `@annotation`."
182
+ )
183
+ ]
184
+ },
185
+ frame: {
186
+ description: "Frame JSON-LD or parsed RDF",
187
+ parse: false,
188
+ help: "frame --frame <frame-file> files ...",
189
+ filter: { output_format: LD_FORMATS.keys }, # Only shows output format set
190
+ lambda: lambda do |files, **options|
191
+ raise ArgumentError, "Framing requires a frame" unless options[:frame]
208
192
 
209
- ##
210
- # Override normal format name
211
- def self.name
212
- "JSON-LD"
193
+ cli_exec(:compact, files, **options)
194
+ end,
195
+ option_use: { context: :removed },
196
+ options: [
197
+ RDF::CLI::Option.new(
198
+ symbol: :frame,
199
+ datatype: RDF::URI,
200
+ control: :url2,
201
+ use: :required,
202
+ on: ["--frame FRAME"],
203
+ description: "Frame to use when serializing."
204
+ ) { |arg| RDF::URI(arg).absolute? ? RDF::URI(arg) : StringIO.new(File.read(arg)) }
205
+ ]
206
+ }
207
+ }
208
+ end
209
+
210
+ ##
211
+ # Override normal symbol generation
212
+ def self.to_sym
213
+ :jsonld
214
+ end
215
+
216
+ ##
217
+ # Override normal format name
218
+ def self.name
219
+ "JSON-LD"
220
+ end
213
221
  end
214
222
  end
215
223
  end