rdf-trig 1.0.1 → 1.0.3

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.
@@ -71,16 +71,19 @@ module RDF::TriG
71
71
  case token.value
72
72
  when 'A', 'a' then input[:resource] = RDF.type
73
73
  when 'true', 'false' then input[:resource] = RDF::Literal::Boolean.new(token.value)
74
- when '@base', '@prefix' then input[:lang] = token.value[1..-1]
74
+ when '.' then input[:terminated] = true
75
75
  else input[:string] = token.value
76
76
  end
77
77
  end
78
78
 
79
+ terminal(:GRAPH, /graph/i) do |prod, token, input|
80
+ input[:string_value] = token.value
81
+ end
79
82
  terminal(:PREFIX, PREFIX) do |prod, token, input|
80
- input[:string_value] = token.value.downcase
83
+ input[:string_value] = token.value
81
84
  end
82
85
  terminal(:BASE, BASE) do |prod, token, input|
83
- input[:string_value] = token.value.downcase
86
+ input[:string_value] = token.value
84
87
  end
85
88
 
86
89
  terminal(:LANGTAG, LANGTAG) do |prod, token, input|
@@ -88,47 +91,72 @@ module RDF::TriG
88
91
  end
89
92
 
90
93
  # Productions
91
- # [3g] graph defines the basic creation of context
92
- start_production(:graph) do |input, current, callback|
94
+ # [2g] block defines the basic creation of context
95
+ start_production(:block) do |input, current, callback|
93
96
  callback.call(:context, "graph", nil)
94
97
  end
95
- production(:graph) do |input, current, callback|
98
+ production(:block) do |input, current, callback|
96
99
  callback.call(:context, "graph", nil)
97
100
  end
98
101
 
99
- # [4g] graphName
100
- # Normally, just returns the resource, but if called from [3g], also
101
- # sets the context for triples defined within that graph
102
- production(:graphName) do |input, current, callback|
102
+ # [7g] labelOrSubject
103
+ # Sets the context for triples defined within that graph
104
+ production(:labelOrSubject) do |input, current, callback|
103
105
  # If input contains set_graph_iri, use the returned value to set @context
104
- debug("graphName") {"Set graph context to #{current[:resource]}"}
105
- callback.call(:context, "graphName", current[:resource])
106
+ debug(":labelOrSubject") {"Set graph context to #{current[:resource]}"}
107
+ callback.call(:context, "labelOrSubject", current[:resource])
108
+ input[:resource] = current[:resource]
106
109
  end
107
110
 
111
+ # _triplesOrGraph_2 ::= predicateObjectList '.'
112
+ start_production(:_triplesOrGraph_2) do |input, current, callback|
113
+ # Default graph after all
114
+ callback.call(:context, "graph", nil)
115
+ debug("_triplesOrGraph_2") {"subject: #{current[:resource]}"}
116
+ current[:subject] = input[:resource]
117
+ end
108
118
 
109
119
  # Productions
110
120
  # [4] prefixID defines a prefix mapping
111
121
  production(:prefixID) do |input, current, callback|
112
122
  prefix = current[:prefix]
113
123
  iri = current[:resource]
124
+ lexical = current[:string_value]
125
+ terminated = current[:terminated]
114
126
  debug("prefixID") {"Defined prefix #{prefix.inspect} mapping to #{iri.inspect}"}
127
+ if lexical.start_with?('@') && lexical != '@prefix'
128
+ error(:prefixID, "should be downcased")
129
+ elsif lexical == '@prefix'
130
+ error(:prefixID, "directive not terminated") unless terminated
131
+ else
132
+ error(:prefixID, "directive should not be terminated") if terminated
133
+ end
115
134
  prefix(prefix, iri)
116
135
  end
117
136
 
118
137
  # [5] base set base_uri
119
138
  production(:base) do |input, current, callback|
120
139
  iri = current[:resource]
140
+ lexical = current[:string_value]
141
+ terminated = current[:terminated]
121
142
  debug("base") {"Defined base as #{iri}"}
143
+ if lexical.start_with?('@') && lexical != '@base'
144
+ error(:base, "should be downcased")
145
+ elsif lexical == '@base'
146
+ error(:base, "directive not terminated") unless terminated
147
+ else
148
+ error(:base, "directive should not be terminated") if terminated
149
+ end
122
150
  options[:base_uri] = iri
123
151
  end
124
152
 
