json-ld 3.2.3 → 3.2.5

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 (99) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/lib/json/ld/api.rb +807 -764
  4. data/lib/json/ld/compact.rb +304 -304
  5. data/lib/json/ld/conneg.rb +179 -161
  6. data/lib/json/ld/context.rb +2080 -1945
  7. data/lib/json/ld/expand.rb +745 -666
  8. data/lib/json/ld/extensions.rb +14 -13
  9. data/lib/json/ld/flatten.rb +257 -247
  10. data/lib/json/ld/format.rb +202 -194
  11. data/lib/json/ld/frame.rb +525 -502
  12. data/lib/json/ld/from_rdf.rb +224 -166
  13. data/lib/json/ld/html/nokogiri.rb +123 -121
  14. data/lib/json/ld/html/rexml.rb +151 -147
  15. data/lib/json/ld/reader.rb +107 -100
  16. data/lib/json/ld/resource.rb +224 -205
  17. data/lib/json/ld/streaming_reader.rb +574 -507
  18. data/lib/json/ld/streaming_writer.rb +93 -92
  19. data/lib/json/ld/to_rdf.rb +171 -167
  20. data/lib/json/ld/utils.rb +270 -264
  21. data/lib/json/ld/version.rb +24 -14
  22. data/lib/json/ld/writer.rb +334 -311
  23. data/lib/json/ld.rb +103 -96
  24. metadata +78 -209
  25. data/spec/api_spec.rb +0 -132
  26. data/spec/compact_spec.rb +0 -3482
  27. data/spec/conneg_spec.rb +0 -373
  28. data/spec/context_spec.rb +0 -2036
  29. data/spec/expand_spec.rb +0 -4496
  30. data/spec/flatten_spec.rb +0 -1203
  31. data/spec/format_spec.rb +0 -115
  32. data/spec/frame_spec.rb +0 -2498
  33. data/spec/from_rdf_spec.rb +0 -1005
  34. data/spec/matchers.rb +0 -20
  35. data/spec/rdfstar_spec.rb +0 -25
  36. data/spec/reader_spec.rb +0 -883
  37. data/spec/resource_spec.rb +0 -76
  38. data/spec/spec_helper.rb +0 -281
  39. data/spec/streaming_reader_spec.rb +0 -237
  40. data/spec/streaming_writer_spec.rb +0 -145
  41. data/spec/suite_compact_spec.rb +0 -22
  42. data/spec/suite_expand_spec.rb +0 -36
  43. data/spec/suite_flatten_spec.rb +0 -34
  44. data/spec/suite_frame_spec.rb +0 -29
  45. data/spec/suite_from_rdf_spec.rb +0 -22
  46. data/spec/suite_helper.rb +0 -411
  47. data/spec/suite_html_spec.rb +0 -22
  48. data/spec/suite_http_spec.rb +0 -35
  49. data/spec/suite_remote_doc_spec.rb +0 -22
  50. data/spec/suite_to_rdf_spec.rb +0 -30
  51. data/spec/support/extensions.rb +0 -44
  52. data/spec/test-files/test-1-compacted.jsonld +0 -10
  53. data/spec/test-files/test-1-context.jsonld +0 -7
  54. data/spec/test-files/test-1-expanded.jsonld +0 -5
  55. data/spec/test-files/test-1-input.jsonld +0 -10
  56. data/spec/test-files/test-1-rdf.ttl +0 -8
  57. data/spec/test-files/test-2-compacted.jsonld +0 -20
  58. data/spec/test-files/test-2-context.jsonld +0 -7
  59. data/spec/test-files/test-2-expanded.jsonld +0 -16
  60. data/spec/test-files/test-2-input.jsonld +0 -20
  61. data/spec/test-files/test-2-rdf.ttl +0 -14
  62. data/spec/test-files/test-3-compacted.jsonld +0 -11
  63. data/spec/test-files/test-3-context.jsonld +0 -8
  64. data/spec/test-files/test-3-expanded.jsonld +0 -10
  65. data/spec/test-files/test-3-input.jsonld +0 -11
  66. data/spec/test-files/test-3-rdf.ttl +0 -8
  67. data/spec/test-files/test-4-compacted.jsonld +0 -10
  68. data/spec/test-files/test-4-context.jsonld +0 -7
  69. data/spec/test-files/test-4-expanded.jsonld +0 -6
  70. data/spec/test-files/test-4-input.jsonld +0 -10
  71. data/spec/test-files/test-4-rdf.ttl +0 -5
  72. data/spec/test-files/test-5-compacted.jsonld +0 -13
  73. data/spec/test-files/test-5-context.jsonld +0 -7
  74. data/spec/test-files/test-5-expanded.jsonld +0 -9
  75. data/spec/test-files/test-5-input.jsonld +0 -13
  76. data/spec/test-files/test-5-rdf.ttl +0 -7
  77. data/spec/test-files/test-6-compacted.jsonld +0 -10
  78. data/spec/test-files/test-6-context.jsonld +0 -7
  79. data/spec/test-files/test-6-expanded.jsonld +0 -10
  80. data/spec/test-files/test-6-input.jsonld +0 -10
  81. data/spec/test-files/test-6-rdf.ttl +0 -6
  82. data/spec/test-files/test-7-compacted.jsonld +0 -23
  83. data/spec/test-files/test-7-context.jsonld +0 -4
  84. data/spec/test-files/test-7-expanded.jsonld +0 -20
  85. data/spec/test-files/test-7-input.jsonld +0 -23
  86. data/spec/test-files/test-7-rdf.ttl +0 -14
  87. data/spec/test-files/test-8-compacted.jsonld +0 -34
  88. data/spec/test-files/test-8-context.jsonld +0 -11
  89. data/spec/test-files/test-8-expanded.jsonld +0 -24
  90. data/spec/test-files/test-8-frame.jsonld +0 -18
  91. data/spec/test-files/test-8-framed.jsonld +0 -25
  92. data/spec/test-files/test-8-input.jsonld +0 -30
  93. data/spec/test-files/test-8-rdf.ttl +0 -15
  94. data/spec/test-files/test-9-compacted.jsonld +0 -20
  95. data/spec/test-files/test-9-context.jsonld +0 -13
  96. data/spec/test-files/test-9-expanded.jsonld +0 -14
  97. data/spec/test-files/test-9-input.jsonld +0 -12
  98. data/spec/to_rdf_spec.rb +0 -1551
  99. data/spec/writer_spec.rb +0 -427
