Skip to content

Commit 877b229

Browse files
committed
Write out version declaration if provided via option, or a triple which uses 1.2 features is found.
1 parent 9f5b2ba commit 877b229

File tree

3 files changed

+86
-19
lines changed

3 files changed

+86
-19
lines changed

lib/rdf/turtle/writer.rb

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ class Writer < RDF::Writer
6363
# @return [Graph] Graph of statements serialized
6464
attr_accessor :graph
6565

66+
# @return [String] RDF Version of output
67+
attr_accessor :version
68+
6669
##
6770
# Writer options
6871
# @see https://ruby-rdf.github.io/rdf/RDF/Writer#options-class_method
@@ -88,6 +91,12 @@ def self.options
8891
datatype: FalseClass,
8992
on: ["--no-literal-shorthand"],
9093
description: "Do not attempt to use Literal shorthands fo numbers and boolean values.") {false},
94+
RDF::CLI::Option.new(
95+
symbol: :version,
96+
control: :select,
97+
datatype: %w{1.1 1.2 1.2-basic},
98+
on: ["--version"],
99+
description: "RDF Version."),
91100
]
92101
end
93102

@@ -118,6 +127,8 @@ def self.options
118127
# Use unique node identifiers, defaults to using the identifier which the node was originall initialized with (if any).
119128
# @option options [Boolean] :literal_shorthand (true)
120129
# Attempt to use Literal shorthands for numbers and boolean values
130+
# @option options [String] :version ("1.2")
131+
# Emit a specific version of RDF ("1.1', "1.2", or "1.2-basic"")
121132
# @yield [writer] `self`
122133
# @yieldparam [RDF::Writer] writer
123134
# @yieldreturn [void]
@@ -127,6 +138,7 @@ def initialize(output = $stdout, **options, &block)
127138
@graph = RDF::Graph.new
128139
@uri_to_pname = {}
129140
@uri_to_prefix = {}
141+
@version = options[:version]
130142
options = {literal_shorthand: true}.merge(options)
131143
super do
132144
reset
@@ -340,8 +352,9 @@ def format_tripleTerm(statement, **options)
340352
end
341353

342354
protected
343-
# Output @base and @prefix definitions
355+
# Output @base, @prefix, and @version definitions
344356
def start_document
357+
@output.write("#{indent}@version #{version.inspect} .\n") if version
345358
@output.write("#{indent}@base <#{base_uri}> .\n") unless base_uri.to_s.empty?
346359

347360
log_debug("start_document") {prefixes.inspect}
@@ -431,6 +444,13 @@ def preprocess_statement(statement, as_subject: true)
431444
#log_debug("preprocess") {statement.to_ntriples}
432445
bump_reference(statement.object)
433446

447+
# Set RDF version to 1.2, if unset and required.
448+
if version.nil? && (statement.object.statement? || statement.object.literal? && statement.object.direction?)
449+
@version = "1.2"
450+
end
451+
452+
# TODO: what to do if version is "1.1" or "1.2-basic"?
453+
434454
# Also count references of triple terms
435455
preprocess_statement(statement.object, as_subject: false) if statement.object.statement?
436456

rdf-turtle.gemspec

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,14 @@ Gem::Specification.new do |gem|
2828
gem.required_ruby_version = '>= 3.0'
2929
gem.requirements = []
3030
gem.add_runtime_dependency 'rdf', '~> 3.3'
31-
gem.add_runtime_dependency 'ebnf', '~> 2.5'
31+
gem.add_runtime_dependency 'ebnf', '~> 2.6'
3232
gem.add_runtime_dependency 'base64', '~> 0.2'
33-
gem.add_runtime_dependency 'bigdecimal', '~> 3.1', '>= 3.1.5'
33+
gem.add_runtime_dependency 'bigdecimal', '~> 3.1', '>= 3.1.9'
3434
gem.add_development_dependency 'erubis', '~> 2.7'
3535
gem.add_development_dependency 'getoptlong', '~> 0.2'
3636
gem.add_development_dependency 'htmlentities', '~> 4.3'
3737
gem.add_runtime_dependency 'readline', '~> 0.0'
38-
gem.add_development_dependency 'rspec', '~> 3.12'
38+
gem.add_development_dependency 'rspec', '~> 3.13'
3939
gem.add_development_dependency 'rspec-its', '~> 1.3'
4040
gem.add_development_dependency 'rdf-isomorphic', '~> 3.3'
4141
gem.add_development_dependency 'json-ld', '~> 3.3'

spec/writer_spec.rb

Lines changed: 62 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -347,8 +347,8 @@
347347
end
348348

