rdf-turtle 3.0.4 → 3.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a2739fecb539c03eacd39c93e7c002ee32f9b6b49f8786d2119150d1a57cd236
4
- data.tar.gz: b72813794b2c80e8b518aaa151740f26a55017074555823fdd14dfbe181efc7f
3
+ metadata.gz: cab6a95280c9ece9d97ed7bde134044c247d0990cd9451772b3726a85c1dafce
4
+ data.tar.gz: 56c87a3f41a22ffae491aed4197261e204332541855777f1822bd24d965047f0
5
5
  SHA512:
6
- metadata.gz: 43ad711bd729dcabcdf0e3e07006fed39f7a31fbe074513777e1dcaec358bb373a1e77e31fd8bb5761ebf487efa0e2aa94cccc2311ffa135534fdabdf4654aa7
7
- data.tar.gz: dc7bafb1ff5ba905b85982b6514e65da5bdf1b1e2fd1f0813ee4678f3e174cf20871087c73f7c1a2a52d65e3d07058d26be31cc8d6ea92dfd315f81e904647b9
6
+ metadata.gz: c5ce46d746a7ed5ac19c3b8fde60934485781149302d6b02e64d1b45dd70a6402c46ba8ca9e7eb06c3d96030c93c26646751bc92155dc239dbc41179d9c72c49
7
+ data.tar.gz: ad9a7a6ea210992f5a0ddbd037ded7b7f0a0129e4fc4a5610ad03f313381354207394840c9c729c70192906dfac58294c216a62382316b909f79a34c3db9d172
data/History CHANGED
@@ -30,7 +30,7 @@
30
30
  * Replace remaining uses of SPARQL with RDF::Turtle or RDF::LL1
31
31
 
32
32
  ### 0.0.3
33
- * Completed RDF 1.1 Turtle based on http://www.w3.org/TR/2011/WD-turtle-20110809/
33
+ * Completed RDF 1.1 Turtle based on https://www.w3.org/TR/2011/WD-turtle-20110809/
34
34
  * Reader
35
35
  * Writer
36
36
  * Issues:
data/README.md CHANGED
@@ -2,10 +2,9 @@
2
2
 
3
3
  [Turtle][] reader/writer for [RDF.rb][RDF.rb] .
4
4
 
