rdf-turtle 0.0.4 → 0.0.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.
- data/History +9 -0
- data/README.markdown +1 -0
- data/VERSION +1 -1
- data/lib/rdf/ll1/parser.rb +40 -29
- data/lib/rdf/turtle.rb +1 -1
- data/lib/rdf/turtle/format.rb +5 -5
- data/lib/rdf/turtle/reader.rb +19 -10
- data/lib/rdf/turtle/version.rb +18 -0
- data/lib/rdf/turtle/writer.rb +39 -44
- metadata +114 -52
data/History
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
### 0.0.5
|
2
|
+
* Update turtle and writer specs to use latest version of Turtle specs.
|
3
|
+
* Use Spira Manifest w/list to order tests.
|
4
|
+
* Change debug to use blocks to reduce computation overhead when not doing debugging, results in a reasonable performance boost.
|
5
|
+
|
6
|
+
### 0.0.4
|
7
|
+
* Make an un-defined empty prefix an error, rather than treating it as <>.
|
8
|
+
* Replace remaining uses of SPARQL with RDF::Turtle or RDF::LL1
|
9
|
+
|
1
10
|
### 0.0.3
|
2
11
|
* Completed RDF 1.1 Turtle based on http://www.w3.org/TR/2011/WD-turtle-20110809/
|
3
12
|
* Reader
|
data/README.markdown
CHANGED
@@ -130,6 +130,7 @@ see <http://unlicense.org/> or the accompanying {file:UNLICENSE} file.
|
|
130
130
|
[PDD]: http://lists.w3.org/Archives/Public/public-rdf-ruby/2010May/0013.html
|
131
131
|
[RDF.rb]: http://rdf.rubyforge.org/
|
132
132
|
[Backports]: http://rubygems.org/gems/backports
|
133
|
+
[N-Triples]: http://www.w3.org/TR/rdf-testcases/#ntriples
|
133
134
|
[Turtle]: http://www.w3.org/TR/2011/WD-turtle-20110809/
|
134
135
|
[Turtle doc]: http://rubydoc.info/github/gkellogg/rdf-turtle/master/file/README.markdown
|
135
136
|
[Turtle EBNF]: http://www.w3.org/2000/10/swap/grammar/turtle.bnf
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.5
|
data/lib/rdf/ll1/parser.rb
CHANGED
@@ -75,7 +75,7 @@ module RDF::LL1
|
|
75
75
|
@patterns ||= []
|
76
76
|
@patterns << [term, regexp] # Passed in order to define evaulation sequence
|
77
77
|
@terminal_handlers ||= {}
|
78
|
-
@terminal_handlers[term] = block
|
78
|
+
@terminal_handlers[term] = block if block_given?
|
79
79
|
@unescape_terms ||= []
|
80
80
|
@unescape_terms << term if options[:unescape]
|
81
81
|
end
|
@@ -187,10 +187,11 @@ module RDF::LL1
|
|
187
187
|
token = @lexer.recover
|
188
188
|
end
|
189
189
|
@lineno = token.lineno if token
|
190
|
-
debug("parse(production)"
|
191
|
-
|
192
|
-
|
193
|
-
|
190
|
+
debug("parse(production)") do
|
191
|
+
"#{token ? token.representation.inspect : 'nil'}, " +
|
192
|
+
"prod #{todo_stack.last[:prod].inspect}, " +
|
193
|
+
"depth #{depth}"
|
194
|
+
end
|
194
195
|
|
195
196
|
# Got an opened production
|
196
197
|
cur_prod = todo_stack.last[:prod]
|
@@ -200,14 +201,15 @@ module RDF::LL1
|
|
200
201
|
|
201
202
|
if prod_branch = @branch[cur_prod]
|
202
203
|
sequence = prod_branch[token.representation]
|
203
|
-
debug("parse(production)"
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
204
|
+
debug("parse(production)") do
|
205
|
+
"#{token.representation.inspect} " +
|
206
|
+
"prod #{cur_prod.inspect}, " +
|
207
|
+
"prod_branch #{prod_branch.keys.inspect}, " +
|
208
|
+
"sequence #{sequence.inspect}"
|
209
|
+
end
|
208
210
|
if sequence.nil?
|
209
211
|
if prod_branch.has_key?(:"ebnf:empty")
|
210
|
-
debug("parse(production)"
|
212
|
+
debug("parse(production)") {"empty sequence for ebnf:empty"}
|
211
213
|
else
|
212
214
|
expected = prod_branch.keys.map {|v| v.inspect}.join(", ")
|
213
215
|
error("parse", "expected one of #{expected}",
|
@@ -227,13 +229,13 @@ module RDF::LL1
|
|
227
229
|
end
|
228
230
|
end
|
229
231
|
|
230
|
-
debug("parse(terms)"
|
232
|
+
debug("parse(terms)") {"todo #{todo_stack.last.inspect}, depth #{depth}"}
|
231
233
|
while !todo_stack.last[:terms].to_a.empty?
|
232
234
|
begin
|
233
235
|
# Get the next term in this sequence
|
234
236
|
term = todo_stack.last[:terms].shift
|
235
237
|
if token = accept(term)
|
236
|
-
debug("parse(token)"
|
238
|
+
debug("parse(token)") {"#{token.inspect}, term #{term.inspect}"}
|
237
239
|
@lineno = token.lineno if token
|
238
240
|
onToken(term, token)
|
239
241
|
elsif terminals.include?(term)
|
@@ -245,7 +247,7 @@ module RDF::LL1
|
|
245
247
|
else
|
246
248
|
# If it's not a string (a symbol), it is a non-terminal and we push the new state
|
247
249
|
todo_stack << {:prod => term, :terms => nil}
|
248
|
-
debug("parse(push)"
|
250
|
+
debug("parse(push)") {"term #{term.inspect}, depth #{depth}"}
|
249
251
|
pushed = true
|
250
252
|
break
|
251
253
|
end
|
@@ -264,7 +266,7 @@ module RDF::LL1
|
|
264
266
|
!todo_stack.empty? &&
|
265
267
|
( todo_stack.last[:terms].to_a.empty? ||
|
266
268
|
(@recovering && @follow[todo_stack.last[:term]].nil?))
|
267
|
-
debug("parse(pop)"
|
269
|
+
debug("parse(pop)") {"todo #{todo_stack.last.inspect}, depth #{depth}, recovering? #{@recovering.inspect}"}
|
268
270
|
prod = todo_stack.last[:prod]
|
269
271
|
@recovering = false if @follow[prod] # Stop recovering when we might have a match
|
270
272
|
todo_stack.pop
|
@@ -276,7 +278,7 @@ module RDF::LL1
|
|
276
278
|
|
277
279
|
# Continue popping contexts off of the stack
|
278
280
|
while !todo_stack.empty?
|
279
|
-
debug("parse(eof)"
|
281
|
+
debug("parse(eof)") {"stack #{todo_stack.last.inspect}, depth #{depth}"}
|
280
282
|
todo_stack.pop
|
281
283
|
onFinish
|
282
284
|
end
|
@@ -297,7 +299,7 @@ module RDF::LL1
|
|
297
299
|
if handler
|
298
300
|
# Create a new production data element, potentially allowing handler
|
299
301
|
# to customize before pushing on the @prod_data stack
|
300
|
-
progress("#{prod}(:start):#{@prod_data.length}"
|
302
|
+
progress("#{prod}(:start):#{@prod_data.length}") {@prod_data.last}
|
301
303
|
data = {}
|
302
304
|
handler.call(self, :start, @prod_data.last, data, @parse_callback)
|
303
305
|
@prod_data << data
|
@@ -315,7 +317,7 @@ module RDF::LL1
|
|
315
317
|
# Pop production data element from stack, potentially allowing handler to use it
|
316
318
|
data = @prod_data.pop
|
317
319
|
handler.call(self, :finish, @prod_data.last, data, @parse_callback)
|
318
|
-
progress("#{prod}(:finish):#{@prod_data.length}"
|
320
|
+
progress("#{prod}(:finish):#{@prod_data.length}") {@prod_data.last}
|
319
321
|
else
|
320
322
|
progress("#{prod}(:finish)", '')
|
321
323
|
end
|
@@ -330,9 +332,9 @@ module RDF::LL1
|
|
330
332
|
handler ||= self.class.terminal_handlers[nil] if prod.is_a?(String) # Allows catch-all for simple string terminals
|
331
333
|
if handler
|
332
334
|
handler.call(self, parentProd, token, @prod_data.last)
|
333
|
-
progress("#{prod}(:token)", "
|
335
|
+
progress("#{prod}(:token)", "", :depth => (depth + 1)) {"#{token}: #{@prod_data.last}"}
|
334
336
|
else
|
335
|
-
progress("#{prod}(:token)",
|
337
|
+
progress("#{prod}(:token)", "", :depth => (depth + 1)) {token.to_s}
|
336
338
|
end
|
337
339
|
else
|
338
340
|
error("#{parentProd}(:token)", "Token has no parent production", :production => prod)
|
@@ -343,16 +345,16 @@ module RDF::LL1
|
|
343
345
|
def skip_until_follow(todo_stack)
|
344
346
|
debug("recovery", "stack follows:")
|
345
347
|
todo_stack.each do |todo|
|
346
|
-
debug("recovery"
|
348
|
+
debug("recovery") {" #{todo[:prod]}: #{@follow[todo[:prod]].inspect}"}
|
347
349
|
end
|
348
350
|
follows = todo_stack.inject([]) do |follow, todo|
|
349
351
|
prod = todo[:prod]
|
350
352
|
follow += @follow[prod] || []
|
351
353
|
end.uniq
|
352
|
-
progress("recovery"
|
354
|
+
progress("recovery") {"first #{@lexer.first.inspect}, follows: #{follows.inspect}"}
|
353
355
|
while (token = @lexer.first) && follows.none? {|t| token === t}
|
354
356
|
skipped = @lexer.shift
|
355
|
-
progress("recovery"
|
357
|
+
progress("recovery") {"skip #{skipped.inspect}"}
|
356
358
|
end
|
357
359
|
end
|
358
360
|
|
@@ -375,11 +377,17 @@ module RDF::LL1
|
|
375
377
|
|
376
378
|
##
|
377
379
|
# Progress output when parsing
|
378
|
-
# @param [String]
|
379
|
-
|
380
|
+
# @param [String] node Relevant location associated with message
|
381
|
+
# @param [String] message ("")
|
382
|
+
# @param [Hash] options
|
383
|
+
# @option options [Integer] :depth
|
384
|
+
# Recursion depth for indenting output
|
385
|
+
# @yieldreturn [String] added to message
|
386
|
+
def progress(node, message = "", options = {})
|
380
387
|
return debug(node, message, options) if @options[:debug]
|
381
388
|
return unless @options[:progress]
|
382
389
|
depth = options[:depth] || self.depth
|
390
|
+
message += yield if block_given?
|
383
391
|
str = "[#{@lineno}]#{' ' * depth}#{node}: #{message}"
|
384
392
|
$stderr.puts("[#{@lineno}]#{' ' * depth}#{node}: #{message}")
|
385
393
|
end
|
@@ -387,12 +395,15 @@ module RDF::LL1
|
|
387
395
|
##
|
388
396
|
# Progress output when debugging
|
389
397
|
# @param [String] node Relevant location associated with message
|
390
|
-
# @param [String] message
|
398
|
+
# @param [String] message ("")
|
391
399
|
# @param [Hash] options
|
392
400
|
# @option options [Integer] :depth
|
393
401
|
# Recursion depth for indenting output
|
394
|
-
|
402
|
+
# @yieldreturn [String] added to message
|
403
|
+
def debug(node, message = "", options = {})
|
404
|
+
return unless @options[:debug]
|
395
405
|
depth = options[:depth] || self.depth
|
406
|
+
message += yield if block_given?
|
396
407
|
str = "[#{@lineno}]#{' ' * depth}#{node}: #{message}"
|
397
408
|
case @options[:debug]
|
398
409
|
when Array
|
@@ -400,7 +411,7 @@ module RDF::LL1
|
|
400
411
|
when TrueClass
|
401
412
|
$stderr.puts str
|
402
413
|
when :yield
|
403
|
-
@parse_callback.call(:
|
414
|
+
@parse_callback.call(:trace, node, message, options)
|
404
415
|
end
|
405
416
|
end
|
406
417
|
|
@@ -409,7 +420,7 @@ module RDF::LL1
|
|
409
420
|
# @return [Token]
|
410
421
|
def accept(type_or_value)
|
411
422
|
if (token = @lexer.first) && token === type_or_value
|
412
|
-
debug("accept"
|
423
|
+
debug("accept") {"#{token.inspect} === #{type_or_value}.inspect"}
|
413
424
|
@lexer.shift
|
414
425
|
end
|
415
426
|
end
|
data/lib/rdf/turtle.rb
CHANGED
@@ -7,7 +7,7 @@ module RDF
|
|
7
7
|
# @example Requiring the `RDF::Turtle` module
|
8
8
|
# require 'rdf/turtle'
|
9
9
|
#
|
10
|
-
# @example Parsing RDF statements from an
|
10
|
+
# @example Parsing RDF statements from an Turtle file
|
11
11
|
# RDF::Turtle::Reader.open("etc/foaf.ttl") do |reader|
|
12
12
|
# reader.each_statement do |statement|
|
13
13
|
# puts statement.inspect
|
data/lib/rdf/turtle/format.rb
CHANGED
@@ -2,14 +2,14 @@ module RDF::Turtle
|
|
2
2
|
##
|
3
3
|
# RDFa format specification.
|
4
4
|
#
|
5
|
-
# @example Obtaining an
|
5
|
+
# @example Obtaining an Turtle format class
|
6
6
|
# RDF::Format.for("etc/foaf.ttl")
|
7
7
|
# RDF::Format.for(:file_name => "etc/foaf.ttl")
|
8
8
|
# RDF::Format.for(:file_extension => "ttl")
|
9
9
|
# RDF::Format.for(:content_type => "text/turtle")
|
10
10
|
#
|
11
11
|
# @example Obtaining serialization format MIME types
|
12
|
-
# RDF::Format.content_types #=> {"text/turtle" => [RDF::
|
12
|
+
# RDF::Format.content_types #=> {"text/turtle" => [RDF::Turtle::Format]}
|
13
13
|
#
|
14
14
|
# @example Obtaining serialization format file extension mappings
|
15
15
|
# RDF::Format.file_extensions #=> {:ttl => "text/turtle"}
|
@@ -31,9 +31,9 @@ module RDF::Turtle
|
|
31
31
|
# This allows the following:
|
32
32
|
#
|
33
33
|
# @example Obtaining an TTL format class
|
34
|
-
# RDF::Format.for(:ttl) # RDF::
|
35
|
-
# RDF::Format.for(:ttl).reader # RDF::
|
36
|
-
# RDF::Format.for(:ttl).writer # RDF::
|
34
|
+
# RDF::Format.for(:ttl) # RDF::Turtle::TTL
|
35
|
+
# RDF::Format.for(:ttl).reader # RDF::Turtle::Reader
|
36
|
+
# RDF::Format.for(:ttl).writer # RDF::Turtle::Writer
|
37
37
|
class TTL < RDF::Format
|
38
38
|
reader { RDF::Turtle::Reader }
|
39
39
|
writer { RDF::Turtle::Writer }
|
data/lib/rdf/turtle/reader.rb
CHANGED
@@ -180,7 +180,7 @@ module RDF::Turtle
|
|
180
180
|
end
|
181
181
|
|
182
182
|
##
|
183
|
-
# Initializes a new
|
183
|
+
# Initializes a new reader instance.
|
184
184
|
#
|
185
185
|
# @param [String, #to_s] input
|
186
186
|
# @param [Hash{Symbol => Object}] options
|
@@ -206,11 +206,11 @@ module RDF::Turtle
|
|
206
206
|
super do
|
207
207
|
@options = {:anon_base => "b0", :validate => false}.merge(options)
|
208
208
|
|
209
|
-
debug("def prefix"
|
209
|
+
debug("def prefix") {base_uri.inspect}
|
210
210
|
|
211
|
-
debug("validate"
|
212
|
-
debug("canonicalize"
|
213
|
-
debug("intern"
|
211
|
+
debug("validate") {validate?.inspect}
|
212
|
+
debug("canonicalize") {canonicalize?.inspect}
|
213
|
+
debug("intern") {intern?.inspect}
|
214
214
|
|
215
215
|
if block_given?
|
216
216
|
case block.arity
|
@@ -271,7 +271,7 @@ module RDF::Turtle
|
|
271
271
|
def add_triple(node, subject, predicate, object)
|
272
272
|
statement = RDF::Statement.new(subject, predicate, object)
|
273
273
|
if statement.valid?
|
274
|
-
debug(node
|
274
|
+
debug(node) {"generate statement: #{statement}"}
|
275
275
|
@callback.call(statement)
|
276
276
|
else
|
277
277
|
error(node, "Statement is invalid: #{statement.inspect}")
|
@@ -297,7 +297,12 @@ module RDF::Turtle
|
|
297
297
|
options = options.dup
|
298
298
|
# Internal representation is to not use xsd:string, although it could arguably go the other way.
|
299
299
|
options.delete(:datatype) if options[:datatype] == RDF::XSD.string
|
300
|
-
debug("literal"
|
300
|
+
debug("literal") do
|
301
|
+
"value: #{value.inspect}, " +
|
302
|
+
"options: #{options.inspect}, " +
|
303
|
+
"validate: #{validate?.inspect}, " +
|
304
|
+
"c14n?: #{canonicalize?.inspect}"
|
305
|
+
end
|
301
306
|
RDF::Literal.new(value, options.merge(:validate => validate?, :canonicalize => canonicalize?))
|
302
307
|
end
|
303
308
|
|
@@ -324,7 +329,7 @@ module RDF::Turtle
|
|
324
329
|
base = ''
|
325
330
|
end
|
326
331
|
suffix = suffix.to_s.sub(/^\#/, "") if base.index("#")
|
327
|
-
debug("pname"
|
332
|
+
debug("pname") {"base: '#{base}', suffix: '#{suffix}'"}
|
328
333
|
process_iri(base + suffix.to_s)
|
329
334
|
end
|
330
335
|
|
@@ -349,9 +354,13 @@ module RDF::Turtle
|
|
349
354
|
|
350
355
|
##
|
351
356
|
# Progress output when debugging
|
352
|
-
# @param [String]
|
353
|
-
|
357
|
+
# @param [String] node relative location in input
|
358
|
+
# @param [String] message ("")
|
359
|
+
# @yieldreturn [String] added to message
|
360
|
+
def debug(node, message = "", options = {})
|
361
|
+
return unless @options[:debug] || RDF::Turtle.debug?
|
354
362
|
depth = options[:depth] || self.depth
|
363
|
+
message += yield if block_given?
|
355
364
|
str = "[#{@lineno}]#{' ' * depth}#{node}: #{message}"
|
356
365
|
@options[:debug] << str if @options[:debug].is_a?(Array)
|
357
366
|
$stderr.puts(str) if RDF::Turtle.debug?
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module RDF::Turtle::VERSION
|
2
|
+
VERSION_FILE = File.join(File.expand_path(File.dirname(__FILE__)), "..", "..", "..", "VERSION")
|
3
|
+
MAJOR, MINOR, TINY, EXTRA = File.read(VERSION_FILE).chop.split(".")
|
4
|
+
|
5
|
+
STRING = [MAJOR, MINOR, TINY, EXTRA].compact.join('.')
|
6
|
+
|
7
|
+
##
|
8
|
+
# @return [String]
|
9
|
+
def self.to_s() STRING end
|
10
|
+
|
11
|
+
##
|
12
|
+
# @return [String]
|
13
|
+
def self.to_str() STRING end
|
14
|
+
|
15
|
+
##
|
16
|
+
# @return [Array(Integer, Integer, Integer)]
|
17
|
+
def self.to_a() STRING.split(".") end
|
18
|
+
end
|
data/lib/rdf/turtle/writer.rb
CHANGED
@@ -9,23 +9,19 @@ module RDF::Turtle
|
|
9
9
|
# and then serialize the graph.
|
10
10
|
#
|
11
11
|
# @example Obtaining a Turtle writer class
|
12
|
-
# RDF::Writer.for(:
|
13
|
-
# RDF::Writer.for("etc/test.n3")
|
12
|
+
# RDF::Writer.for(:ttl) #=> RDF::Turtle::Writer
|
14
13
|
# RDF::Writer.for("etc/test.ttl")
|
15
|
-
# RDF::Writer.for(:file_name => "etc/test.n3")
|
16
14
|
# RDF::Writer.for(:file_name => "etc/test.ttl")
|
17
|
-
# RDF::Writer.for(:file_extension => "n3")
|
18
15
|
# RDF::Writer.for(:file_extension => "ttl")
|
19
|
-
# RDF::Writer.for(:content_type => "text/n3")
|
20
16
|
# RDF::Writer.for(:content_type => "text/turtle")
|
21
17
|
#
|
22
18
|
# @example Serializing RDF graph into an Turtle file
|
23
|
-
# RDF::Turtle::Writer.open("etc/test.
|
19
|
+
# RDF::Turtle::Writer.open("etc/test.ttl") do |writer|
|
24
20
|
# writer << graph
|
25
21
|
# end
|
26
22
|
#
|
27
23
|
# @example Serializing RDF statements into an Turtle file
|
28
|
-
# RDF::Turtle::Writer.open("etc/test.
|
24
|
+
# RDF::Turtle::Writer.open("etc/test.ttl") do |writer|
|
29
25
|
# graph.each_statement do |statement|
|
30
26
|
# writer << statement
|
31
27
|
# end
|
@@ -136,11 +132,10 @@ module RDF::Turtle
|
|
136
132
|
def write_epilogue
|
137
133
|
@max_depth = @options[:max_depth] || 3
|
138
134
|
@base_uri = RDF::URI(@options[:base_uri])
|
139
|
-
@debug = @options[:debug]
|
140
135
|
|
141
136
|
self.reset
|
142
137
|
|
143
|
-
|
138
|
+
debug {"\nserialize: graph: #{@graph.size}"}
|
144
139
|
|
145
140
|
preprocess
|
146
141
|
start_document
|
@@ -172,13 +167,13 @@ module RDF::Turtle
|
|
172
167
|
# Use a defined prefix
|
173
168
|
prefix = @uri_to_prefix[u]
|
174
169
|
prefix(prefix, u) unless u.to_s.empty? # Define for output
|
175
|
-
|
170
|
+
debug {"get_pname: add prefix #{prefix.inspect} => #{u}"}
|
176
171
|
uri.sub(u.to_s, "#{prefix}:")
|
177
172
|
when @options[:standard_prefixes] && vocab = RDF::Vocabulary.each.to_a.detect {|v| uri.index(v.to_uri.to_s) == 0}
|
178
173
|
prefix = vocab.__name__.to_s.split('::').last.downcase
|
179
174
|
@uri_to_prefix[vocab.to_uri.to_s] = prefix
|
180
175
|
prefix(prefix, vocab.to_uri) # Define for output
|
181
|
-
|
176
|
+
debug {"get_pname: add standard prefix #{prefix.inspect} => #{vocab.to_uri}"}
|
182
177
|
uri.sub(vocab.to_uri.to_s, "#{prefix}:")
|
183
178
|
else
|
184
179
|
nil
|
@@ -200,20 +195,11 @@ module RDF::Turtle
|
|
200
195
|
# @param [Hash{String => Array<Resource>}] properties A hash of Property to Resource mappings
|
201
196
|
# @return [Array<String>}] Ordered list of properties. Uses predicate_order.
|
202
197
|
def sort_properties(properties)
|
203
|
-
properties.keys.each do |k|
|
204
|
-
properties[k] = properties[k].sort do |a, b|
|
205
|
-
a_li = a.to_s.index(RDF._.to_s) == 0 ? a.to_s.match(/\d+$/).to_s.to_i : a.to_s
|
206
|
-
b_li = b.to_s.index(RDF._.to_s) == 0 ? b.to_s.match(/\d+$/).to_s.to_i : b.to_s
|
207
|
-
|
208
|
-
a_li <=> b_li
|
209
|
-
end
|
210
|
-
end
|
211
|
-
|
212
198
|
# Make sorted list of properties
|
213
199
|
prop_list = []
|
214
200
|
|
215
201
|
predicate_order.each do |prop|
|
216
|
-
next unless properties[prop]
|
202
|
+
next unless properties[prop.to_s]
|
217
203
|
prop_list << prop.to_s
|
218
204
|
end
|
219
205
|
|
@@ -222,7 +208,7 @@ module RDF::Turtle
|
|
222
208
|
prop_list << prop.to_s
|
223
209
|
end
|
224
210
|
|
225
|
-
|
211
|
+
debug {"sort_properties: #{prop_list.join(', ')}"}
|
226
212
|
prop_list
|
227
213
|
end
|
228
214
|
|
@@ -260,7 +246,7 @@ module RDF::Turtle
|
|
260
246
|
# @return [String]
|
261
247
|
def format_uri(uri, options = {})
|
262
248
|
md = relativize(uri)
|
263
|
-
|
249
|
+
debug {"relativize(#{uri.inspect}) => #{md.inspect}"} if md != uri.to_s
|
264
250
|
md != uri.to_s ? "<#{md}>" : (get_pname(uri) || "<#{uri}>")
|
265
251
|
end
|
266
252
|
|
@@ -281,7 +267,7 @@ module RDF::Turtle
|
|
281
267
|
|
282
268
|
@output.write("#{indent}@base <#{@base_uri}> .\n") unless @base_uri.to_s.empty?
|
283
269
|
|
284
|
-
|
270
|
+
debug {"start_document: #{prefixes.inspect}"}
|
285
271
|
prefixes.keys.sort_by(&:to_s).each do |prefix|
|
286
272
|
@output.write("#{indent}@prefix #{prefix}: <#{prefixes[prefix]}> .\n")
|
287
273
|
end
|
@@ -321,7 +307,7 @@ module RDF::Turtle
|
|
321
307
|
# Add distinguished classes
|
322
308
|
top_classes.each do |class_uri|
|
323
309
|
graph.query(:predicate => RDF.type, :object => class_uri).map {|st| st.subject}.sort.uniq.each do |subject|
|
324
|
-
|
310
|
+
debug {"order_subjects: #{subject.inspect}"}
|
325
311
|
subjects << subject
|
326
312
|
seen[subject] = true
|
327
313
|
end
|
@@ -353,7 +339,7 @@ module RDF::Turtle
|
|
353
339
|
# prefixes.
|
354
340
|
# @param [Statement] statement
|
355
341
|
def preprocess_statement(statement)
|
356
|
-
#
|
342
|
+
#debug {"preprocess: #{statement.inspect}"}
|
357
343
|
references = ref_count(statement.object) + 1
|
358
344
|
@references[statement.object] = references
|
359
345
|
@subjects[statement.subject] = true
|
@@ -408,27 +394,30 @@ module RDF::Turtle
|
|
408
394
|
|
409
395
|
private
|
410
396
|
|
397
|
+
##
|
411
398
|
# Add debug event to debug array, if specified
|
412
|
-
#
|
413
|
-
# @
|
414
|
-
def
|
415
|
-
|
416
|
-
|
399
|
+
# @param [String] message ("")
|
400
|
+
# @yieldreturn [String] added to message
|
401
|
+
def debug(message = "", options = {})
|
402
|
+
return unless @options[:debug] || RDF::Turtle.debug?
|
403
|
+
message += yield if block_given?
|
404
|
+
@options[:debug] << message if @options[:debug].is_a?(Array)
|
405
|
+
$stderr.puts(message) if RDF::Turtle.debug?
|
417
406
|
end
|
418
407
|
|
419
408
|
# Checks if l is a valid RDF list, i.e. no nodes have other properties.
|
420
409
|
def is_valid_list(l)
|
421
|
-
#
|
410
|
+
#debug {"is_valid_list: #{l.inspect}"}
|
422
411
|
return RDF::List.new(l, @graph).valid?
|
423
412
|
end
|
424
413
|
|
425
414
|
def do_list(l)
|
426
415
|
list = RDF::List.new(l, @graph)
|
427
|
-
|
416
|
+
debug {"do_list: #{list.inspect}"}
|
428
417
|
position = :subject
|
429
418
|
list.each_statement do |st|
|
430
419
|
next unless st.predicate == RDF.first
|
431
|
-
|
420
|
+
debug {" list this: #{st.subject} first: #{st.object}[#{position}]"}
|
432
421
|
path(st.object, position)
|
433
422
|
subject_done(st.subject)
|
434
423
|
position = :object
|
@@ -437,7 +426,7 @@ module RDF::Turtle
|
|
437
426
|
|
438
427
|
def p_list(node, position)
|
439
428
|
return false if !is_valid_list(node)
|
440
|
-
#
|
429
|
+
#debug {"p_list: #{node.inspect}, #{position}"}
|
441
430
|
|
442
431
|
@output.write(position == :subject ? "(" : " (")
|
443
432
|
@depth += 2
|
@@ -455,7 +444,7 @@ module RDF::Turtle
|
|
455
444
|
def p_squared(node, position)
|
456
445
|
return false unless p_squared?(node, position)
|
457
446
|
|
458
|
-
#
|
447
|
+
#debug {"p_squared: #{node.inspect}, #{position}"}
|
459
448
|
subject_done(node)
|
460
449
|
@output.write(position == :subject ? '[' : ' [')
|
461
450
|
@depth += 2
|
@@ -467,18 +456,24 @@ module RDF::Turtle
|
|
467
456
|
end
|
468
457
|
|
469
458
|
def p_default(node, position)
|
470
|
-
#
|
459
|
+
#debug {"p_default: #{node.inspect}, #{position}"}
|
471
460
|
l = (position == :subject ? "" : " ") + format_value(node)
|
472
461
|
@output.write(l)
|
473
462
|
end
|
474
463
|
|
475
464
|
def path(node, position)
|
476
|
-
|
465
|
+
debug do
|
466
|
+
"path: #{node.inspect}, " +
|
467
|
+
"pos: #{position}, " +
|
468
|
+
"[]: #{is_valid_list(node)}, " +
|
469
|
+
"p2?: #{p_squared?(node, position)}, " +
|
470
|
+
"rc: #{ref_count(node)}"
|
471
|
+
end
|
477
472
|
raise RDF::WriterError, "Cannot serialize node '#{node}'" unless p_list(node, position) || p_squared(node, position) || p_default(node, position)
|
478
473
|
end
|
479
474
|
|
480
475
|
def verb(node)
|
481
|
-
|
476
|
+
debug {"verb: #{node.inspect}"}
|
482
477
|
if node == RDF.type
|
483
478
|
@output.write(" a")
|
484
479
|
else
|
@@ -487,7 +482,7 @@ module RDF::Turtle
|
|
487
482
|
end
|
488
483
|
|
489
484
|
def object_list(objects)
|
490
|
-
|
485
|
+
debug {"object_list: #{objects.inspect}"}
|
491
486
|
return if objects.empty?
|
492
487
|
|
493
488
|
objects.each_with_index do |obj, i|
|
@@ -504,7 +499,7 @@ module RDF::Turtle
|
|
504
499
|
end
|
505
500
|
|
506
501
|
prop_list = sort_properties(properties) - [RDF.first.to_s, RDF.rest.to_s]
|
507
|
-
|
502
|
+
debug {"predicate_list: #{prop_list.inspect}"}
|
508
503
|
return if prop_list.empty?
|
509
504
|
|
510
505
|
prop_list.each_with_index do |prop, i|
|
@@ -514,7 +509,7 @@ module RDF::Turtle
|
|
514
509
|
verb(prop[0, 2] == "_:" ? RDF::Node.new(prop.split(':').last) : RDF::URI.intern(prop))
|
515
510
|
object_list(properties[prop])
|
516
511
|
rescue Addressable::URI::InvalidURIError => e
|
517
|
-
|
512
|
+
debug {"Predicate #{prop.inspect} is an invalid URI: #{e.message}"}
|
518
513
|
end
|
519
514
|
end
|
520
515
|
end
|
@@ -526,7 +521,7 @@ module RDF::Turtle
|
|
526
521
|
def s_squared(subject)
|
527
522
|
return false unless s_squared?(subject)
|
528
523
|
|
529
|
-
|
524
|
+
debug {"s_squared: #{subject.inspect}"}
|
530
525
|
@output.write("\n#{indent} [")
|
531
526
|
@depth += 1
|
532
527
|
predicate_list(subject)
|
@@ -544,7 +539,7 @@ module RDF::Turtle
|
|
544
539
|
end
|
545
540
|
|
546
541
|
def statement(subject)
|
547
|
-
|
542
|
+
debug {"statement: #{subject.inspect}, s2?: #{s_squared?(subject)}"}
|
548
543
|
subject_done(subject)
|
549
544
|
s_squared(subject) || s_default(subject)
|
550
545
|
@output.puts
|
metadata
CHANGED
@@ -1,77 +1,127 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: rdf-turtle
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 21
|
5
5
|
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 5
|
10
|
+
version: 0.0.5
|
6
11
|
platform: ruby
|
7
|
-
authors:
|
12
|
+
authors:
|
8
13
|
- Gregg Kellogg
|
9
14
|
autorequire:
|
10
15
|
bindir: bin
|
11
16
|
cert_chain: []
|
12
|
-
|
13
|
-
|
14
|
-
|
17
|
+
|
18
|
+
date: 2011-09-04 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
15
21
|
name: rdf
|
16
|
-
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
17
24
|
none: false
|
18
|
-
requirements:
|
19
|
-
- -
|
20
|
-
- !ruby/object:Gem::Version
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 21
|
29
|
+
segments:
|
30
|
+
- 0
|
31
|
+
- 3
|
32
|
+
- 3
|
21
33
|
version: 0.3.3
|
22
34
|
type: :runtime
|
23
|
-
|
24
|
-
|
25
|
-
- !ruby/object:Gem::Dependency
|
35
|
+
version_requirements: *id001
|
36
|
+
- !ruby/object:Gem::Dependency
|
26
37
|
name: yard
|
27
|
-
|
38
|
+
prerelease: false
|
39
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
28
40
|
none: false
|
29
|
-
requirements:
|
30
|
-
- -
|
31
|
-
- !ruby/object:Gem::Version
|
41
|
+
requirements:
|
42
|
+
- - ">="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
hash: 7
|
45
|
+
segments:
|
46
|
+
- 0
|
47
|
+
- 6
|
48
|
+
- 0
|
32
49
|
version: 0.6.0
|
33
50
|
type: :development
|
34
|
-
|
35
|
-
|
36
|
-
- !ruby/object:Gem::Dependency
|
51
|
+
version_requirements: *id002
|
52
|
+
- !ruby/object:Gem::Dependency
|
37
53
|
name: rspec
|
38
|
-
|
54
|
+
prerelease: false
|
55
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
39
56
|
none: false
|
40
|
-
requirements:
|
41
|
-
- -
|
42
|
-
- !ruby/object:Gem::Version
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
hash: 27
|
61
|
+
segments:
|
62
|
+
- 2
|
63
|
+
- 5
|
64
|
+
- 0
|
43
65
|
version: 2.5.0
|
44
66
|
type: :development
|
67
|
+
version_requirements: *id003
|
68
|
+
- !ruby/object:Gem::Dependency
|
69
|
+
name: rdf-n3
|
45
70
|
prerelease: false
|
46
|
-
|
47
|
-
|
71
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
hash: 25
|
77
|
+
segments:
|
78
|
+
- 0
|
79
|
+
- 3
|
80
|
+
- 5
|
81
|
+
version: 0.3.5
|
82
|
+
type: :development
|
83
|
+
version_requirements: *id004
|
84
|
+
- !ruby/object:Gem::Dependency
|
48
85
|
name: rdf-spec
|
49
|
-
|
86
|
+
prerelease: false
|
87
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
50
88
|
none: false
|
51
|
-
requirements:
|
52
|
-
- -
|
53
|
-
- !ruby/object:Gem::Version
|
89
|
+
requirements:
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
hash: 23
|
93
|
+
segments:
|
94
|
+
- 0
|
95
|
+
- 3
|
96
|
+
- 2
|
54
97
|
version: 0.3.2
|
55
98
|
type: :development
|
56
|
-
|
57
|
-
|
58
|
-
- !ruby/object:Gem::Dependency
|
99
|
+
version_requirements: *id005
|
100
|
+
- !ruby/object:Gem::Dependency
|
59
101
|
name: rdf-isomorphic
|
60
|
-
|
102
|
+
prerelease: false
|
103
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
61
104
|
none: false
|
62
|
-
requirements:
|
63
|
-
- -
|
64
|
-
- !ruby/object:Gem::Version
|
105
|
+
requirements:
|
106
|
+
- - ">="
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
hash: 27
|
109
|
+
segments:
|
110
|
+
- 0
|
111
|
+
- 3
|
112
|
+
- 4
|
65
113
|
version: 0.3.4
|
66
114
|
type: :development
|
67
|
-
|
68
|
-
version_requirements: *2168940140
|
115
|
+
version_requirements: *id006
|
69
116
|
description: Turtle reader/writer for Ruby.
|
70
117
|
email: public-rdf-ruby@w3.org
|
71
118
|
executables: []
|
119
|
+
|
72
120
|
extensions: []
|
121
|
+
|
73
122
|
extra_rdoc_files: []
|
74
|
-
|
123
|
+
|
124
|
+
files:
|
75
125
|
- AUTHORS
|
76
126
|
- README.markdown
|
77
127
|
- History
|
@@ -85,31 +135,43 @@ files:
|
|
85
135
|
- lib/rdf/turtle/patches.rb
|
86
136
|
- lib/rdf/turtle/reader.rb
|
87
137
|
- lib/rdf/turtle/terminals.rb
|
138
|
+
- lib/rdf/turtle/version.rb
|
88
139
|
- lib/rdf/turtle/writer.rb
|
89
140
|
- lib/rdf/turtle.rb
|
90
141
|
homepage: http://github.com/gkellogg/rdf-turtle
|
91
|
-
licenses:
|
142
|
+
licenses:
|
92
143
|
- Public Domain
|
93
144
|
post_install_message:
|
94
145
|
rdoc_options: []
|
95
|
-
|
146
|
+
|
147
|
+
require_paths:
|
96
148
|
- lib
|
97
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
149
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
98
150
|
none: false
|
99
|
-
requirements:
|
100
|
-
- -
|
101
|
-
- !ruby/object:Gem::Version
|
151
|
+
requirements:
|
152
|
+
- - ">="
|
153
|
+
- !ruby/object:Gem::Version
|
154
|
+
hash: 53
|
155
|
+
segments:
|
156
|
+
- 1
|
157
|
+
- 8
|
158
|
+
- 1
|
102
159
|
version: 1.8.1
|
103
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
160
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
104
161
|
none: false
|
105
|
-
requirements:
|
106
|
-
- -
|
107
|
-
- !ruby/object:Gem::Version
|
108
|
-
|
162
|
+
requirements:
|
163
|
+
- - ">="
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
hash: 3
|
166
|
+
segments:
|
167
|
+
- 0
|
168
|
+
version: "0"
|
109
169
|
requirements: []
|
170
|
+
|
110
171
|
rubyforge_project: rdf-turtle
|
111
172
|
rubygems_version: 1.8.6
|
112
173
|
signing_key:
|
113
174
|
specification_version: 3
|
114
175
|
summary: Turtle reader/writer for Ruby.
|
115
176
|
test_files: []
|
177
|
+
|