349349
it "specifies language for literal with language and direction" do
350-
ttl = %q(<http://a> <http:/b> "string"@en-ltr .)
351-
serialize(ttl, [%r("string"@en-ltr)])
350+
ttl = %q(<http://a> <http:/b> "string"@en--ltr .)
351+
serialize(ttl, [%r(@version "1.2" \.), %r("string"@en--ltr)])
352352
end
353353
end
354354

@@ -611,7 +611,10 @@
611611
RDF::URI('http://example/p1'),
612612
RDF::URI('http://example/o1'),
613613
tripleTerm: true)),
614-
regexp: [%r(ex:s ex:p <<\(ex:s1 ex:p1 ex:o1\)>> .)]
614+
regexp: [
615+
%r(@version "1.2" \.),
616+
%r(ex:s ex:p <<\(ex:s1 ex:p1 ex:o1\)>> .)
617+
]
615618
},
616619
"object-iib": {
617620
input: RDF::Statement(
@@ -622,7 +625,10 @@
622625
RDF::URI('http://example/p1'),
623626
RDF::Node.new('o1'),
624627
tripleTerm: true)),
625-
regexp: [%r(ex:s ex:p <<\(ex:s1 ex:p1 _:o1\)>> .)]
628+
regexp: [
629+
%r(@version "1.2" \.),
630+
%r(ex:s ex:p <<\(ex:s1 ex:p1 _:o1\)>> .)
631+
]
626632
},
627633
"object-iil": {
628634
input: RDF::Statement(
@@ -633,7 +639,10 @@
633639
RDF::URI('http://example/p1'),
634640
RDF::Literal('o1'),
635641
tripleTerm: true)),
636-
regexp: [%r(ex:s ex:p <<\(ex:s1 ex:p1 "o1"\)>> .)],
642+
regexp: [
643+
%r(@version "1.2" \.),
644+
%r(ex:s ex:p <<\(ex:s1 ex:p1 "o1"\)>> .)
645+
],
637646
},
638647
"recursive-object": {
639648
input: RDF::Statement(
@@ -651,6 +660,7 @@
651660
)
652661
),
653662
regexp: [
663+
%r(@version "1.2" \.),
654664
%r(ex:s ex:p <<\(\s*ex:s1 ex:p1 <<\(\s*ex:s2 ex:p2 ex:o2*\s*\)>>\s*\)>>)
655665
]
656666
}
@@ -669,71 +679,98 @@
669679
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
670680
<< :s1 :p1 :o1 >> :p :o .
671681
),
672-
regexp: [%r(<<\s*ex:s1 ex:p1 ex:o1\s*>> ex:p ex:o .)]
682+
regexp: [
683+
%r(@version "1.2" \.),
684+
%r(<<\s*ex:s1 ex:p1 ex:o1\s*>> ex:p ex:o .)
685+
]
673686
},
674687
"subject-iib": {
675688
input: %(
676689
PREFIX : <http://example/>
677690
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
678691
<< :s1 :p1 _:o1 >> :p :o .
679692
),
680-
regexp: [%r(<<\s*ex:s1 ex:p1 _:o1\s*>> ex:p ex:o .)]
693+
regexp: [
694+
%r(@version "1.2" \.),
695+
%r(<<\s*ex:s1 ex:p1 _:o1\s*>> ex:p ex:o .)
696+
]
681697
},
682698
"subject-iil": {
683699
input: %(
684700
PREFIX : <http://example/>
685701
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
686702
<< :s1 :p1 "o1" >> :p :o .
687703
),
688-
regexp: [%r(<<\s*ex:s1 ex:p1 "o1"\s*>> ex:p ex:o .)]
704+
regexp: [
705+
%r(@version "1.2" \.),
706+
%r(<<\s*ex:s1 ex:p1 "o1"\s*>> ex:p ex:o .)
707+
]
689708
},
690709
"subject-bn-no-prop": {
691710
input: %(
692711
PREFIX : <http://example/>
693712
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
694713
_:reif rdf:reifies <<( :s1 :p1 :o1 )>> .
695714
),
696-
regexp: [%r(\[\s*rdf:reifies <<\(\s*ex:s1 ex:p1 ex:o1\s*\)>>\] .)]
715+
regexp: [
716+
%r(@version "1.2" \.),
717+
%r(\[\s*rdf:reifies <<\(\s*ex:s1 ex:p1 ex:o1\s*\)>>\] .)
718+
]
697719
},
698720
"subject-iri-no-prop": {
699721
input: %(
700722
PREFIX : <http://example/>
701723
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
702724
:reif rdf:reifies <<( :s1 :p1 :o1 )>> .
703725
),
704-
regexp: [%r(ex:reif *rdf:reifies <<\(\s*ex:s1 ex:p1 ex:o1\s*\)>> .)]
726+
regexp: [
727+
%r(@version "1.2" \.),
728+
%r(ex:reif *rdf:reifies <<\(\s*ex:s1 ex:p1 ex:o1\s*\)>> .)
729+
]
705730
},
706731
"subject-bn-no-prop-multiple": {
707732
input: %(
708733
PREFIX : <http://example/>
709734
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
710735
_:reif rdf:reifies <<( :s1 :p1 :o1 )>>, <<( :s2 :p2 :o2 )>> .
711736
),
712-
regexp: [%r(\[\s*rdf:reifies <<\(\s*ex:s1 ex:p1 ex:o1\s*\)>>,\s+<<\(\s*ex:s2 ex:p2 ex:o2\s*\)>>\] .)m]
737+
regexp: [
738+
%r(@version "1.2" \.),
739+
%r(\[\s*rdf:reifies <<\(\s*ex:s1 ex:p1 ex:o1\s*\)>>,\s+<<\(\s*ex:s2 ex:p2 ex:o2\s*\)>>\] .)m
740+
]
713741
},
714742
"object-iii": {
715743
input: %(
716744
PREFIX : <http://example/>
717745
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
718746
:s :p << :s1 :p1 :o1 >> .
719747
),
720-
regexp: [%r(ex:s ex:p <<\s*ex:s1 ex:p1 ex:o1\s*>> .)]
748+
regexp: [
749+
%r(@version "1.2" \.),
750+
%r(ex:s ex:p <<\s*ex:s1 ex:p1 ex:o1\s*>> .)
751+
]
721752
},
722753
"object-iib": {
723754
input: %(
724755
PREFIX : <http://example/>
725756
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
726757
:s :p << :s1 :p1 _:o1 >> .
727758
),
728-
regexp: [%r(ex:s ex:p <<\s*ex:s1 ex:p1 _:o1\s*>> .)]
759+
regexp: [
760+
%r(@version "1.2" \.),
761+
%r(ex:s ex:p <<\s*ex:s1 ex:p1 _:o1\s*>> .)
762+
]
729763
},
730764
"object-iil": {
731765
input: %(
732766
PREFIX : <http://example/>
733767
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
734768
:s :p << :s1 :p1 "o1" >> .
735769
),
736-
regexp: [%r(ex:s ex:p <<\s*ex:s1 ex:p1 "o1"\s*>> .)]
770+
regexp: [
771+
%r(@version "1.2" \.),
772+
%r(ex:s ex:p <<\s*ex:s1 ex:p1 "o1"\s*>> .)
773+
]
737774
},
738775
"bnode-01": {
739776
# Bnode in two positions
@@ -743,6 +780,7 @@
743780
<<_:a :p2 :o2 >> :q 456 .
744781
),
745782
regexp: [
783+
%r(@version "1.2" \.),
746784
%r(_:a ex:p1 ex:o1 .),
747785
%r(<<\s*_:a ex:p2 ex:o2\s*>> ex:q 456 .)
748786
]
@@ -753,6 +791,7 @@
753791
:s :p << :s1 :p1 << :s2 :p2 :o2 >> >> .
754792
),
755793
regexp: [
794+
%r(@version "1.2" \.),
756795
%r(ex:s ex:p <<\s*ex:s1 ex:p1 <<\s*ex:s2 ex:p2 ex:o2\s*>>\s*>> .)
757796
]
758797
},
@@ -762,6 +801,7 @@
762801
<< << :s2 :p2 :o2 >> :p1 :o1 >> :p :o .
763802
),
764803
regexp: [
804+
%r(@version "1.2" \.),
765805
%r(<<\s*<<\s*ex:s2 ex:p2 ex:o2\s*>> ex:p1 ex:o1\s*>> ex:p ex:o .)
766806
]
767807
},
@@ -773,6 +813,7 @@
773813
:r :p1 :o1 .
774814
),
775815
regexp: [
816+
%r(@version "1.2" \.),
776817
%r(<<\s*ex:s ex:p ex:o\s*~\s*ex:r\s*>>\s*ex:p1 ex:o1 .)
777818
]
778819
},
@@ -784,6 +825,7 @@
784825
:s1 :p1 :r .
785826
),
786827
regexp: [
828+
%r(@version "1.2" \.),
787829
%r(ex:s1 ex:p1 <<\s*ex:s ex:p ex:o\s*~\s*ex:r\s*>>\s*.)
788830
]
789831
},
@@ -807,6 +849,7 @@
807849
:s :p :o {| :r :z |} .
808850
),
809851
regexp: [
852+
%r(@version "1.2" \.),
810853
%r(ex:s ex:p ex:o {\|\s+ex:r ex:z\s+\|} \.)m
811854
]
812855
},
@@ -824,6 +867,7 @@
824867
|} .
825868
),
826869
regexp: [
870+
%r(@version "1.2" \.),
827871
%r(ex:s ex:p ex:o {\|\s+ex:source \[)m,
828872
%r(\s+ex:date "2020-01-20"\^\^<http://www.w3.org/2001/XMLSchema#date>;),
829873
%r(\s+ex:graph <http://host1/>),
@@ -846,7 +890,10 @@
846890
describe "w3c turtle tests" do
847891
require 'suite_helper'
848892

849-
%w(rdf11/rdf-turtle/manifest.ttl).each do |man|
893+
%w(rdf11/rdf-turtle/manifest.ttl
894+
rdf12/rdf-turtle/syntax/manifest.ttl
895+
rdf12/rdf-turtle/eval/manifest.ttl
896+
).each do |man|
850897
Fixtures::SuiteTest::Manifest.open(Fixtures::SuiteTest::BASE + man) do |m|
851898
describe m.comment do
852899
m.entries.each do |t|

0 commit comments

Comments
 (0)