5
- [![Gem Version](https://badge.fury.io/rb/rdf-turtle.png)](http://badge.fury.io/rb/rdf-turtle)
6
- [![Build Status](https://travis-ci.org/ruby-rdf/rdf-turtle.png?branch=master)](http://travis-ci.org/ruby-rdf/rdf-turtle)
5
+ [![Gem Version](https://badge.fury.io/rb/rdf-turtle.png)](https://badge.fury.io/rb/rdf-turtle)
6
+ [![Build Status](https://travis-ci.org/ruby-rdf/rdf-turtle.png?branch=master)](https://travis-ci.org/ruby-rdf/rdf-turtle)
7
7
  [![Coverage Status](https://coveralls.io/repos/ruby-rdf/rdf-turtle/badge.svg)](https://coveralls.io/r/ruby-rdf/rdf-turtle)
8
- [![Dependency Status](https://gemnasium.com/ruby-rdf/rdf-turtle.png)](https://gemnasium.com/ruby-rdf/rdf-turtle)
9
8
 
10
9
  ## Description
11
10
  This is a [Ruby][] implementation of a [Turtle][] parser for [RDF.rb][].
@@ -15,10 +14,11 @@ RDF::Turtle parses [Turtle][Turtle] and [N-Triples][N-Triples] into statements o
15
14
 
16
15
  Install with `gem install rdf-turtle`
17
16
 
18
- * 100% free and unencumbered [public domain](http://unlicense.org/) software.
17
+ * 100% free and unencumbered [public domain](https://unlicense.org/) software.
19
18
  * Implements a complete parser for [Turtle][].
20
19
  * Compatible with Ruby >= 2.2.2.
21
20
  * Optional streaming writer, to serialize large graphs
21
+ * Provisional support for [Turtle*][RDF*].
22
22
 
23
23
  ## Usage
24
24
  Instantiate a reader from a local file:
@@ -35,6 +35,50 @@ Write a graph to a file:
35
35
  writer << graph
36
36
  end
37
37
 
38
+ ## Turtle* (RDFStar)
39
+
40
+ Both reader and writer include provisional support for [Turtle*][RDF*].
41
+
42
+ Internally, an `RDF::Statement` is treated as another resource, along with `RDF::URI` and `RDF::Node`, which allows an `RDF::Statement` to have a `#subject` or `#object` which is also an `RDF::Statement`.
43
+
44
+ **Note: This feature is subject to change or elimination as the standards process progresses.**
45
+
46
+ ### Serializing a Graph containing embedded statements
47
+
48
+ require 'rdf/turtle'
49
+ statement = RDF::Statement(RDF::URI('bob'), RDF::Vocab::FOAF.age, RDF::Literal(23))
50
+ graph = RDF::Graph.new << [statement, RDF::URI("ex:certainty"), RDF::Literal(0.9)]
51
+ graph.dump(:ttl, validate: false, standard_prefixes: true)
52
+ # => '<<<bob> foaf:age 23>> <ex:certainty> 9.0e-1 .'
53
+
54
+ ### Reading a Graph containing embedded statements
55
+
56
+ By default, the Turtle reader will reject a document containing a subject resource.
57
+
58
+ ttl = %(
59
+ @prefix foaf: <http://xmlns.com/foaf/0.1/> .
60
+ @prefix ex: <http://example.com/> .
61
+ <<<bob> foaf:age 23>> ex:certainty 9.0e-1 .
62
+ )
63
+ graph = RDF::Graph.new do |graph|
64
+ RDF::Turtle::Reader.new(ttl) {|reader| graph << reader}
65
+ end
66
+ # => RDF::ReaderError
67
+
68
+ Readers support a `rdfstar` option with either `:PG` (Property Graph) or `:SA` (Separate Assertions) modes. In `:PG` mode, statements that are used in the subject or object positions are also implicitly added to the graph:
69
+
70
+ graph = RDF::Graph.new do |graph|
71
+ RDF::Turtle::Reader.new(ttl, rdfstar: :PG) {|reader| graph << reader}
72
+ end
73
+ graph.count #=> 2
74
+
75
+ When using the `:SA` mode, only one statement is asserted, although the reified statement is contained within the graph.
76
+
77
+ graph = RDF::Graph.new do |graph|
78
+ RDF::Turtle::Reader.new(ttl, rdfstar: :SA) {|reader| graph << reader}
79
+ end
80
+ graph.count #=> 1
81
+
38
82
  ## Documentation
39
83
  Full documentation available on [Rubydoc.info][Turtle doc]
40
84
 
@@ -85,22 +129,22 @@ This version uses a hand-written parser using the Lexer from the [EBNF][] gem in
85
129
 
86
130
  ## Dependencies
87
131
 
88
- * [Ruby](http://ruby-lang.org/) (>= 2.2)
89
- * [RDF.rb](http://rubygems.org/gems/rdf) (~> 3.0)
132
+ * [Ruby](https://ruby-lang.org/) (>= 2.4)
133
+ * [RDF.rb](https://rubygems.org/gems/rdf) (~> 3.1)
90
134
  * [EBNF][] (~> 1.1)
91
135
 
92
136
  ## Installation
93
137
 
94
- The recommended installation method is via [RubyGems](http://rubygems.org/).
138
+ The recommended installation method is via [RubyGems](https://rubygems.org/).
95
139
  To install the latest official release of the `RDF::Turtle` gem, do:
96
140
 
97
141
  % [sudo] gem install rdf-turtle
98
142
 
99
143
  ## Mailing List
100
- * <http://lists.w3.org/Archives/Public/public-rdf-ruby/>
144
+ * <https://lists.w3.org/Archives/Public/public-rdf-ruby/>
101
145
 
102
146
  ## Author
103
- * [Gregg Kellogg](http://github.com/gkellogg) - <http://greggkellogg.net/>
147
+ * [Gregg Kellogg](https://github.com/gkellogg) - <https://greggkellogg.net/>
104
148
 
105
149
  ## Contributing
106
150
  This repository uses [Git Flow](https://github.com/nvie/gitflow) to mange development and release activity. All submissions _must_ be on a feature branch based on the _develop_ branch to ease staging and integration.
@@ -119,20 +163,21 @@ This repository uses [Git Flow](https://github.com/nvie/gitflow) to mange develo
119
163
 
120
164
  ## License
121
165
  This is free and unencumbered public domain software. For more information,
122
- see <http://unlicense.org/> or the accompanying {file:UNLICENSE} file.
123
-
124
- A copy of the [Turtle EBNF][] and derived parser files are included in the repository, which are not covered under the UNLICENSE. These files are covered via the [W3C Document License](http://www.w3.org/Consortium/Legal/2002/copyright-documents-20021231).
125
-
126
- [Ruby]: http://ruby-lang.org/
127
- [RDF]: http://www.w3.org/RDF/
128
- [YARD]: http://yardoc.org/
129
- [YARD-GS]: http://rubydoc.info/docs/yard/file/docs/GettingStarted.md
130
- [PDD]: http://lists.w3.org/Archives/Public/public-rdf-ruby/2010May/0013.html
131
- [RDF.rb]: http://rubydoc.info/github/ruby-rdf/rdf
132
- [EBNF]: http://rubygems.org/gems/ebnf
133
- [Backports]: http://rubygems.org/gems/backports
134
- [N-Triples]: http://www.w3.org/TR/rdf-testcases/#ntriples
135
- [Turtle]: http://www.w3.org/TR/2012/WD-turtle-20120710/
136
- [Turtle doc]: http://rubydoc.info/github/ruby-rdf/rdf-turtle/master/file/README.md
137
- [Turtle EBNF]: http://dvcs.w3.org/hg/rdf/file/default/rdf-turtle/turtle.bnf
166
+ see <https://unlicense.org/> or the accompanying {file:UNLICENSE} file.
167
+
168
+ A copy of the [Turtle EBNF][] and derived parser files are included in the repository, which are not covered under the UNLICENSE. These files are covered via the [W3C Document License](https://www.w3.org/Consortium/Legal/2002/copyright-documents-20021231).
169
+
170
+ [Ruby]: https://ruby-lang.org/
171
+ [RDF]: https://www.w3.org/RDF/
172
+ [YARD]: https://yardoc.org/
173
+ [YARD-GS]: https://rubydoc.info/docs/yard/file/docs/GettingStarted.md
174
+ [PDD]: https://lists.w3.org/Archives/Public/public-rdf-ruby/2010May/0013.html
175
+ [RDF.rb]: https://rubydoc.info/github/ruby-rdf/rdf
176
+ [EBNF]: https://rubygems.org/gems/ebnf
177
+ [Backports]: https://rubygems.org/gems/backports
178
+ [N-Triples]: https://www.w3.org/TR/rdf-testcases/#ntriples
179
+ [Turtle]: https://www.w3.org/TR/2012/WD-turtle-20120710/
180
+ [RDF*]: https://lists.w3.org/Archives/Public/public-rdf-star/
181
+ [Turtle doc]: https://rubydoc.info/github/ruby-rdf/rdf-turtle/master/file/README.md
182
+ [Turtle EBNF]: https://dvcs.w3.org/hg/rdf/file/default/rdf-turtle/turtle.bnf
138
183
  [Freebase Dumps]: https://developers.google.com/freebase/data
data/UNLICENSE CHANGED
@@ -21,4 +21,4 @@ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21
21
  ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
22
  OTHER DEALINGS IN THE SOFTWARE.
23
23
 
24
- For more information, please refer to <http://unlicense.org/>
24
+ For more information, please refer to <https://unlicense.org/>
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.0.4
1
+ 3.1.2
@@ -15,10 +15,10 @@ module RDF
15
15
  # end
16
16
  # end
17
17
  #
18
- # @see http://rubydoc.info/github/ruby-rdf/rdf/master/frames
19
- # @see http://dvcs.w3.org/hg/rdf/raw-file/default/rdf-turtle/index.html
18
+ # @see https://rubydoc.info/github/ruby-rdf/rdf/master/frames
19
+ # @see https://dvcs.w3.org/hg/rdf/raw-file/default/rdf-turtle/index.html
20
20
  #
21
- # @author [Gregg Kellogg](http://greggkellogg.net/)
21
+ # @author [Gregg Kellogg](https://greggkellogg.net/)
22
22
  module Turtle
23
23
  require 'rdf/turtle/format'
24
24
  autoload :Reader, 'rdf/turtle/reader'
@@ -14,7 +14,7 @@ module RDF::Turtle
14
14
  # @example Obtaining serialization format file extension mappings
15
15
  # RDF::Format.file_extensions #=> {ttl: "text/turtle"}
16
16
  #
17
- # @see http://www.w3.org/TR/rdf-testcases/#ntriples
17
+ # @see https://www.w3.org/TR/rdf-testcases/#ntriples
18
18
  class Format < RDF::Format
19
19
  content_type 'text/turtle',
20
20
  extension: :ttl,
@@ -55,7 +55,7 @@ module RDF::Turtle
55
55
  ##
56
56
  # Read a PNAME of the form `prefix:suffix`.
57
57
  # @return [RDF::URI]
58
- def read_pname(options = {})
58
+ def read_pname(**options)
59
59
  if pname_str = match(/^(\w+:\S+)/)
60
60
  ns, suffix = pname_str.split(':', 2)
61
61
  if suffix[-1,1] == "."
@@ -74,7 +74,7 @@ module RDF::Turtle
74
74
 
75
75
  ##
76
76
  # @return [RDF::Literal]
77
- # @see http://www.w3.org/TR/rdf-testcases/#ntrip_grammar (literal)
77
+ # @see https://www.w3.org/TR/rdf-testcases/#ntrip_grammar (literal)
78
78
  def read_literal
79
79
  if literal_str = match(LITERAL_PLAIN)
80
80
  literal_str = self.class.unescape(literal_str)
@@ -25,7 +25,7 @@ module RDF::Turtle
25
25
  terminal(:STRING_LITERAL_SINGLE_QUOTE, STRING_LITERAL_SINGLE_QUOTE, unescape: true)
26
26
 
27
27
  # String terminals
28
- terminal(nil, %r([\(\),.;\[\]Aa]|\^\^|true|false))
28
+ terminal(nil, %r([\(\),.;\[\]Aa]|\^\^|true|false|<<|>>))
29
29
 
30
30
  terminal(:PREFIX, PREFIX)
31
31
  terminal(:BASE, BASE)
@@ -33,7 +33,7 @@ module RDF::Turtle
33
33
 
34
34
  ##
35
35
  # Reader options
36
- # @see http://www.rubydoc.info/github/ruby-rdf/rdf/RDF/Reader#options-class_method
36
+ # @see https://www.rubydoc.info/github/ruby-rdf/rdf/RDF/Reader#options-class_method
37
37
  def self.options
38
38
  super + [
39
39
  RDF::CLI::Option.new(
@@ -48,14 +48,14 @@ module RDF::Turtle
48
48
  # Redirect for Freebase Reader
49
49
  #
50
50
  # @private
51
- def self.new(input = nil, options = {}, &block)
51
+ def self.new(input = nil, **options, &block)
52
52
  klass = if options[:freebase]
53
53
  FreebaseReader
54
54
  else
55
55
  self
56
56
  end
57
57
  reader = klass.allocate
58
- reader.send(:initialize, input, options, &block)
58
+ reader.send(:initialize, input, **options, &block)
59
59
  reader
60
60
  end
61
61
 
@@ -82,12 +82,12 @@ module RDF::Turtle
82
82
  # @option options [Boolean] :freebase (false)
83
83
  # Use optimized Freebase reader
84
84
  # @return [RDF::Turtle::Reader]
85
- def initialize(input = nil, options = {}, &block)
85
+ def initialize(input = nil, **options, &block)
86
86
  super do
87
87
  @options = {
88
88
  anon_base: "b0",
89
89
  whitespace: WS,
90
- log_depth: 0,
90
+ depth: 0,
91
91
  }.merge(@options)
92
92
  @prod_stack = []
93
93
 
@@ -98,7 +98,7 @@ module RDF::Turtle
98
98
  log_debug("canonicalize") {canonicalize?.inspect}
99
99
  log_debug("intern") {intern?.inspect}
100
100
 
101
- @lexer = EBNF::LL1::Lexer.new(input, self.class.patterns, @options)
101
+ @lexer = EBNF::LL1::Lexer.new(input, self.class.patterns, **@options)
102
102
 
103
103
  if block_given?
104
104
  case block.arity
@@ -163,7 +163,7 @@ module RDF::Turtle
163
163
  # @return [RDF::Statement] Added statement
164
164
  # @raise [RDF::ReaderError] Checks parameter types and raises if they are incorrect if parsing mode is _validate_.
165
165
  def add_statement(production, statement)
166
- error("Statement is invalid: #{statement.inspect.inspect}", production: produciton) if validate? && statement.invalid?
166
+ error("Statement is invalid: #{statement.inspect}", production: produciton) if validate? && statement.invalid?
167
167
  @callback.call(statement) if statement.subject &&
168
168
  statement.predicate &&
169
169
  statement.object &&
@@ -184,14 +184,14 @@ module RDF::Turtle
184
184
  end
185
185
 
186
186
  # Create a literal
187
- def literal(value, options = {})
188
- log_debug("literal") do
187
+ def literal(value, **options)
188
+ log_debug("literal", depth: @options[:depth]) do
189
189
  "value: #{value.inspect}, " +
190
190
  "options: #{options.inspect}, " +
191
191
  "validate: #{validate?.inspect}, " +
192
192
  "c14n?: #{canonicalize?.inspect}"
193
193
  end
194
- RDF::Literal.new(value, options.merge(validate: validate?, canonicalize: canonicalize?))
194
+ RDF::Literal.new(value, validate: validate?, canonicalize: canonicalize?, **options)
195
195
  rescue ArgumentError => e
196
196
  error("Argument Error #{e.message}", production: :literal, token: @lexer.first)
197
197
  end
@@ -221,7 +221,7 @@ module RDF::Turtle
221
221
  ''
222
222
  end
223
223
  suffix = suffix.to_s.sub(/^\#/, "") if base.index("#")
224
- log_debug("pname") {"base: '#{base}', suffix: '#{suffix}'"}
224
+ log_debug("pname", depth: options[:depth]) {"base: '#{base}', suffix: '#{suffix}'"}
225
225
  process_iri(base + suffix.to_s)
226
226
  end
227
227
 
@@ -283,7 +283,7 @@ module RDF::Turtle
283
283
  terminated = token.value == '@prefix'
284
284
  error("Expected PNAME_NS", production: :prefix, token: pfx) unless pfx === :PNAME_NS
285
285
  error("Expected IRIREF", production: :prefix, token: iri) unless iri === :IRIREF
286
- log_debug("prefixID") {"Defined prefix #{pfx.inspect} mapping to #{iri.inspect}"}
286
+ log_debug("prefixID", depth: options[:depth]) {"Defined prefix #{pfx.inspect} mapping to #{iri.inspect}"}
287
287
  prefix(pfx.value[0..-2], process_iri(iri))
288
288
  error("prefixId", "#{token} should be downcased") if token.value.start_with?('@') && token.value != '@prefix'
289
289
 
@@ -362,6 +362,7 @@ module RDF::Turtle
362
362
  read_iri ||
363
363
  read_BlankNode ||
364
364
  read_collection ||
365
+ read_rdfstar ||
365
366
  error( "Expected subject", production: :subject, token: @lexer.first)
366
367
  end
367
368
  end
@@ -373,7 +374,8 @@ module RDF::Turtle
373
374
  read_BlankNode ||
374
375
  read_collection ||
375
376
  read_blankNodePropertyList ||
376
- read_literal
377
+ read_literal ||
378
+ read_rdfstar
377
379
 
378
380
  add_statement(:object, RDF::Statement(subject, predicate, object)) if subject && predicate
379
381
  object
@@ -381,6 +383,28 @@ module RDF::Turtle
381
383
  end
382
384
  end
383
385
 
386
+ # Read an RDF* reified statement
387
+ # @return [RDF::Statement]
388
+ def read_rdfstar
389
+ return unless @options[:rdfstar]
390
+ if @lexer.first.value == '<<'
391
+ prod(:rdfstar) do
392
+ @lexer.shift # eat <<
393
+ subject = read_subject || error("Failed to parse subject", production: :rdfstar, token: @lexer.first)
394
+ predicate = read_verb || error("Failed to parse predicate", production: :rdfstar, token: @lexer.first)
395
+ object = read_object || error("Failed to parse object", production: :rdfstar, token: @lexer.first)
396
+ unless @lexer.first.value == '>>'
397
+ error("Failed to end of embedded triple", production: :rdfstar, token: @lexer.first)
398
+ end
399
+ @lexer.shift
400
+ statement = RDF::Statement(subject, predicate, object)
401
+ # Emit the statement if in Property Graph mode
402
+ add_statement(:rdfstar, statement) if @options[:rdfstar] == :PG
403
+ statement
404
+ end
405
+ end
406
+ end
407
+
384
408
  # @return [RDF::Literal]
385
409
  def read_literal
386
410
  error("Unexpected end of file", production: :literal) unless token = @lexer.first
@@ -431,7 +455,7 @@ module RDF::Turtle
431
455
  if token === '['
432
456
  prod(:blankNodePropertyList, %{]}) do
433
457
  @lexer.shift
434
- log_info("blankNodePropertyList") {"token: #{token.inspect}"}
458
+ log_info("blankNodePropertyList", depth: options[:depth]) {"token: #{token.inspect}"}
435
459
  node = bnode
436
460
  read_predicateObjectList(node)
437
461
  error("blankNodePropertyList", "Expected closing ']'") unless @lexer.first === ']'
@@ -447,7 +471,7 @@ module RDF::Turtle
447
471
  prod(:collection, %{)}) do
448
472
  @lexer.shift
449
473
  token = @lexer.first
450
- log_info("collection") {"token: #{token.inspect}"}
474
+ log_info("collection", depth: options[:depth]) {"token: #{token.inspect}"}
451
475
  objects = []
452
476
  while object = read_object
453
477
  objects << object
@@ -483,8 +507,8 @@ module RDF::Turtle
483
507
 
484
508
  def prod(production, recover_to = [])
485
509
  @prod_stack << {prod: production, recover_to: recover_to}
486
- @options[:log_depth] += 1
487
- log_recover("#{production}(start)") {"token: #{@lexer.first.inspect}"}
510
+ @options[:depth] += 1
511
+ log_recover("#{production}(start)", depth: options[:depth]) {"token: #{@lexer.first.inspect}"}
488
512
  yield
489
513
  rescue EBNF::LL1::Lexer::Error, SyntaxError, Recovery => e
490
514
  # Lexer encountered an illegal token or the parser encountered
@@ -504,13 +528,13 @@ module RDF::Turtle
504
528
  end
505
529
  end
506
530
  raise EOFError, "End of input found when recovering" if @lexer.first.nil?
507
- log_debug("recovery", "current token: #{@lexer.first.inspect}")
531
+ log_debug("recovery", "current token: #{@lexer.first.inspect}", depth: options[:depth])
508
532
 
509
533
  unless e.is_a?(Recovery)
510
534
  # Get the list of follows for this sequence, this production and the stacked productions.
511
- log_debug("recovery", "stack follows:")
535
+ log_debug("recovery", "stack follows:", depth: options[:depth])
512
536
  @prod_stack.reverse.each do |prod|
513
- log_debug("recovery", level: 4) {" #{prod[:prod]}: #{prod[:recover_to].inspect}"}
537
+ log_debug("recovery", level: 4, depth: options[:depth]) {" #{prod[:prod]}: #{prod[:recover_to].inspect}"}
514
538
  end
515
539
  end
516
540
 
@@ -520,9 +544,9 @@ module RDF::Turtle
520
544
  # Skip tokens until one is found in follows
521
545
  while (token = (@lexer.first rescue @lexer.recover)) && follows.none? {|t| token === t}
522
546
  skipped = @lexer.shift
523
- log_debug("recovery") {"skip #{skipped.inspect}"}
547
+ log_debug("recovery", depth: options[:depth]) {"skip #{skipped.inspect}"}
524
548
  end
525
- log_debug("recovery") {"found #{token.inspect} in follows"}
549
+ log_debug("recovery", depth: options[:depth]) {"found #{token.inspect} in follows"}
526
550
 
527
551
  # Re-raise the error unless token is a follows of this production
528
552
  raise Recovery unless Array(recover_to).any? {|t| token === t}
@@ -530,8 +554,8 @@ module RDF::Turtle
530
554
  # Skip that token to get something reasonable to start the next production with
531
555
  @lexer.shift
532
556
  ensure
533
- log_info("#{production}(finish)")
534
- @options[:log_depth] -= 1
557
+ log_info("#{production}(finish)", depth: options[:depth])
558
+ @options[:depth] -= 1
535
559
  @prod_stack.pop
536
560
  end
537
561
 
@@ -554,7 +578,8 @@ module RDF::Turtle
554
578
  lineno: lineno,
555
579
  token: options[:token],
556
580
  production: options[:production],
557
- exception: SyntaxError)
581
+ depth: options[:depth],
582
+ exception: SyntaxError,)
558
583
  end
559
584
 
560
585
  # Used for internal error recovery
@@ -587,7 +612,7 @@ module RDF::Turtle
587
612
  # @option options [Symbol] :production (nil)
588
613
  # @option options [String] :token (nil)
589
614
  # @option options [Integer] :lineno (nil)
590
- def initialize(message, options = {})
615
+ def initialize(message, **options)
591
616
  @production = options[:production]
592
617
  @token = options[:token]
593
618
  @lineno = options[:lineno] || (@token.lineno if @token.respond_to?(:lineno))
@@ -3,7 +3,7 @@ require 'rdf/turtle/terminals'
3
3
  module RDF::Turtle
4
4
  ##
5
5
  # Streaming writer interface
6
- # @author [Gregg Kellogg](http://greggkellogg.net/)
6
+ # @author [Gregg Kellogg](https://greggkellogg.net/)
7
7
  module StreamingWriter
8
8
  ##
9
9
  # Write out declarations
@@ -28,15 +28,15 @@ module RDF::Turtle
28
28
  if statement.subject != @streaming_subject
29
29
  @output.puts ' .' if @streaming_subject
30
30
  @streaming_subject, @streaming_predicate = statement.subject, statement.predicate
31
- @output.write "#{format_term(statement.subject, options)} "
32
- @output.write "#{format_term(statement.predicate, options)} "
31
+ @output.write "#{format_term(statement.subject, **options)} "
32
+ @output.write "#{format_term(statement.predicate, **options)} "
33
33
  elsif statement.predicate != @streaming_predicate
34
34
  @streaming_predicate = statement.predicate
35
- @output.write ";\n#{indent(1)}#{format_term(statement.predicate, options)} "
35
+ @output.write ";\n#{indent(1)}#{format_term(statement.predicate, **options)} "
36
36
  else
37
37
  @output.write ",\n#{indent(2)}"
38
38
  end
39
- @output.write("#{format_term(statement.object, options)}")
39
+ @output.write("#{format_term(statement.object, **options)}")
40
40
  end
41
41
 
42
42
  ##
@@ -1,9 +1,9 @@
1
+ # encoding: utf-8
1
2
  require 'ebnf/ll1/lexer'
2
3
 
3
4
  module RDF::Turtle
4
5
  module Terminals
5
6
  # Definitions of token regular expressions used for lexical analysis
6
-
7
7
  ##
8
8
  # Unicode regular expressions for Ruby 1.9+ with the Oniguruma engine.
9
9
  U_CHARS1 = Regexp.compile(<<-EOS.gsub(/\s+/, ''))
@@ -12,66 +12,66 @@ module RDF::Turtle
12
12
  [\\u2070-\\u218F]|[\\u2C00-\\u2FEF]|[\\u3001-\\uD7FF]|
13
13
  [\\uF900-\\uFDCF]|[\\uFDF0-\\uFFFD]|[\\u{10000}-\\u{EFFFF}]
14
14
  EOS
15
- U_CHARS2 = Regexp.compile("\\u00B7|[\\u0300-\\u036F]|[\\u203F-\\u2040]").freeze
16
- IRI_RANGE = Regexp.compile("[[^<>\"{}|^`\\\\]&&[^\\x00-\\x20]]").freeze
15
+ U_CHARS2 = Regexp.compile("\\u00B7|[\\u0300-\\u036F]|[\\u203F-\\u2040]", Regexp::FIXEDENCODING).freeze
16
+ IRI_RANGE = Regexp.compile("[[^<>\"{}|^`\\\\]&&[^\\x00-\\x20]]", Regexp::FIXEDENCODING).freeze
17
17
 
18
18
  # 26
19
19
  UCHAR = EBNF::LL1::Lexer::UCHAR
20
20
  # 170s
21
- PERCENT = /%[0-9A-Fa-f]{2}/.freeze
21
+ PERCENT = /%[0-9A-Fa-f]{2}/u.freeze
22
22
  # 172s
23
- PN_LOCAL_ESC = /\\[_~\.\-\!$\&'\(\)\*\+,;=\/\?\#@%]/.freeze
23
+ PN_LOCAL_ESC = /\\[_~\.\-\!$\&'\(\)\*\+,;=\/\?\#@%]/u.freeze
24
24
  # 169s
25
- PLX = /#{PERCENT}|#{PN_LOCAL_ESC}/.freeze.freeze
25
+ PLX = /#{PERCENT}|#{PN_LOCAL_ESC}/u.freeze
26
26
  # 163s
27
- PN_CHARS_BASE = /[A-Z]|[a-z]|#{U_CHARS1}/.freeze
27
+ PN_CHARS_BASE = /[A-Z]|[a-z]|#{U_CHARS1}/u.freeze
28
28
  # 164s
29
- PN_CHARS_U = /_|#{PN_CHARS_BASE}/.freeze
29
+ PN_CHARS_U = /_|#{PN_CHARS_BASE}/u.freeze
30
30
  # 166s
31
- PN_CHARS = /-|[0-9]|#{PN_CHARS_U}|#{U_CHARS2}/.freeze
32
- PN_LOCAL_BODY = /(?:(?:\.|:|#{PN_CHARS}|#{PLX})*(?:#{PN_CHARS}|:|#{PLX}))?/.freeze
33
- PN_CHARS_BODY = /(?:(?:\.|#{PN_CHARS})*#{PN_CHARS})?/.freeze
31
+ PN_CHARS = /-|[0-9]|#{PN_CHARS_U}|#{U_CHARS2}/u.freeze
32
+ PN_LOCAL_BODY = /(?:(?:\.|:|#{PN_CHARS}|#{PLX})*(?:#{PN_CHARS}|:|#{PLX}))?/u.freeze
33
+ PN_CHARS_BODY = /(?:(?:\.|#{PN_CHARS})*#{PN_CHARS})?/u.freeze
34
34
  # 167s
35
- PN_PREFIX = /#{PN_CHARS_BASE}#{PN_CHARS_BODY}/.freeze
35
+ PN_PREFIX = /#{PN_CHARS_BASE}#{PN_CHARS_BODY}/u.freeze
36
36
  # 168s
37
- PN_LOCAL = /(?:[0-9]|:|#{PN_CHARS_U}|#{PLX})#{PN_LOCAL_BODY}/.freeze
37
+ PN_LOCAL = /(?:[0-9]|:|#{PN_CHARS_U}|#{PLX})#{PN_LOCAL_BODY}/u.freeze
38
38
  # 154s
39
- EXPONENT = /[eE][+-]?[0-9]+/
39
+ EXPONENT = /[eE][+-]?[0-9]+/u.freeze
40
40
  # 159s
41
- ECHAR = /\\[tbnrf\\"']/
41
+ ECHAR = /\\[tbnrf\\"']/u.freeze
42
42
  # 18
43
- IRIREF = /<(?:#{IRI_RANGE}|#{UCHAR})*>/.freeze
43
+ IRIREF = /<(?:#{IRI_RANGE}|#{UCHAR})*>/u.freeze
44
44
  # 139s
45
- PNAME_NS = /#{PN_PREFIX}?:/.freeze
45
+ PNAME_NS = /#{PN_PREFIX}?:/u.freeze
46
46
  # 140s
47
- PNAME_LN = /#{PNAME_NS}#{PN_LOCAL}/.freeze
47
+ PNAME_LN = /#{PNAME_NS}#{PN_LOCAL}/u.freeze
48
48
  # 141s
49
- BLANK_NODE_LABEL = /_:(?:[0-9]|#{PN_CHARS_U})(?:(?:#{PN_CHARS}|\.)*#{PN_CHARS})?/.freeze
49
+ BLANK_NODE_LABEL = /_:(?:[0-9]|#{PN_CHARS_U})(?:(?:#{PN_CHARS}|\.)*#{PN_CHARS})?/u.freeze
50
50
  # 144s
51
- LANGTAG = /@[a-zA-Z]+(?:-[a-zA-Z0-9]+)*/.freeze
51
+ LANGTAG = /@[a-zA-Z]+(?:-[a-zA-Z0-9]+)*/u.freeze
52
52
  # 19
53
- INTEGER = /[+-]?[0-9]+/.freeze
53
+ INTEGER = /[+-]?[0-9]+/u.freeze
54
54
  # 20
55
- DECIMAL = /[+-]?(?:[0-9]*\.[0-9]+)/.freeze
55
+ DECIMAL = /[+-]?(?:[0-9]*\.[0-9]+)/u.freeze
56
56
  # 21
57
- DOUBLE = /[+-]?(?:[0-9]+\.[0-9]*#{EXPONENT}|\.?[0-9]+#{EXPONENT})/.freeze
57
+ DOUBLE = /[+-]?(?:[0-9]+\.[0-9]*#{EXPONENT}|\.?[0-9]+#{EXPONENT})/u.freeze
58
58
  # 22
59
- STRING_LITERAL_SINGLE_QUOTE = /'(?:[^\'\\\n\r]|#{ECHAR}|#{UCHAR})*'/.freeze
59
+ STRING_LITERAL_SINGLE_QUOTE = /'(?:[^\'\\\n\r]|#{ECHAR}|#{UCHAR})*'/u.freeze
60
60
  # 23
61
- STRING_LITERAL_QUOTE = /"(?:[^\"\\\n\r]|#{ECHAR}|#{UCHAR})*"/.freeze
61
+ STRING_LITERAL_QUOTE = /"(?:[^\"\\\n\r]|#{ECHAR}|#{UCHAR})*"/u.freeze
62
62
  # 24
63
- STRING_LITERAL_LONG_SINGLE_QUOTE = /'''(?:(?:'|'')?(?:[^'\\]|#{ECHAR}|#{UCHAR}))*'''/m.freeze
63
+ STRING_LITERAL_LONG_SINGLE_QUOTE = /'''(?:(?:'|'')?(?:[^'\\]|#{ECHAR}|#{UCHAR}))*'''/um.freeze
64
64
  # 25
65
- STRING_LITERAL_LONG_QUOTE = /"""(?:(?:"|"")?(?:[^"\\]|#{ECHAR}|#{UCHAR}))*"""/m.freeze
65
+ STRING_LITERAL_LONG_QUOTE = /"""(?:(?:"|"")?(?:[^"\\]|#{ECHAR}|#{UCHAR}))*"""/um.freeze
66
66
 
67
67
  # 161s
68
- WS = /(?:\s|(?:#[^\n\r]*))+/m.freeze
68
+ WS = /(?:\s|(?:#[^\n\r]*))+/um.freeze
69
69
  # 162s
70
- ANON = /\[#{WS}*\]/m.freeze
70
+ ANON = /\[#{WS}*\]/um.freeze
71
71
  # 28t
72
- PREFIX = /@?prefix/i.freeze
72
+ PREFIX = /@?prefix/ui.freeze
73
73
  # 29t
74
- BASE = /@?base/i.freeze
74
+ BASE = /@?base/ui.freeze
75
75
 
76
76
  end
77
77
  end
@@ -54,7 +54,7 @@ module RDF::Turtle
54
54
  # end
55
55
  # end
56
56
  #
57
- # @author [Gregg Kellogg](http://greggkellogg.net/)
57
+ # @author [Gregg Kellogg](https://greggkellogg.net/)
58
58
  class Writer < RDF::Writer
59
59
  include StreamingWriter
60
60
  include RDF::Util::Logger
@@ -65,7 +65,7 @@ module RDF::Turtle
65
65
 
66
66
  ##
67
67
  # Writer options
68
- # @see http://www.rubydoc.info/github/ruby-rdf/rdf/RDF/Writer#options-class_method
68
+ # @see https://www.rubydoc.info/github/ruby-rdf/rdf/RDF/Writer#options-class_method
69
69
  def self.options
70
70
  super + [
71
71
  RDF::CLI::Option.new(
@@ -123,7 +123,7 @@ module RDF::Turtle
123
123
  # @yieldreturn [void]
124
124
  # @yield [writer]
125
125
  # @yieldparam [RDF::Writer] writer
126
- def initialize(output = $stdout, options = {}, &block)
126
+ def initialize(output = $stdout, **options, &block)
127
127
  @graph = RDF::Graph.new
128
128
  @uri_to_pname = {}
129
129
  @uri_to_prefix = {}
@@ -272,7 +272,7 @@ module RDF::Turtle
272
272
  # @param [RDF::Literal, String, #to_s] literal
273
273
  # @param [Hash{Symbol => Object}] options
274
274
  # @return [String]
275
- def format_literal(literal, options = {})
275
+ def format_literal(literal, **options)
276
276
  case literal
277
277
  when RDF::Literal
278
278
  case @options[:literal_shorthand] && literal.valid? ? literal.datatype : false
@@ -297,7 +297,7 @@ module RDF::Turtle
297
297
  # @param [RDF::URI] uri
298
298
  # @param [Hash{Symbol => Object}] options
299
299
  # @return [String]
300
- def format_uri(uri, options = {})
300
+ def format_uri(uri, **options)
301
301
  md = uri.relativize(base_uri)
302
302
  log_debug("relativize") {"#{uri.to_ntriples} => #{md.inspect}"} if md != uri.to_s
303
303
  md != uri.to_s ? "<#{md}>" : (get_pname(uri) || "<#{uri}>")
@@ -309,10 +309,21 @@ module RDF::Turtle
309
309
  # @param [RDF::Node] node
310
310
  # @param [Hash{Symbol => Object}] options
311
311
  # @return [String]
312
- def format_node(node, options = {})
312
+ def format_node(node, **options)
313
313
  options[:unique_bnodes] ? node.to_unique_base : node.to_base
314
314
  end
315
315
 
316
+ ##
317
+ # Returns an embedded triples
318
+ #
319
+ # @param [RDF::Statement] statement
320
+ # @param [Hash{Symbol => Object}] options
321
+ # @return [String]
322
+ def format_rdfstar(statement, **options)
323
+ log_debug("rdfstar") {"#{statement.to_ntriples}"}
324
+ "<<%s %s %s>>" % statement.to_a.map { |value| format_term(value, **options) }
325
+ end
326
+
316
327
  protected
317
328
  # Output @base and @prefix definitions
318
329
  def start_document
@@ -349,7 +360,7 @@ module RDF::Turtle
349
360
 
350
361
  # Add distinguished classes
351
362
  top_classes.each do |class_uri|
352
- graph.query(predicate: RDF.type, object: class_uri).
363
+ graph.query({predicate: RDF.type, object: class_uri}).
353
364
  map {|st| st.subject}.
354
365
  sort.
355
366
  uniq.
@@ -363,7 +374,7 @@ module RDF::Turtle
363
374
  # Mark as seen lists that are part of another list
364
375
  @lists.values.map(&:statements).
365
376
  flatten.each do |st|
366
- seen[st.object] if @lists.has_key?(st.object)
377
+ seen[st.object] = true if @lists.has_key?(st.object)
367
378
  end
368
379
 
369
380
  # List elements which are bnodes should not be targets for top-level serialization
@@ -447,7 +458,8 @@ module RDF::Turtle
447
458
  # @return [String]
448
459
  def quoted(string)
449
460
  if string.to_s.match(/[\t\n\r]/)
450
- string = string.gsub('\\', '\\\\\\\\').gsub('"""', '\\"""')
461
+ string = string.gsub('\\', '\\\\\\\\').gsub('"', '\\"')
462
+
451
463
  %("""#{string}""")
452
464
  else
453
465
  "\"#{escaped(string)}\""
@@ -456,7 +468,7 @@ module RDF::Turtle
456
468
 
457
469
  # Can subject be represented as a blankNodePropertyList?
458
470
  def blankNodePropertyList?(resource, position)
459
- resource.node? &&
471
+ !resource.statement? && resource.node? &&
460
472
  !is_valid_list?(resource) &&
461
473
  (!is_done?(resource) || position == :subject) &&
462
474
  ref_count(resource) == (position == :object ? 1 : 0)
@@ -545,7 +557,7 @@ module RDF::Turtle
545
557
  l = if resource == RDF.nil
546
558
  "()"
547
559
  else
548
- format_term(resource, options)
560
+ format_term(resource, **options)
549
561
  end
550
562
  @output.write(l)
551
563
  end
@@ -594,7 +606,7 @@ module RDF::Turtle
594
606
  # @return [Integer] the number of properties serialized
595
607
  def predicateObjectList(subject, from_bpl = false)
596
608
  properties = {}
597
- @graph.query(subject: subject) do |st|
609
+ @graph.query({subject: subject}) do |st|
598
610
  (properties[st.predicate.to_s] ||= []) << st.object
599
611
  end
600
612
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rdf-turtle
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.4
4
+ version: 3.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gregg Kellogg
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-01-23 00:00:00.000000000 Z
11
+ date: 2020-07-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rdf
@@ -16,146 +16,146 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '3.0'
19
+ version: '3.1'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 3.1.2
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
27
  - - "~>"
25
28
  - !ruby/object:Gem::Version
26
- version: '3.0'
29
+ version: '3.1'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 3.1.2
27
33
  - !ruby/object:Gem::Dependency
28
34
  name: ebnf
29
35
  requirement: !ruby/object:Gem::Requirement
30
36
  requirements:
31
37
  - - "~>"
32
38
  - !ruby/object:Gem::Version
33
- version: '1.1'
39
+ version: '2.0'
34
40
  type: :runtime
35
41
  prerelease: false
36
42
  version_requirements: !ruby/object:Gem::Requirement
37
43
  requirements:
38
44
  - - "~>"
39
45
  - !ruby/object:Gem::Version
40
- version: '1.1'
46
+ version: '2.0'
41
47
  - !ruby/object:Gem::Dependency
42
48
  name: rspec
43
49
  requirement: !ruby/object:Gem::Requirement
44
50
  requirements:
45
51
  - - "~>"
46
52
  - !ruby/object:Gem::Version
47
- version: '3.7'
53
+ version: '3.9'
48
54
  type: :development
49
55
  prerelease: false
50
56
  version_requirements: !ruby/object:Gem::Requirement
51
57
  requirements:
52
58
  - - "~>"
53
59
  - !ruby/object:Gem::Version
54
- version: '3.7'
60
+ version: '3.9'
55
61
  - !ruby/object:Gem::Dependency
56
62
  name: rspec-its
57
63
  requirement: !ruby/object:Gem::Requirement
58
64
  requirements:
59
65
  - - "~>"
60
66
  - !ruby/object:Gem::Version
61
- version: '1.2'
67
+ version: '1.3'
62
68
  type: :development
63
69
  prerelease: false
64
70
  version_requirements: !ruby/object:Gem::Requirement
65
71
  requirements:
66
72
  - - "~>"
67
73
  - !ruby/object:Gem::Version
68
- version: '1.2'
74
+ version: '1.3'
69
75
  - !ruby/object:Gem::Dependency
70
76
  name: rdf-isomorphic
71
77
  requirement: !ruby/object:Gem::Requirement
72
78
  requirements:
73
79
  - - "~>"
74
80
  - !ruby/object:Gem::Version
75
- version: '3.0'
81
+ version: '3.1'
76
82
  type: :development
77
83
  prerelease: false
78
84
  version_requirements: !ruby/object:Gem::Requirement
79
85
  requirements:
80
86
  - - "~>"
81
87
  - !ruby/object:Gem::Version
82
- version: '3.0'
88
+ version: '3.1'
83
89
  - !ruby/object:Gem::Dependency
84
- name: rdf-spec
90
+ name: json-ld
85
91
  requirement: !ruby/object:Gem::Requirement
86
92
  requirements:
87
93
  - - "~>"
88
94
  - !ruby/object:Gem::Version
89
- version: '3.0'
95
+ version: '3.1'
90
96
  type: :development
91
97
  prerelease: false
92
98
  version_requirements: !ruby/object:Gem::Requirement
93
99
  requirements:
94
100
  - - "~>"
95
101
  - !ruby/object:Gem::Version
96
- version: '3.0'
102
+ version: '3.1'
97
103
  - !ruby/object:Gem::Dependency
98
- name: rdf-vocab
104
+ name: rdf-spec
99
105
  requirement: !ruby/object:Gem::Requirement
100
106
  requirements:
101
107
  - - "~>"
102
108
  - !ruby/object:Gem::Version
103
- version: '3.0'
109
+ version: '3.1'
104
110
  type: :development
105
111
  prerelease: false
106
112
  version_requirements: !ruby/object:Gem::Requirement
107
113
  requirements:
108
114
  - - "~>"
109
115
  - !ruby/object:Gem::Version
110
- version: '3.0'
116
+ version: '3.1'
111
117
  - !ruby/object:Gem::Dependency
112
- name: json-ld
118
+ name: rdf-vocab
113
119
  requirement: !ruby/object:Gem::Requirement
114
120
  requirements:
115
- - - ">="
116
- - !ruby/object:Gem::Version
117
- version: '2.1'
118
- - - "<"
121
+ - - "~>"
119
122
  - !ruby/object:Gem::Version
120
- version: '4.0'
123
+ version: '3.1'
121
124
  type: :development
122
125
  prerelease: false
123
126
  version_requirements: !ruby/object:Gem::Requirement
124
127
  requirements:
125
- - - ">="
126
- - !ruby/object:Gem::Version
127
- version: '2.1'
128
- - - "<"
128
+ - - "~>"
129
129
  - !ruby/object:Gem::Version
130
- version: '4.0'
130
+ version: '3.1'
131
131
  - !ruby/object:Gem::Dependency
132
132
  name: rake
133
133
  requirement: !ruby/object:Gem::Requirement
134
134
  requirements:
135
135
  - - "~>"
136
136
  - !ruby/object:Gem::Version
137
- version: '12.0'
137
+ version: '13.0'
138
138
  type: :development
139
139
  prerelease: false
140
140
  version_requirements: !ruby/object:Gem::Requirement
141
141
  requirements:
142
142
  - - "~>"
143
143
  - !ruby/object:Gem::Version
144
- version: '12.0'
144
+ version: '13.0'
145
145
  - !ruby/object:Gem::Dependency
146
146
  name: yard
147
147
  requirement: !ruby/object:Gem::Requirement
148
148
  requirements:
149
149
  - - "~>"
150
150
  - !ruby/object:Gem::Version
151
- version: 0.9.12
151
+ version: 0.9.20
152
152
  type: :development
153
153
  prerelease: false
154
154
  version_requirements: !ruby/object:Gem::Requirement
155
155
  requirements:
156
156
  - - "~>"
157
157
  - !ruby/object:Gem::Version
158
- version: 0.9.12
158
+ version: 0.9.20
159
159
  description: RDF::Turtle is an Turtle reader/writer for the RDF.rb library suite.
160
160
  email: public-rdf-ruby@w3.org
161
161
  executables: []
@@ -175,7 +175,7 @@ files:
175
175
  - lib/rdf/turtle/terminals.rb
176
176
  - lib/rdf/turtle/version.rb
177
177
  - lib/rdf/turtle/writer.rb
178
- homepage: http://ruby-rdf.github.com/rdf-turtle
178
+ homepage: https://github.com/ruby-rdf/rdf-turtle
179
179
  licenses:
180
180
  - Unlicense
181
181
  metadata: {}
@@ -187,14 +187,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
187
187
  requirements:
188
188
  - - ">="
189
189
  - !ruby/object:Gem::Version
190
- version: 2.2.2
190
+ version: '2.4'
191
191
  required_rubygems_version: !ruby/object:Gem::Requirement
192
192
  requirements:
193
193
  - - ">="
194
194
  - !ruby/object:Gem::Version
195
195
  version: '0'
196
196
  requirements: []
197
- rubygems_version: 3.0.2
197
+ rubygems_version: 3.1.3
198
198
  signing_key:
199
199
  specification_version: 4
200
200
  summary: Turtle reader/writer for Ruby.