125
- # [6] triples
126
- start_production(:triples) do |input, current, callback|
153
+ # [52s] triplesBlock
154
+ start_production(:triplesBlock) do |input, current, callback|
127
155
  # Note production as triples for blankNodePropertyList
128
156
  # to set :subject instead of :resource
129
157
  current[:triples] = true
130
158
  end
131
- production(:triples) do |input, current, callback|
159
+ production(:triplesBlock) do |input, current, callback|
132
160
  # Note production as triples for blankNodePropertyList
133
161
  # to set :subject instead of :resource
134
162
  current[:triples] = true
@@ -139,7 +167,7 @@ module RDF::TriG
139
167
  input[:predicate] = current[:resource]
140
168
  end
141
169
 
142
- # [10] subject ::= IRIref | BlankNode | collection
170
+ # [10] subject ::= iri | blank
143
171
  start_production(:subject) do |input, current, callback|
144
172
  current[:triples] = nil
145
173
  end
@@ -0,0 +1,42 @@
1
+ module RDF::TriG
2
+ ##
3
+ # Streaming writer interface
4
+ # @author [Gregg Kellogg](http://greggkellogg.net/)
5
+ module StreamingWriter
6
+ ##
7
+ # Write out a statement, retaining current
8
+ # `subject` and `predicate` to create more compact output
9
+ # @return [void] `self`
10
+ def stream_statement(statement)
11
+ if statement.context != @streaming_context
12
+ stream_epilogue
13
+ if statement.context
14
+ @output.write "#{format_term(statement.context)} {"
15
+ end
16
+ @streaming_context, @streaming_subject, @streaming_predicate = statement.context, statement.subject, statement.predicate
17
+ @output.write "#{format_term(statement.subject)} "
18
+ @output.write "#{format_term(statement.predicate)} "
19
+ elsif statement.subject != @streaming_subject
20
+ @output.write " .\n#{indent(@streaming_subject ? 1 : 0)}"
21
+ @streaming_subject, @streaming_predicate = statement.subject, statement.predicate
22
+ @output.write "#{format_term(statement.subject)} "
23
+ @output.write "#{format_term(statement.predicate)} "
24
+ elsif statement.predicate != @streaming_predicate
25
+ @streaming_predicate = statement.predicate
26
+ @output.write ";\n#{indent(@streaming_subject ? 2 : 1)}#{format_term(statement.predicate)} "
27
+ else
28
+ @output.write ",\n#{indent(@streaming_subject ? 3 : 2)}"
29
+ end
30
+ @output.write("#{format_term(statement.object)}")
31
+ end
32
+
33
+ ##
34
+ # Complete open statements
35
+ # @return [void] `self`
36
+ def stream_epilogue
37
+ @output.puts " }" if @streaming_context
38
+ end
39
+
40
+ private
41
+ end
42
+ end
@@ -1,4 +1,5 @@
1
1
  require 'rdf/turtle'
2
+ require 'rdf/trig/streaming_writer'
2
3
 
3
4
  module RDF::TriG
4
5
  ##
@@ -34,6 +35,13 @@ module RDF::TriG
34
35
  # end
35
36
  # end
36
37
  #
38
+ # @example Serializing RDF statements to a string in streaming mode
39
+ # RDF::TriG::Writer.buffer(:stream => true) do |writer|
40
+ # repo.each_statement do |statement|
41
+ # writer << statement
42
+ # end
43
+ # end
44
+ #
37
45
  # The writer will add prefix definitions, and use them for creating @prefix definitions, and minting QNames
38
46
  #
39
47
  # @example Creating @base and @prefix definitions in output
@@ -48,6 +56,7 @@ module RDF::TriG
48
56
  #
49
57
  # @author [Gregg Kellogg](http://greggkellogg.net/)
50
58
  class Writer < RDF::Turtle::Writer
59
+ include StreamingWriter
51
60
  format RDF::TriG::Format
52
61
 
53
62
  class ContextFilteredRepo
@@ -103,6 +112,8 @@ module RDF::TriG
103
112
  # Maximum depth for recursively defining resources, defaults to 3
104
113
  # @option options [Boolean] :standard_prefixes (false)
105
114
  # Add standard prefixes to @prefixes, if necessary.
115
+ # @option options [Boolean] :stream (false)
116
+ # Do not attempt to optimize graph presentation, suitable for streaming large repositories.
106
117
  # @option options [String] :default_namespace (nil)
107
118
  # URI to use as default namespace, same as `prefixes\[nil\]`
108
119
  # @yield [writer] `self`
@@ -111,6 +122,7 @@ module RDF::TriG
111
122
  # @yield [writer]