@@ -1,116 +1,117 @@
1
- # -*- encoding: utf-8 -*-
2
1
  # frozen_string_literal: true
3
- module JSON::LD
4
- ##
5
- # Streaming writer interface.
6
- #
7
- # Writes an array of statements serialized in expanded JSON-LD. No provision for turning rdf:first/rest into @list encodings.
8
- # @author [Gregg Kellogg](http://greggkellogg.net/)
9
- module StreamingWriter
10
- ##
11
- # Write out array start, and note not to prepend node-separating ','
12
- # @return [void] `self`
13
- def stream_prologue
14
-
15
- # If we were provided a context, or prefixes, use them to compact the output
16
- @context = case @options[:context]
17
- when nil then nil
18
- when Context then @options[:context]
19
- else Context.parse(@options[:context])
20
- end
21
-
22
- #log_debug("prologue") {"context: #{context.inspect}"}
23
- if context
24
- @output.puts %({"@context": #{context.serialize['@context'].to_json}, "@graph": [)
25
- else
26
- @output.puts "["
27
- end
28
- self
29
- end
30
2
 
3
+ module JSON
4
+ module LD
31
5
  ##
32
- # Write a statement, creating a current node definition, if necessary.
33
- #
34
- # Once a new/first statement is seen, terminate the current node definition and compact if provided a context.
35
- #
36
- # Also expects all statements in the same context to be contained in a block including all subjects in a block (except for list elements)
6
+ # Streaming writer interface.
37
7
  #
38
- # Note that if list elements are not received in order using the same subject and property, this may cause a bad serialization.
39
- #
40
- # @return [void] `self`
41
- def stream_statement(statement)
42
- #log_debug("ss") {"state: #{@state.inspect}, stmt: #{statement}"}
43
- if @current_graph != statement.graph_name
44
- end_graph
45
- start_graph(statement.graph_name)
8
+ # Writes an array of statements serialized in expanded JSON-LD. No provision for turning rdf:first/rest into @list encodings.
9
+ # @author [Gregg Kellogg](http://greggkellogg.net/)
10
+ module StreamingWriter
11
+ ##
12
+ # Write out array start, and note not to prepend node-separating ','
13
+ # @return [void] `self`
14
+ def stream_prologue
15
+ # If we were provided a context, or prefixes, use them to compact the output
16
+ @context = case @options[:context]
17
+ when nil then nil
18
+ when Context then @options[:context]
19
+ else Context.parse(@options[:context])
20
+ end
21
+
22
+ # log_debug("prologue") {"context: #{context.inspect}"}
23
+ if context
24
+ @output.puts %({"@context": #{context.serialize['@context'].to_json}, "@graph": [)
25
+ else
26
+ @output.puts "["
27
+ end
28
+ self
46
29
  end
47
30
 
48
- # If we're writing a list
49
- @current_node_def ||= {'@id' => statement.subject.to_s}
31
+ ##
32
+ # Write a statement, creating a current node definition, if necessary.
33
+ #
34
+ # Once a new/first statement is seen, terminate the current node definition and compact if provided a context.
35
+ #
36
+ # Also expects all statements in the same context to be contained in a block including all subjects in a block (except for list elements)
37
+ #
38
+ # Note that if list elements are not received in order using the same subject and property, this may cause a bad serialization.
39
+ #
40
+ # @return [void] `self`
41
+ def stream_statement(statement)
42
+ # log_debug("ss") {"state: #{@state.inspect}, stmt: #{statement}"}
43
+ if @current_graph != statement.graph_name
44
+ end_graph
45
+ start_graph(statement.graph_name)
46
+ end
50
47
 
51
- if statement.subject.to_s != @current_node_def['@id']
52
- end_node
53
- @current_node_def = {'@id' => statement.subject.to_s}
54
- end
48
+ # If we're writing a list
49
+ @current_node_def ||= { '@id' => statement.subject.to_s }
55
50
 
56
- if statement.predicate == RDF.type
57
- (@current_node_def['@type'] ||= []) << statement.object.to_s
58
- else
59
- pd = (@current_node_def[statement.predicate.to_s] ||= [])
51
+ if statement.subject.to_s != @current_node_def['@id']
52
+ end_node
53
+ @current_node_def = { '@id' => statement.subject.to_s }
54
+ end
60
55
 
61
- pd << if statement.object.resource?
62
- {'@id' => statement.object.to_s}
63
- elsif statement.object.datatype == RDF::URI(RDF.to_uri + "JSON")
64
- {"@value" => MultiJson.load(statement.object.to_s), "@type" => "@json"}
56
+ if statement.predicate == RDF.type
57
+ (@current_node_def['@type'] ||= []) << statement.object.to_s
65
58
  else
66
- lit = {"@value" => statement.object.to_s}
67
- lit["@type"] = statement.object.datatype.to_s if statement.object.datatype?
68
- lit["@language"] = statement.object.language.to_s if statement.object.language?
69
- lit
59
+ pd = (@current_node_def[statement.predicate.to_s] ||= [])
60
+
61
+ pd << if statement.object.resource?
62
+ { '@id' => statement.object.to_s }
63
+ elsif statement.object.datatype == RDF_JSON
64
+ { "@value" => MultiJson.load(statement.object.to_s), "@type" => "@json" }
65
+ else
66
+ lit = { "@value" => statement.object.to_s }
67
+ lit["@type"] = statement.object.datatype.to_s if statement.object.datatype?
68
+ lit["@language"] = statement.object.language.to_s if statement.object.language?
69
+ lit
70
+ end
70
71
  end
72
+ self
71
73
  end
72
- self
73
- end
74
74
 
75
- ##
76
- # Complete open statements
77
- # @return [void] `self`
78
- def stream_epilogue
79
- #log_debug("epilogue") {"state: #{@state.inspect}"}
80
- end_graph
81
- if context
82
- @output.puts "\n]}"
83
- else
84
- @output.puts "\n]"
75
+ ##
76
+ # Complete open statements
77
+ # @return [void] `self`
78
+ def stream_epilogue
79
+ # log_debug("epilogue") {"state: #{@state.inspect}"}
80
+ end_graph
81
+ if context
82
+ @output.puts "\n]}"
83
+ else
84
+ @output.puts "\n]"
85
+ end
86
+ self
85
87
  end
86
- self
87
- end
88
88
 
89
- private
90
-
91
- def start_graph(resource)
92
- #log_debug("start_graph") {"state: #{@state.inspect}, resource: #{resource}"}
93
- if resource
94
- @output.puts(",") if %i(wrote_node wrote_graph).include?(@state)
95
- @output.puts %({"@id": "#{resource}", "@graph": [)
96
- @state = :in_graph
89
+ private
90
+
91
+ def start_graph(resource)
92
+ # log_debug("start_graph") {"state: #{@state.inspect}, resource: #{resource}"}
93
+ if resource
94
+ @output.puts(",") if %i[wrote_node wrote_graph].include?(@state)
95
+ @output.puts %({"@id": "#{resource}", "@graph": [)
96
+ @state = :in_graph
97
+ end
98
+ @current_graph = resource
97
99
  end
98
- @current_graph = resource
99
- end
100
100
 
101
- def end_graph
102
- #log_debug("end_graph") {"state: #{@state.inspect}, ctx: #{@current_graph}"}
103
- end_node
104
- if @current_graph
101
+ def end_graph
102
+ # log_debug("end_graph") {"state: #{@state.inspect}, ctx: #{@current_graph}"}
103
+ end_node
104
+ return unless @current_graph
105
+
105
106
  @output.write %(]})
106
107
  @state = :wrote_graph
107
108
  end
108
- end
109
109
 
110
- def end_node
111
- #log_debug("end_node") {"state: #{@state.inspect}, node: #{@current_node_def.to_json}"}
112
- @output.puts(",") if %i(wrote_node wrote_graph).include?(@state)
113
- if @current_node_def
110
+ def end_node
111
+ # log_debug("end_node") {"state: #{@state.inspect}, node: #{@current_node_def.to_json}"}
112
+ @output.puts(",") if %i[wrote_node wrote_graph].include?(@state)
113
+ return unless @current_node_def
114
+
114
115
  node_def = if context
115
116
  compacted = JSON::LD::API.compact(@current_node_def, context, rename_bnodes: false, **@options)
116
117
  compacted.delete('@context')
@@ -1,192 +1,196 @@
1
- # -*- encoding: utf-8 -*-
2
1
  # frozen_string_literal: true
2
+
3
3
  require 'rdf'
4
4
  require 'rdf/nquads'
5
5
  require 'json/canonicalization'
6
6
 
7
- module JSON::LD
8
- module ToRDF
9
- include Utils
10
-
11
- ##
12
- # @param [Hash{String => Object}] item
13
- # @param [RDF::Resource] graph_name
14
- # @param [Boolean] quoted emitted triples are quoted triples.
15
- # @yield statement
16
- # @yieldparam [RDF::Statement] statement
17
- # @return RDF::Resource the subject of this item
18
- def item_to_rdf(item, graph_name: nil, quoted: false, &block)
19
- # Just return value object as Term
20
- return unless item
21
-
22
- if value?(item)
23
- value, datatype = item.fetch('@value'), item.fetch('@type', nil)
24
-
25
- datatype = RDF::URI(RDF.to_uri + "JSON") if datatype == '@json'
26
-
27
- case value
28
- when TrueClass, FalseClass
29
- # If value is true or false, then set value its canonical lexical form as defined in the section Data Round Tripping. If datatype is null, set it to xsd:boolean.
30
- value = value.to_s
31
- datatype ||= RDF::XSD.boolean.to_s
32
- when Numeric
33
- # Otherwise, if value is a number, then set value to its canonical lexical form as defined in the section Data Round Tripping. If datatype is null, set it to either xsd:integer or xsd:double, depending on if the value contains a fractional and/or an exponential component.
34
- value = if datatype == RDF::URI(RDF.to_uri + "JSON")
35
- value.to_json_c14n
36
- else
37
- # Don't serialize as double if there are no fractional bits
38
- as_double = value.ceil != value || value >= 1e21 || datatype == RDF::XSD.double
39
- lit = if as_double
40
- RDF::Literal::Double.new(value, canonicalize: true)
7
+ module JSON
8
+ module LD
9
+ module ToRDF
10
+ include Utils
11
+
12
+ ##
13
+ # @param [Hash{String => Object}] item
14
+ # @param [RDF::Resource] graph_name
15
+ # @param [Boolean] quoted emitted triples are quoted triples.
16
+ # @yield statement
17
+ # @yieldparam [RDF::Statement] statement
18
+ # @return RDF::Resource the subject of this item
19
+ def item_to_rdf(item, graph_name: nil, quoted: false, &block)
20
+ # Just return value object as Term
21
+ return unless item
22
+
23
+ if value?(item)
24
+ value = item.fetch('@value')
25
+ datatype = item.fetch('@type', nil)
26
+
27
+ datatype = RDF_JSON if datatype == '@json'
28
+
29
+ case value
30
+ when RDF::Value
31
+ return value
32
+ when TrueClass, FalseClass
33
+ # If value is true or false, then set value its canonical lexical form as defined in the section Data Round Tripping. If datatype is null, set it to xsd:boolean.
34
+ value = value.to_s
35
+ datatype ||= RDF::XSD.boolean.to_s
36
+ when Numeric
37
+ # Otherwise, if value is a number, then set value to its canonical lexical form as defined in the section Data Round Tripping. If datatype is null, set it to either xsd:integer or xsd:double, depending on if the value contains a fractional and/or an exponential component.
38
+ value = if datatype == RDF_JSON
39
+ value.to_json_c14n
41
40
  else
42
- RDF::Literal.new(value.numerator, canonicalize: true)
41
+ # Don't serialize as double if there are no fractional bits
42
+ as_double = value.ceil != value || value >= 1e21 || datatype == RDF::XSD.double
43
+ lit = if as_double
44
+ RDF::Literal::Double.new(value, canonicalize: true)
45
+ else
46
+ RDF::Literal.new(value.numerator, canonicalize: true)
47
+ end
48
+
49
+ datatype ||= lit.datatype
50
+ lit.to_s.sub("E+", "E")
43
51
  end
44
-
45
- datatype ||= lit.datatype
46
- lit.to_s.sub("E+", "E")
47
- end
48
- when Array, Hash
49
- # Only valid for rdf:JSON
50
- value = value.to_json_c14n
51
- else
52
- if item.key?('@direction') && @options[:rdfDirection]
53
- # Either serialize using a datatype, or a compound-literal
54
- case @options[:rdfDirection]
55
- when 'i18n-datatype'
56
- datatype = RDF::URI("https://www.w3.org/ns/i18n##{item.fetch('@language', '').downcase}_#{item['@direction']}")
57
- when 'compound-literal'
58
- cl = RDF::Node.new
59
- yield RDF::Statement(cl, RDF.value, item['@value'].to_s)
60
- yield RDF::Statement(cl, RDF.to_uri + 'language', item['@language'].downcase) if item['@language']
61
- yield RDF::Statement(cl, RDF.to_uri + 'direction', item['@direction'])
62
- return cl
52
+ when Array, Hash
53
+ # Only valid for rdf:JSON
54
+ value = value.to_json_c14n
55
+ else
56
+ if item.key?('@direction') && @options[:rdfDirection]
57
+ # Either serialize using a datatype, or a compound-literal
58
+ case @options[:rdfDirection]
59
+ when 'i18n-datatype'
60
+ datatype = RDF::URI("https://www.w3.org/ns/i18n##{item.fetch('@language',
61
+ '').downcase}_#{item['@direction']}")
62
+ when 'compound-literal'
63
+ cl = RDF::Node.new
64
+ yield RDF::Statement(cl, RDF.value, item['@value'].to_s)
65
+ yield RDF::Statement(cl, RDF_LANGUAGE, item['@language'].downcase) if item['@language']
66
+ yield RDF::Statement(cl, RDF_DIRECTION, item['@direction'])
67
+ return cl
68
+ end
63
69
  end
64
- end
65
70
 
66
- # Otherwise, if datatype is null, set it to xsd:string or xsd:langString, depending on if item has a @language key.
67
- datatype ||= item.key?('@language') ? RDF.langString : RDF::XSD.string
68
- if datatype == RDF::URI(RDF.to_uri + "JSON")
69
- value = value.to_json_c14n
71
+ # Otherwise, if datatype is null, set it to xsd:string or xsd:langString, depending on if item has a @language key.
72
+ datatype ||= item.key?('@language') ? RDF.langString : RDF::XSD.string
73
+ value = value.to_json_c14n if datatype == RDF_JSON
70
74
  end
75
+ datatype = RDF::URI(datatype) if datatype && !datatype.is_a?(RDF::URI)
76
+
77
+ # Initialize literal as an RDF literal using value and datatype. If element has the key @language and datatype is xsd:string, then add the value associated with the @language key as the language of the object.
78
+ language = item.fetch('@language', nil) if datatype == RDF.langString
79
+ return RDF::Literal.new(value, datatype: datatype, language: language)
80
+ elsif list?(item)
81
+ # If item is a list object, initialize list_results as an empty array, and object to the result of the List Conversion algorithm, passing the value associated with the @list key from item and list_results.
82
+ return parse_list(item['@list'], graph_name: graph_name, &block)
71
83
  end
72
- datatype = RDF::URI(datatype) if datatype && !datatype.is_a?(RDF::URI)
73
-
74
- # Initialize literal as an RDF literal using value and datatype. If element has the key @language and datatype is xsd:string, then add the value associated with the @language key as the language of the object.
75
- language = item.fetch('@language', nil) if datatype == RDF.langString
76
- return RDF::Literal.new(value, datatype: datatype, language: language)
77
- elsif list?(item)
78
- # If item is a list object, initialize list_results as an empty array, and object to the result of the List Conversion algorithm, passing the value associated with the @list key from item and list_results.
79
- return parse_list(item['@list'], graph_name: graph_name, &block)
80
- end
81
84
 
82
- subject = case item['@id']
83
- when nil then node
84
- when String then as_resource(item['@id'])
85
- when Object
86
- # Embedded/quoted statement
87
- # (No error checking, as this is done in expansion)
88
- to_enum(:item_to_rdf, item['@id'], quoted: true).to_a.first
89
- end
85
+ subject = case item['@id']
86
+ when nil then node
87
+ when String then as_resource(item['@id'])
88
+ when Object
89
+ # Embedded/quoted statement
90
+ # (No error checking, as this is done in expansion)
91
+ to_enum(:item_to_rdf, item['@id'], quoted: true).to_a.first
92
+ end
90
93
 
91
- #log_debug("item_to_rdf") {"subject: #{subject.to_ntriples rescue 'malformed rdf'}"}
92
- item.each do |property, values|
93
- case property
94
- when '@type'
95
- # If property is @type, construct triple as an RDF Triple composed of id, rdf:type, and object from values where id and object are represented either as IRIs or Blank Nodes
96
- values.each do |v|
97
- object = as_resource(v)
98
- #log_debug("item_to_rdf") {"type: #{object.to_ntriples rescue 'malformed rdf'}"}
99
- yield RDF::Statement(subject, RDF.type, object, graph_name: graph_name, quoted: quoted)
100
- end
101
- when '@graph'
102
- values = [values].compact unless values.is_a?(Array)
103
- values.each do |nd|
104
- item_to_rdf(nd, graph_name: subject, quoted: quoted, &block)
105
- end
106
- when '@reverse'
107
- raise "Huh?" unless values.is_a?(Hash)
108
- values.each do |prop, vv|
109
- predicate = as_resource(prop)
110
- #log_debug("item_to_rdf") {"@reverse predicate: #{predicate.to_ntriples rescue 'malformed rdf'}"}
111
- # For each item in values
112
- vv.each do |v|
113
- # Item is a node definition. Generate object as the result of the Object Converstion algorithm passing item.
114
- object = item_to_rdf(v, graph_name: graph_name, &block)
115
- #log_debug("item_to_rdf") {"subject: #{object.to_ntriples rescue 'malformed rdf'}"}
116
- # yield subject, prediate, and literal to results.
117
- yield RDF::Statement(object, predicate, subject, graph_name: graph_name, quoted: quoted)
94
+ # log_debug("item_to_rdf") {"subject: #{subject.to_ntriples rescue 'malformed rdf'}"}
95
+ item.each do |property, values|
96
+ case property
97
+ when '@type'
98
+ # If property is @type, construct triple as an RDF Triple composed of id, rdf:type, and object from values where id and object are represented either as IRIs or Blank Nodes
99
+ values.each do |v|
100
+ object = as_resource(v)
101
+ # log_debug("item_to_rdf") {"type: #{object.to_ntriples rescue 'malformed rdf'}"}
102
+ yield RDF::Statement(subject, RDF.type, object, graph_name: graph_name, quoted: quoted)
118
103
  end
119
- end
120
- when '@included'
121
- values.each do |v|
122
- item_to_rdf(v, graph_name: graph_name, &block)
123
- end
124
- when /^@/
125
- # Otherwise, if @type is any other keyword, skip to the next property-values pair
126
- else
127
- # Otherwise, property is an IRI or Blank Node identifier
128
- # Initialize predicate from property as an IRI or Blank node
129
- predicate = as_resource(property)
130
- #log_debug("item_to_rdf") {"predicate: #{predicate.to_ntriples rescue 'malformed rdf'}"}
131
-
132
- # For each item in values
133
- values.each do |v|
134
- if list?(v)
135
- #log_debug("item_to_rdf") {"list: #{v.inspect}"}
136
- # If item is a list object, initialize list_results as an empty array, and object to the result of the List Conversion algorithm, passing the value associated with the @list key from item and list_results.
137
- object = parse_list(v['@list'], graph_name: graph_name, &block)
138
-
139
- # Append a triple composed of subject, prediate, and object to results and add all triples from list_results to results.
140
- yield RDF::Statement(subject, predicate, object, graph_name: graph_name, quoted: quoted)
141
- else
142
- # Otherwise, item is a value object or a node definition. Generate object as the result of the Object Converstion algorithm passing item.
143
- object = item_to_rdf(v, graph_name: graph_name, &block)
144
- #log_debug("item_to_rdf") {"object: #{object.to_ntriples rescue 'malformed rdf'}"}
145
- # yield subject, prediate, and literal to results.
104
+ when '@graph'
105
+ values = [values].compact unless values.is_a?(Array)
106
+ values.each do |nd|
107
+ item_to_rdf(nd, graph_name: subject, quoted: quoted, &block)
108
+ end
109
+ when '@reverse'
110
+ raise "Huh?" unless values.is_a?(Hash)
111
+
112
+ values.each do |prop, vv|
113
+ predicate = as_resource(prop)
114
+ # log_debug("item_to_rdf") {"@reverse predicate: #{predicate.to_ntriples rescue 'malformed rdf'}"}
115
+ # For each item in values
116
+ vv.each do |v|
117
+ # Item is a node definition. Generate object as the result of the Object Converstion algorithm passing item.
118
+ object = item_to_rdf(v, graph_name: graph_name, &block)
119
+ # log_debug("item_to_rdf") {"subject: #{object.to_ntriples rescue 'malformed rdf'}"}
120
+ # yield subject, prediate, and literal to results.
121
+ yield RDF::Statement(object, predicate, subject, graph_name: graph_name, quoted: quoted)
122
+ end
123
+ end
124
+ when '@included'
125
+ values.each do |v|
126
+ item_to_rdf(v, graph_name: graph_name, &block)
127
+ end
128
+ when /^@/
129
+ # Otherwise, if @type is any other keyword, skip to the next property-values pair
130
+ else
131
+ # Otherwise, property is an IRI or Blank Node identifier
132
+ # Initialize predicate from property as an IRI or Blank node
133
+ predicate = as_resource(property)
134
+ # log_debug("item_to_rdf") {"predicate: #{predicate.to_ntriples rescue 'malformed rdf'}"}
135
+
136
+ # For each item in values
137
+ values.each do |v|
138
+ if list?(v)
139
+ # log_debug("item_to_rdf") {"list: #{v.inspect}"}
140
+ # If item is a list object, initialize list_results as an empty array, and object to the result of the List Conversion algorithm, passing the value associated with the @list key from item and list_results.
141
+ object = parse_list(v['@list'], graph_name: graph_name, &block)
142
+
143
+ # Append a triple composed of subject, prediate, and object to results and add all triples from list_results to results.
144
+ else
145
+ # Otherwise, item is a value object or a node definition. Generate object as the result of the Object Converstion algorithm passing item.
146
+ object = item_to_rdf(v, graph_name: graph_name, &block)
147
+ # log_debug("item_to_rdf") {"object: #{object.to_ntriples rescue 'malformed rdf'}"}
148
+ # yield subject, prediate, and literal to results.
149
+ end
146
150
  yield RDF::Statement(subject, predicate, object, graph_name: graph_name, quoted: quoted)
147
151
  end
148
152
  end
149
153
  end
150
- end
151
-
152
- subject
153
- end
154
154
 
155
- ##
156
- # Parse a List
157
- #
158
- # @param [Array] list
159
- # The Array to serialize as a list
160
- # @yield statement
161
- # @yieldparam [RDF::Resource] statement
162
- # @return [Array<RDF::Statement>]
163
- # Statements for each item in the list
164
- def parse_list(list, graph_name: nil, &block)
165
- #log_debug('parse_list') {"list: #{list.inspect}"}
166
-
167
- last = list.pop
168
- result = first_bnode = last ? node : RDF.nil
169
-
170
- list.each do |list_item|
171
- # Set first to the result of the Object Converstion algorithm passing item.
172
- object = item_to_rdf(list_item, graph_name: graph_name, &block)
173
- yield RDF::Statement(first_bnode, RDF.first, object, graph_name: graph_name)
174
- rest_bnode = node
175
- yield RDF::Statement(first_bnode, RDF.rest, rest_bnode, graph_name: graph_name)
176
- first_bnode = rest_bnode
155
+ subject
177
156
  end
178
- if last
179
- object = item_to_rdf(last, graph_name: graph_name, &block)
180
- yield RDF::Statement(first_bnode, RDF.first, object, graph_name: graph_name)
181
- yield RDF::Statement(first_bnode, RDF.rest, RDF.nil, graph_name: graph_name)
157
+
158
+ ##
159
+ # Parse a List
160
+ #
161
+ # @param [Array] list
162
+ # The Array to serialize as a list
163
+ # @yield statement
164
+ # @yieldparam [RDF::Resource] statement
165
+ # @return [Array<RDF::Statement>]
166
+ # Statements for each item in the list
167
+ def parse_list(list, graph_name: nil, &block)
168
+ # log_debug('parse_list') {"list: #{list.inspect}"}
169
+
170
+ last = list.pop
171
+ result = first_bnode = last ? node : RDF.nil
172
+
173
+ list.each do |list_item|
174
+ # Set first to the result of the Object Converstion algorithm passing item.
175
+ object = item_to_rdf(list_item, graph_name: graph_name, &block)
176
+ yield RDF::Statement(first_bnode, RDF.first, object, graph_name: graph_name)
177
+ rest_bnode = node
178
+ yield RDF::Statement(first_bnode, RDF.rest, rest_bnode, graph_name: graph_name)
179
+ first_bnode = rest_bnode
180
+ end
181
+ if last
182
+ object = item_to_rdf(last, graph_name: graph_name, &block)
183
+ yield RDF::Statement(first_bnode, RDF.first, object, graph_name: graph_name)
184
+ yield RDF::Statement(first_bnode, RDF.rest, RDF.nil, graph_name: graph_name)
185
+ end
186
+ result
182
187
  end
183
- result
184
- end
185
188
 
186
- ##
187
- # Create a new named node using the sequence
188
- def node
189
- RDF::Node.new(namer.get_sym)
189
+ ##
190
+ # Create a new named node using the sequence
191
+ def node
192
+ RDF::Node.new(namer.get_sym)
193
+ end
190
194
  end
191
195
  end
192
196
  end