json-ld 3.2.4 → 3.2.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/lib/json/ld/api.rb +807 -771
  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 -1913
  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 +223 -204
  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 -169
  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 +55 -198
  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 -2056
  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 -2541
  33. data/spec/from_rdf_spec.rb +0 -1072
  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 -1684
  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,194 +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 RDF::Value
29
- return value
30
- when TrueClass, FalseClass
31
- # 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.
32
- value = value.to_s
33
- datatype ||= RDF::XSD.boolean.to_s
34
- when Numeric
35
- # 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.
36
- value = if datatype == RDF::URI(RDF.to_uri + "JSON")
37
- value.to_json_c14n
38
- else
39
- # Don't serialize as double if there are no fractional bits
40
- as_double = value.ceil != value || value >= 1e21 || datatype == RDF::XSD.double
41
- lit = if as_double
42
- 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
43
40
  else
44
- 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")
45
51
  end
46
-
47
- datatype ||= lit.datatype
48
- lit.to_s.sub("E+", "E")
49
- end
50
- when Array, Hash
51
- # Only valid for rdf:JSON
52
- value = value.to_json_c14n
53
- else
54
- if item.key?('@direction') && @options[:rdfDirection]
55
- # Either serialize using a datatype, or a compound-literal
56
- case @options[:rdfDirection]
57
- when 'i18n-datatype'
58
- datatype = RDF::URI("https://www.w3.org/ns/i18n##{item.fetch('@language', '').downcase}_#{item['@direction']}")
59
- when 'compound-literal'
60
- cl = RDF::Node.new
61
- yield RDF::Statement(cl, RDF.value, item['@value'].to_s)
62
- yield RDF::Statement(cl, RDF.to_uri + 'language', item['@language'].downcase) if item['@language']
63
- yield RDF::Statement(cl, RDF.to_uri + 'direction', item['@direction'])
64
- 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
65
69
  end
66
- end
67
70
 
68
- # Otherwise, if datatype is null, set it to xsd:string or xsd:langString, depending on if item has a @language key.
69
- datatype ||= item.key?('@language') ? RDF.langString : RDF::XSD.string
70
- if datatype == RDF::URI(RDF.to_uri + "JSON")
71
- 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
72
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)
73
83
  end
74
- datatype = RDF::URI(datatype) if datatype && !datatype.is_a?(RDF::URI)
75
-
76
- # 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.
77
- language = item.fetch('@language', nil) if datatype == RDF.langString
78
- return RDF::Literal.new(value, datatype: datatype, language: language)
79
- elsif list?(item)
80
- # 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.
81
- return parse_list(item['@list'], graph_name: graph_name, &block)
82
- end
83
84
 
84
- subject = case item['@id']
85
- when nil then node
86
- when String then as_resource(item['@id'])
87
- when Object
88
- # Embedded/quoted statement
89
- # (No error checking, as this is done in expansion)
90
- to_enum(:item_to_rdf, item['@id'], quoted: true).to_a.first
91
- 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
92
93
 
93
- # log_debug("item_to_rdf") {"subject: #{subject.to_ntriples rescue 'malformed rdf'}"}
94
- item.each do |property, values|
95
- case property
96
- when '@type'
97
- # 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
98
- values.each do |v|
99
- object = as_resource(v)
100
- # log_debug("item_to_rdf") {"type: #{object.to_ntriples rescue 'malformed rdf'}"}
101
- yield RDF::Statement(subject, RDF.type, object, graph_name: graph_name, quoted: quoted)
102
- end
103
- when '@graph'
104
- values = [values].compact unless values.is_a?(Array)
105
- values.each do |nd|
106
- item_to_rdf(nd, graph_name: subject, quoted: quoted, &block)
107
- end
108
- when '@reverse'
109
- raise "Huh?" unless values.is_a?(Hash)
110
- values.each do |prop, vv|
111
- predicate = as_resource(prop)
112
- # log_debug("item_to_rdf") {"@reverse predicate: #{predicate.to_ntriples rescue 'malformed rdf'}"}
113
- # For each item in values
114
- vv.each do |v|
115
- # Item is a node definition. Generate object as the result of the Object Converstion algorithm passing item.
116
- object = item_to_rdf(v, graph_name: graph_name, &block)
117
- # log_debug("item_to_rdf") {"subject: #{object.to_ntriples rescue 'malformed rdf'}"}
118
- # yield subject, prediate, and literal to results.
119
- 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)
120
103
  end
121
- end
122
- when '@included'
123
- values.each do |v|
124
- item_to_rdf(v, graph_name: graph_name, &block)
125
- end
126
- when /^@/
127
- # Otherwise, if @type is any other keyword, skip to the next property-values pair
128
- else
129
- # Otherwise, property is an IRI or Blank Node identifier
130
- # Initialize predicate from property as an IRI or Blank node
131
- predicate = as_resource(property)
132
- # log_debug("item_to_rdf") {"predicate: #{predicate.to_ntriples rescue 'malformed rdf'}"}
133
-
134
- # For each item in values
135
- values.each do |v|
136
- if list?(v)
137
- # log_debug("item_to_rdf") {"list: #{v.inspect}"}
138
- # 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.
139
- object = parse_list(v['@list'], graph_name: graph_name, &block)
140
-
141
- # Append a triple composed of subject, prediate, and object to results and add all triples from list_results to results.
142
- yield RDF::Statement(subject, predicate, object, graph_name: graph_name, quoted: quoted)
143
- else
144
- # Otherwise, item is a value object or a node definition. Generate object as the result of the Object Converstion algorithm passing item.
145
- object = item_to_rdf(v, graph_name: graph_name, &block)
146
- # log_debug("item_to_rdf") {"object: #{object.to_ntriples rescue 'malformed rdf'}"}
147
- # 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
148
150
  yield RDF::Statement(subject, predicate, object, graph_name: graph_name, quoted: quoted)
149
151
  end
150
152
  end
151
153
  end
152
- end
153
-
154
- subject
155
- end
156
154
 
157
- ##
158
- # Parse a List
159
- #
160
- # @param [Array] list
161
- # The Array to serialize as a list
162
- # @yield statement
163
- # @yieldparam [RDF::Resource] statement
164
- # @return [Array<RDF::Statement>]
165
- # Statements for each item in the list
166
- def parse_list(list, graph_name: nil, &block)
167
- # log_debug('parse_list') {"list: #{list.inspect}"}
168
-
169
- last = list.pop
170
- result = first_bnode = last ? node : RDF.nil
171
-
172
- list.each do |list_item|
173
- # Set first to the result of the Object Converstion algorithm passing item.
174
- object = item_to_rdf(list_item, graph_name: graph_name, &block)
175
- yield RDF::Statement(first_bnode, RDF.first, object, graph_name: graph_name)
176
- rest_bnode = node
177
- yield RDF::Statement(first_bnode, RDF.rest, rest_bnode, graph_name: graph_name)
178
- first_bnode = rest_bnode
155
+ subject
179
156
  end
180
- if last
181
- object = item_to_rdf(last, graph_name: graph_name, &block)
182
- yield RDF::Statement(first_bnode, RDF.first, object, graph_name: graph_name)
183
- 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
184
187
  end
185
- result
186
- end
187
188
 
188
- ##
189
- # Create a new named node using the sequence
190
- def node
191
- 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
192
194
  end
193
195
  end
194
196
  end