112
123
  # @yieldparam [RDF::Writer] writer
113
124
  def initialize(output = $stdout, options = {}, &block)
125
+ reset
114
126
  super do
115
127
  # Set both @repo and @graph to a new repository.
116
128
  # When serializing a context, @graph is changed
@@ -125,45 +137,74 @@ module RDF::TriG
125
137
  end
126
138
  end
127
139
 
140
+
141
+ ##
142
+ # Adds a statement to be serialized
143
+ # @param [RDF::Statement] statement
144
+ # @return [void]
145
+ def write_statement(statement)
146
+ case
147
+ when @options[:stream]
148
+ stream_statement(statement)
149
+ else
150
+ super
151
+ end
152
+ end
153
+
154
+ ##
155
+ # Write out declarations
156
+ # @return [void] `self`
157
+ def write_prologue
158
+ case
159
+ when @options[:stream]
160
+ stream_prologue
161
+ else
162
+ super
163
+ end
164
+ end
165
+
128
166
  ##
129
167
  # Outputs the TriG representation of all stored triples.
130
168
  #
131
169
  # @return [void]
132
170
  # @see #write_triple
133
171
  def write_epilogue
134
- @max_depth = @options[:max_depth] || 3
135
- @base_uri = RDF::URI(@options[:base_uri])
172
+ case
173
+ when @options[:stream]
174
+ stream_epilogue
175
+ else
176
+ @max_depth = @options[:max_depth] || 3
177
+ @base_uri = RDF::URI(@options[:base_uri])
136
178
 
137
- reset
179
+ reset
138
180
 
139
- debug {"\nserialize: repo: #{@repo.size}"}
181
+ debug {"\nserialize: repo: #{@repo.size}"}
140
182
 
141
- preprocess
142
- start_document
183
+ preprocess
184
+ start_document
143
185
 
144
- order_contexts.each do |ctx|
145
- debug {"context: #{ctx.inspect}"}
146
- reset
147
- @depth = 2
186
+ order_contexts.each do |ctx|
187
+ debug {"context: #{ctx.inspect}"}
188
+ reset
189
+ @depth = 2
148
190
 
149
- if ctx
150
- @output.write("\n#{format_value(ctx)} {")
151
- else
152
- @output.write("\n{")
153
- end
191
+ if ctx
192
+ @output.write("\n#{format_value(ctx)} {")
193
+ end
154
194
 
155
- # Restrict view to the particular context
156
- @graph = ContextFilteredRepo.new(@repo, ctx)
195
+ # Restrict view to the particular context
196
+ @graph = ContextFilteredRepo.new(@repo, ctx)
157
197
 
158
- # Pre-process statements again, but in the specified context
159
- @graph.each {|st| preprocess_statement(st)}
160
- order_subjects.each do |subject|
161
- unless is_done?(subject)
162
- statement(subject)
198
+ # Pre-process statements again, but in the specified context
199
+ @graph.each {|st| preprocess_statement(st)}
200
+ order_subjects.each do |subject|
201
+ unless is_done?(subject)
202
+ statement(subject)
203
+ end
163
204
  end
164
- end
165
205
 
166
- @output.puts("}")
206
+ @output.puts("}") if ctx
207
+ end
167
208
  end
168
209
  end
169
210
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rdf-trig
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gregg Kellogg
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-05-30 00:00:00.000000000 Z
11
+ date: 2013-09-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rdf
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - ! '>='
46
46
  - !ruby/object:Gem::Version
47
- version: 1.0.7
47
+ version: 1.0.9
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - ! '>='
53
53
  - !ruby/object:Gem::Version
54
- version: 1.0.7
54
+ version: 1.0.9
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: open-uri-cached
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -164,6 +164,7 @@ files:
164
164
  - lib/rdf/trig/format.rb
165
165
  - lib/rdf/trig/meta.rb
166
166
  - lib/rdf/trig/reader.rb
167
+ - lib/rdf/trig/streaming_writer.rb
167
168
  - lib/rdf/trig/version.rb
168
169
  - lib/rdf/trig/writer.rb
169
170
  - lib/rdf/trig.rb
@@ -187,7 +188,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
187
188
  version: '0'
188
189
  requirements: []
189
190
  rubyforge_project: rdf-trig
190
- rubygems_version: 2.0.3
191
+ rubygems_version: 2.0.5
191
192
  signing_key:
192
193
  specification_version: 4
193
194
  summary: TriG reader/writer for Ruby.