rdf-turtle 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|