rdf-trig 0.0.1

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.
@@ -0,0 +1,118 @@
1
+ require 'rdf/trig/meta'
2
+ require 'rdf/turtle'
3
+
4
+ module RDF::TriG
5
+ ##
6
+ # A parser for the TriG
7
+ #
8
+ # Leverages the Turtle reader
9
+ class Reader < RDF::Turtle::Reader
10
+ format Format
11
+ include RDF::TriG::Meta
12
+
13
+ # String terminals
14
+ terminal(nil, %r([\{\}\(\),.;\[\]a]|\^\^|@base|@prefix|true|false)) do |reader, prod, token, input|
15
+ case token.value
16
+ when 'a' then input[:resource] = RDF.type
17
+ when 'true', 'false' then input[:resource] = RDF::Literal::Boolean.new(token.value)
18
+ else input[:string] = token.value
19
+ end
20
+ end
21
+ terminal(:LANGTAG, LANGTAG) do |reader, prod, token, input|
22
+ input[:lang] = token.value[1..-1]
23
+ end
24
+
25
+ # Productions
26
+ # [3g] graph defines the basic creation of context
27
+ production(:graph) do |reader, phase, input, current, callback|
28
+ current[:context] = nil
29
+ end
30
+
31
+ # [4g] graphIri
32
+ # Normally, just returns the IRIref, but if called from [3g], also
33
+ # sets the context for triples defined within that graph
34
+ production(:graphIri) do |reader, phase, input, current, callback|
35
+ # If input contains set_graph_iri, use the returned value to set @context
36
+ if phase == :finish
37
+ callback.call(:trace, "graphIri", lambda {"Set graph context to #{current[:resource]}"})
38
+ input[:context] = current[:resource]
39
+ end
40
+ end
41
+
42
+ # [12] object ::= IRIref | blank | literal
43
+ production(:object) do |reader, phase, input, current, callback|
44
+ next unless phase == :finish
45
+ if input[:object_list]
46
+ # Part of an rdf:List collection
47
+ input[:object_list] << current[:resource]
48
+ else
49
+ callback.call(:trace, "object", lambda {"current: #{current.inspect}"})
50
+ callback.call(:statement, "object", input[:subject], input[:predicate], current[:resource], input[:context])
51
+ end
52
+ end
53
+
54
+ # [16] collection ::= "(" object* ")"
55
+ production(:collection) do |reader, phase, input, current, callback|
56
+ if phase == :start
57
+ current[:object_list] = [] # Tells the object production to collect and not generate statements
58
+ else
59
+ # Create an RDF list
60
+ bnode = reader.bnode
61
+ objects = current[:object_list]
62
+ list = RDF::List.new(bnode, nil, objects)
63
+ list.each_statement do |statement|
64
+ # Spec Confusion, referenced section "Collection" is missing from the spec.
65
+ # Anicdodal evidence indicates that some expect each node to be of type rdf:list,
66
+ # but existing Notation3 and Turtle tests (http://www.w3.org/2001/sw/DataAccess/df1/tests/manifest.ttl) do not.
67
+ next if statement.predicate == RDF.type && statement.object == RDF.List
68
+ callback.call(:statement, "collection", statement.subject, statement.predicate, statement.object, input[:context])
69
+ end
70
+ bnode = RDF.nil if list.empty?
71
+
72
+ # Return bnode as resource
73
+ input[:resource] = bnode
74
+ end
75
+ end
76
+
77
+ ##
78
+ # Iterates the given block for each RDF statement in the input.
79
+ #
80
+ # @yield [statement]
81
+ # @yieldparam [RDF::Statement] statement
82
+ # @return [void]
83
+ def each_statement(&block)
84
+ @callback = block
85
+
86
+ parse(@input, START.to_sym, @options.merge(:branch => BRANCH,
87
+ :first => FIRST,
88
+ :follow => FOLLOW)
89
+ ) do |context, *data|
90
+ loc = data.shift
91
+ case context
92
+ when :statement
93
+ add_statement(loc, RDF::Statement.from(data))
94
+ when :trace
95
+ debug(loc, *data)
96
+ end
97
+ end
98
+ rescue RDF::LL1::Parser::Error => e
99
+ debug("Parsing completed with errors:\n\t#{e.message}")
100
+ raise RDF::ReaderError, e.message if validate?
101
+ end
102
+
103
+ ##
104
+ # Iterates the given block for each RDF quad in the input.
105
+ #
106
+ # @yield [subject, predicate, object, context]
107
+ # @yieldparam [RDF::Resource] subject
108
+ # @yieldparam [RDF::URI] predicate
109
+ # @yieldparam [RDF::Value] object
110
+ # @yieldparam [RDF::URI] context
111
+ # @return [void]
112
+ def each_quad(&block)
113
+ each_statement do |statement|
114
+ block.call(*statement.to_quad)
115
+ end
116
+ end
117
+ end # class Reader
118
+ end # module RDF::Turtle
@@ -0,0 +1,18 @@
1
+ module RDF::TriG::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
@@ -0,0 +1,190 @@
1
+ require 'rdf/turtle'
2
+
3
+ module RDF::TriG
4
+ ##
5
+ # A TriG serialiser
6
+ #
7
+ # Note that the natural interface is to write a whole repository at a time.
8
+ # Writing statements or Triples will create a repository to add them to
9
+ # and then serialize the repository.
10
+ #
11
+ # @example Obtaining a TriG writer class
12
+ # RDF::Writer.for(:trig) #=> RDF::TriG::Writer
13
+ # RDF::Writer.for("etc/test.trig")
14
+ # RDF::Writer.for(:file_name => "etc/test.trig")
15
+ # RDF::Writer.for(:file_extension => "trig")
16
+ # RDF::Writer.for(:content_type => "application/trig")
17
+ #
18
+ # @example Serializing RDF repo into an TriG file
19
+ # RDF::TriG::Writer.open("etc/test.trig") do |writer|
20
+ # writer << repo
21
+ # end
22
+ #
23
+ # @example Serializing RDF statements into an TriG file
24
+ # RDF::TriG::Writer.open("etc/test.trig") do |writer|
25
+ # repo.each_statement do |statement|
26
+ # writer << statement
27
+ # end
28
+ # end
29
+ #
30
+ # @example Serializing RDF statements into an TriG string
31
+ # RDF::TriG::Writer.buffer do |writer|
32
+ # repo.each_statement do |statement|
33
+ # writer << statement
34
+ # end
35
+ # end
36
+ #
37
+ # The writer will add prefix definitions, and use them for creating @prefix definitions, and minting QNames
38
+ #
39
+ # @example Creating @base and @prefix definitions in output
40
+ # RDF::TriG::Writer.buffer(:base_uri => "http://example.com/", :prefixes => {
41
+ # nil => "http://example.com/ns#",
42
+ # :foaf => "http://xmlns.com/foaf/0.1/"}
43
+ # ) do |writer|
44
+ # repo.each_statement do |statement|
45
+ # writer << statement
46
+ # end
47
+ # end
48
+ #
49
+ # @author [Gregg Kellogg](http://kellogg-assoc.com/)
50
+ class Writer < RDF::Turtle::Writer
51
+ format RDF::TriG::Format
52
+
53
+ class ContextFilteredRepo
54
+ include RDF::Queryable
55
+
56
+ def initialize(repo, context)
57
+ @repo = repo
58
+ @context = context
59
+ end
60
+
61
+ # Filter statements in repository to those having the specified context
62
+ # Returns each statement having the specified context, `false` for default context
63
+ # @yield statement
64
+ # @yieldparam [RDF::Statement] statement
65
+ # @return [void]
66
+ # @see [RDF::Queryable]
67
+ def each
68
+ @repo.each_statement do |st|
69
+ case @context
70
+ when false
71
+ yield st if !st.context
72
+ else
73
+ yield st if st.context == @context
74
+ end
75
+ end
76
+ end
77
+
78
+ ##
79
+ # Proxy Repository#query_pattern
80
+ # @see RDF::Repository#query_pattern
81
+ def query_pattern(pattern, &block)
82
+ pattern.context = @context || false
83
+ @repo.send(:query_pattern, pattern, &block)
84
+ end
85
+ end
86
+
87
+ ##
88
+ # Initializes the TriG writer instance.
89
+ #
90
+ # @param [IO, File] output
91
+ # the output stream
92
+ # @param [Hash{Symbol => Object}] options
93
+ # any additional options
94
+ # @option options [Encoding] :encoding (Encoding::UTF_8)
95
+ # the encoding to use on the output stream (Ruby 1.9+)
96
+ # @option options [Boolean] :canonicalize (false)
97
+ # whether to canonicalize literals when serializing
98
+ # @option options [Hash] :prefixes (Hash.new)
99
+ # the prefix mappings to use (not supported by all writers)
100
+ # @option options [#to_s] :base_uri (nil)
101
+ # the base URI to use when constructing relative URIs
102
+ # @option options [Integer] :max_depth (3)
103
+ # Maximum depth for recursively defining resources, defaults to 3
104
+ # @option options [Boolean] :standard_prefixes (false)
105
+ # Add standard prefixes to @prefixes, if necessary.
106
+ # @option options [String] :default_namespace (nil)
107
+ # URI to use as default namespace, same as prefixes[nil]
108
+ # @yield [writer] `self`
109
+ # @yieldparam [RDF::Writer] writer
110
+ # @yieldreturn [void]
111
+ # @yield [writer]
112
+ # @yieldparam [RDF::Writer] writer
113
+ def initialize(output = $stdout, options = {}, &block)
114
+ super do
115
+ # Set both @repo and @graph to a new repository.
116
+ # When serializing a context, @graph is changed
117
+ # to a ContextFilteredRepo
118
+ @repo = @graph = RDF::Repository.new
119
+ if block_given?
120
+ case block.arity
121
+ when 0 then instance_eval(&block)
122
+ else block.call(self)
123
+ end
124
+ end
125
+ end
126
+ end
127
+
128
+ ##
129
+ # Outputs the TriG representation of all stored triples.
130
+ #
131
+ # @return [void]
132
+ # @see #write_triple
133
+ def write_epilogue
134
+ @max_depth = @options[:max_depth] || 3
135
+ @base_uri = RDF::URI(@options[:base_uri])
136
+
137
+ reset
138
+
139
+ debug {"\nserialize: repo: #{@repo.size}"}
140
+
141
+ preprocess
142
+ start_document
143
+
144
+ order_contexts.each do |ctx|
145
+ debug {"context: #{ctx.inspect}"}
146
+ reset
147
+ @depth = 2
148
+
149
+ if ctx
150
+ @output.write("\n#{format_value(ctx)} {")
151
+ else
152
+ @output.write("\n{")
153
+ end
154
+
155
+ # Restrict view to the particular context
156
+ @graph = ContextFilteredRepo.new(@repo, ctx)
157
+
158
+ # Pre-process statements again, but in the specified context
159
+ @graph.each {|st| preprocess_statement(st)}
160
+ order_subjects.each do |subject|
161
+ unless is_done?(subject)
162
+ statement(subject)
163
+ end
164
+ end
165
+
166
+ @output.puts("}")
167
+ end
168
+ end
169
+
170
+ protected
171
+ # Order contexts for output
172
+ def order_contexts
173
+ debug("order_contexts") {repo.contexts.to_a.inspect}
174
+ contexts = repo.contexts.to_a.sort
175
+
176
+ # include default context, if necessary
177
+ contexts.unshift(nil) unless repo.query(:context => false).to_a.empty?
178
+
179
+ contexts
180
+ end
181
+
182
+ # Perform any statement preprocessing required. This is used to perform reference counts and determine required
183
+ # prefixes.
184
+ # @param [Statement] statement
185
+ def preprocess_statement(statement)
186
+ super
187
+ get_pname(statement.context) if statement.has_context?
188
+ end
189
+ end
190
+ end
metadata ADDED
@@ -0,0 +1,221 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rdf-trig
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Gregg Kellogg
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-12-22 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: rdf
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ hash: 27
29
+ segments:
30
+ - 0
31
+ - 3
32
+ - 4
33
+ version: 0.3.4
34
+ type: :runtime
35
+ version_requirements: *id001
36
+ - !ruby/object:Gem::Dependency
37
+ name: rdf-turtle
38
+ prerelease: false
39
+ requirement: &id002 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ hash: 25
45
+ segments:
46
+ - 0
47
+ - 1
48
+ - 1
49
+ version: 0.1.1
50
+ type: :runtime
51
+ version_requirements: *id002
52
+ - !ruby/object:Gem::Dependency
53
+ name: open-uri-cached
54
+ prerelease: false
55
+ requirement: &id003 !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ hash: 23
61
+ segments:
62
+ - 0
63
+ - 0
64
+ - 4
65
+ version: 0.0.4
66
+ type: :development
67
+ version_requirements: *id003
68
+ - !ruby/object:Gem::Dependency
69
+ name: spira
70
+ prerelease: false
71
+ requirement: &id004 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ hash: 7
77
+ segments:
78
+ - 0
79
+ - 0
80
+ - 12
81
+ version: 0.0.12
82
+ type: :development
83
+ version_requirements: *id004
84
+ - !ruby/object:Gem::Dependency
85
+ name: rspec
86
+ prerelease: false
87
+ requirement: &id005 !ruby/object:Gem::Requirement
88
+ none: false
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ hash: 27
93
+ segments:
94
+ - 2
95
+ - 5
96
+ - 0
97
+ version: 2.5.0
98
+ type: :development
99
+ version_requirements: *id005
100
+ - !ruby/object:Gem::Dependency
101
+ name: rdf-isomorphic
102
+ prerelease: false
103
+ requirement: &id006 !ruby/object:Gem::Requirement
104
+ none: false
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ hash: 27
109
+ segments:
110
+ - 0
111
+ - 3
112
+ - 4
113
+ version: 0.3.4
114
+ type: :development
115
+ version_requirements: *id006
116
+ - !ruby/object:Gem::Dependency
117
+ name: rdf-n3
118
+ prerelease: false
119
+ requirement: &id007 !ruby/object:Gem::Requirement
120
+ none: false
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ hash: 25
125
+ segments:
126
+ - 0
127
+ - 3
128
+ - 5
129
+ version: 0.3.5
130
+ type: :development
131
+ version_requirements: *id007
132
+ - !ruby/object:Gem::Dependency
133
+ name: rdf-spec
134
+ prerelease: false
135
+ requirement: &id008 !ruby/object:Gem::Requirement
136
+ none: false
137
+ requirements:
138
+ - - ">="
139
+ - !ruby/object:Gem::Version
140
+ hash: 27
141
+ segments:
142
+ - 0
143
+ - 3
144
+ - 4
145
+ version: 0.3.4
146
+ type: :development
147
+ version_requirements: *id008
148
+ - !ruby/object:Gem::Dependency
149
+ name: yard
150
+ prerelease: false
151
+ requirement: &id009 !ruby/object:Gem::Requirement
152
+ none: false
153
+ requirements:
154
+ - - ">="
155
+ - !ruby/object:Gem::Version
156
+ hash: 7
157
+ segments:
158
+ - 0
159
+ - 6
160
+ - 0
161
+ version: 0.6.0
162
+ type: :development
163
+ version_requirements: *id009
164
+ description: RDF::TriG is an TriG reader/writer for the RDF.rb library suite.
165
+ email: public-rdf-ruby@w3.org
166
+ executables: []
167
+
168
+ extensions: []
169
+
170
+ extra_rdoc_files: []
171
+
172
+ files:
173
+ - AUTHORS
174
+ - README.markdown
175
+ - History
176
+ - UNLICENSE
177
+ - VERSION
178
+ - lib/rdf/trig/format.rb
179
+ - lib/rdf/trig/meta.rb
180
+ - lib/rdf/trig/reader.rb
181
+ - lib/rdf/trig/version.rb
182
+ - lib/rdf/trig/writer.rb
183
+ - lib/rdf/trig.rb
184
+ homepage: http://github.com/gkellogg/rdf-trig
185
+ licenses:
186
+ - Public Domain
187
+ post_install_message:
188
+ rdoc_options: []
189
+
190
+ require_paths:
191
+ - lib
192
+ required_ruby_version: !ruby/object:Gem::Requirement
193
+ none: false
194
+ requirements:
195
+ - - ">="
196
+ - !ruby/object:Gem::Version
197
+ hash: 53
198
+ segments:
199
+ - 1
200
+ - 8
201
+ - 1
202
+ version: 1.8.1
203
+ required_rubygems_version: !ruby/object:Gem::Requirement
204
+ none: false
205
+ requirements:
206
+ - - ">="
207
+ - !ruby/object:Gem::Version
208
+ hash: 3
209
+ segments:
210
+ - 0
211
+ version: "0"
212
+ requirements: []
213
+
214
+ rubyforge_project: rdf-trig
215
+ rubygems_version: 1.8.10
216
+ signing_key:
217
+ specification_version: 3
218
+ summary: TriG reader/writer for Ruby.
219
+ test_files: []
220
+
221
+ has_rdoc: false