annotations2triannon 0.1.0
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.
- checksums.yaml +7 -0
- data/.env_example +44 -0
- data/.travis.yml +15 -0
- data/Gemfile +5 -0
- data/LICENSE +202 -0
- data/README.md +31 -0
- data/Rakefile +50 -0
- data/annotations2triannon.gemspec +58 -0
- data/bin/console +5 -0
- data/bin/ctags.rb +8 -0
- data/bin/dms.rb +175 -0
- data/bin/revs.rb +17 -0
- data/bin/revs_annotations2csv.sh +66 -0
- data/lib/annotations2triannon/annotation_list.rb +37 -0
- data/lib/annotations2triannon/configuration.rb +52 -0
- data/lib/annotations2triannon/iiif_annotation_list.rb +17 -0
- data/lib/annotations2triannon/iiif_collection.rb +56 -0
- data/lib/annotations2triannon/iiif_manifest.rb +32 -0
- data/lib/annotations2triannon/iiif_navigator.rb +172 -0
- data/lib/annotations2triannon/manifest.rb +86 -0
- data/lib/annotations2triannon/open_annotation.rb +262 -0
- data/lib/annotations2triannon/open_annotation_harvest.rb +37 -0
- data/lib/annotations2triannon/resource.rb +264 -0
- data/lib/annotations2triannon/revs.rb +263 -0
- data/lib/annotations2triannon/revs_db.rb +69 -0
- data/lib/annotations2triannon/shared_canvas_annotation_list.rb +18 -0
- data/lib/annotations2triannon/shared_canvas_manifest.rb +32 -0
- data/lib/annotations2triannon.rb +27 -0
- data/lib/rdf/vocab/Content.rb +112 -0
- data/lib/rdf/vocab/sc.rb +233 -0
- data/lib/requires.rb +69 -0
- data/log/.gitignore +4 -0
- data/spec/lib/annotations2triannon/configuration_spec.rb +24 -0
- data/spec/lib/annotations2triannon/open_annotation_spec.rb +176 -0
- data/spec/lib/annotations2triannon/resource_spec.rb +53 -0
- data/spec/lib/annotations2triannon_spec.rb +45 -0
- data/spec/spec_helper.rb +10 -0
- metadata +387 -0
@@ -0,0 +1,263 @@
|
|
1
|
+
|
2
|
+
require_relative 'revs_db'
|
3
|
+
|
4
|
+
module Annotations2triannon
|
5
|
+
|
6
|
+
class Revs
|
7
|
+
|
8
|
+
attr_accessor :db
|
9
|
+
attr_accessor :open_annotations
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@db = Annotations2triannon::RevsDb.new
|
13
|
+
end
|
14
|
+
|
15
|
+
def open_annotations
|
16
|
+
# convert all the annotations
|
17
|
+
user_id = nil
|
18
|
+
oa_list = []
|
19
|
+
@db.annotation_ids.each do |a|
|
20
|
+
# the annotation_ids are sorted by user, so there's no
|
21
|
+
# need to retrieve the user data for every annotation.
|
22
|
+
if user_id != a[:user_id]
|
23
|
+
user = user_rdf(a[:user_id])
|
24
|
+
end
|
25
|
+
annotation = @db.annotation(a[:id])
|
26
|
+
oa_list << annotation2oa(annotation, user)
|
27
|
+
end
|
28
|
+
oa_list
|
29
|
+
end
|
30
|
+
|
31
|
+
def open_annotations_as_jsonld
|
32
|
+
oa_list = open_annotations
|
33
|
+
oa_list.collect {|a| a.as_jsonld }
|
34
|
+
end
|
35
|
+
|
36
|
+
def open_annotation(id=nil)
|
37
|
+
# Not using a join, because some annotations may be anonymous.
|
38
|
+
# join = r.db.annotations.join_table(:inner, r.db.users, :id=>:user_id)
|
39
|
+
raise 'Invalid annotation ID' if id.nil?
|
40
|
+
# find and convert an annotation by id
|
41
|
+
annotation = @db.annotation(id)
|
42
|
+
raise "No annotation with id => #{id}" if annotation.nil?
|
43
|
+
user = user_rdf(annotation[:user_id])
|
44
|
+
annotation2oa(annotation, user)
|
45
|
+
end
|
46
|
+
|
47
|
+
def user_rdf(user_id)
|
48
|
+
user = @db.user(user_id)
|
49
|
+
user_id = sprintf 'revs_user_%04d', user[:id]
|
50
|
+
user_uri = RDF::URI.parse(user_id)
|
51
|
+
# avoid creation of blank nodes?
|
52
|
+
# user_node = RDF::Node.new(user_uri)
|
53
|
+
user_graph = RDF::Graph.new
|
54
|
+
user_graph.insert([user_uri, RDF.type, RDF::SCHEMA.Person])
|
55
|
+
# user_info = RDF::Literal.new("REVS user id: #{user[:id]}")
|
56
|
+
# user_graph.insert([user_uri, RDF::SCHEMA.description, user_info])
|
57
|
+
if user[:public]
|
58
|
+
unless user[:first_name].nil? || user[:first_name].empty?
|
59
|
+
# TODO: add language tags?
|
60
|
+
#fn = RDF::Literal.new(user[:first_name], :language => :en)
|
61
|
+
fn = RDF::Literal.new(user[:first_name])
|
62
|
+
user_graph.insert([user_uri, RDF::SCHEMA.givenName, fn])
|
63
|
+
end
|
64
|
+
unless user[:last_name].nil? || user[:last_name].empty?
|
65
|
+
#ln = RDF::Literal.new(user[:last_name], :language => :en)
|
66
|
+
ln = RDF::Literal.new(user[:last_name])
|
67
|
+
user_graph.insert([user_uri, RDF::SCHEMA.familyName, ln])
|
68
|
+
end
|
69
|
+
unless user[:bio].nil? || user[:bio].empty?
|
70
|
+
#description = RDF::Literal.new(user[:bio], :language => :en)
|
71
|
+
description = RDF::Literal.new(user[:bio])
|
72
|
+
user_graph.insert([user_uri, RDF::SCHEMA.description, description])
|
73
|
+
end
|
74
|
+
unless user[:email].nil? || user[:email].empty?
|
75
|
+
email = RDF::URI.parse('mailto:' + user[:email])
|
76
|
+
user_graph.insert([user_uri, RDF::SCHEMA.email, email])
|
77
|
+
end
|
78
|
+
unless user[:url].nil? || user[:url].empty?
|
79
|
+
url = user[:url]
|
80
|
+
url = url.start_with?('http://') ? url : 'http://' + url
|
81
|
+
url = RDF::URI.parse(url)
|
82
|
+
user_graph.insert([user_uri, RDF::SCHEMA.url, url])
|
83
|
+
end
|
84
|
+
unless user[:twitter].nil? || user[:twitter].empty?
|
85
|
+
url = user[:twitter]
|
86
|
+
unless (url.start_with? 'https://twitter.com') || (url.start_with? 'http://twitter.com')
|
87
|
+
url = 'https://twitter.com/' + url
|
88
|
+
end
|
89
|
+
url = RDF::URI.parse(url)
|
90
|
+
user_graph.insert([user_uri, RDF::SCHEMA.url, url])
|
91
|
+
end
|
92
|
+
end
|
93
|
+
{
|
94
|
+
:uri => user_uri,
|
95
|
+
# :node => user_node,
|
96
|
+
:graph => user_graph
|
97
|
+
}
|
98
|
+
end
|
99
|
+
|
100
|
+
# private
|
101
|
+
|
102
|
+
#
|
103
|
+
# Mapping a REVS annotation into an Open Annotation
|
104
|
+
#
|
105
|
+
def annotation2oa(annotation, user)
|
106
|
+
|
107
|
+
begin
|
108
|
+
# id --> part of URI for the annotation but, triannon POST will not accept an ID
|
109
|
+
annotation_id = sprintf 'revs_annotation_%04d', annotation[:id]
|
110
|
+
|
111
|
+
# convert the 'druid' into a PURL URI
|
112
|
+
purl = 'http://purl.stanford.edu/' + annotation[:druid]
|
113
|
+
purl_uri = RDF::URI.parse(purl)
|
114
|
+
|
115
|
+
# Commentary on the annotation json field
|
116
|
+
#
|
117
|
+
# > for each row of the annotation table (in mysql), can the 'shapes' array
|
118
|
+
# contain more than one entry?
|
119
|
+
#
|
120
|
+
# Shapes can currently only contain one entry, and are currently always
|
121
|
+
# rectangular. This data structure and shape implementation is a result of our
|
122
|
+
# use of the annotorious plugin, which is not guaranteed across projects or even
|
123
|
+
# in Revs in the long term.
|
124
|
+
#
|
125
|
+
# > if so, this suggests that a 'text' annotation might refer to more than
|
126
|
+
# one segment or region of a REVS image?
|
127
|
+
#
|
128
|
+
# Not at the moment. Not sure why it is an array. Perhaps so you can store
|
129
|
+
# multiple annotations about the same image in one row instead of many, but we
|
130
|
+
# do not do this for various reasons.
|
131
|
+
#
|
132
|
+
# > What is the 'context' field? Would you rather use the 'context' field than
|
133
|
+
# the 'src' field as the target of an open annotation (OA)?
|
134
|
+
#
|
135
|
+
# Context is just what annotorious uses for the src target. Again, we just used
|
136
|
+
# their vocabulary for ease of implementation. If we were to use a different
|
137
|
+
# back-end data store at some point, we could always transform into and out-of
|
138
|
+
# their specific json structure as needed.
|
139
|
+
#
|
140
|
+
|
141
|
+
# convert the 'json' field
|
142
|
+
annotation_json = JSON.parse(annotation[:json])
|
143
|
+
revs_uri = RDF::URI.parse(annotation_json['context'])
|
144
|
+
revs_img_src = annotation_json['src']
|
145
|
+
revs_img_uri = RDF::URI.parse(revs_img_src)
|
146
|
+
revs_fragments = []
|
147
|
+
annotation_json['shapes'].each do |shape|
|
148
|
+
# shapes are likely type 'rect'
|
149
|
+
if shape['type'] == 'rect'
|
150
|
+
# image annotation geometry
|
151
|
+
# x is % across from top left
|
152
|
+
# y is % down from top left
|
153
|
+
# width is % across from x
|
154
|
+
# height is % down from y
|
155
|
+
x = shape['geometry']['x'] * 100
|
156
|
+
y = shape['geometry']['y'] * 100
|
157
|
+
w = shape['geometry']['width'] * 100
|
158
|
+
h = shape['geometry']['height'] * 100
|
159
|
+
# media fragment: #xywh=percent:30.1,16.8,35.1,52.2
|
160
|
+
fragment = sprintf '#xywh=percent:%04.1f,%04.1f,%04.1f,%04.1f', x, y, w, h
|
161
|
+
revs_fragments << fragment
|
162
|
+
end
|
163
|
+
end
|
164
|
+
revs_img_graph = RDF::Graph.new
|
165
|
+
# revs_img_node = RDF::Node.new(revs_img_uri)
|
166
|
+
# revs_img_graph.insert([revs_img_node, RDF.type, RDF::Vocab::OA.SpecificResource])
|
167
|
+
# revs_img_graph.insert([revs_img_node, RDF::Vocab::OA.hasSource, revs_img_uri])
|
168
|
+
revs_img_graph.insert([revs_uri, RDF.type, RDF::Vocab::OA.SpecificResource])
|
169
|
+
revs_img_graph.insert([revs_uri, RDF::Vocab::OA.hasSource, revs_img_uri])
|
170
|
+
revs_img_graph.insert([revs_img_uri, RDF.type, RDF::DCMIType.Image])
|
171
|
+
# Note: it's most likely there is only one fragment in a REVS annotation.
|
172
|
+
revs_fragment_graphs = []
|
173
|
+
revs_fragments.each_with_index do |f, i|
|
174
|
+
# img_uri = RDF::URI.parse(revs_img_src + fragment)
|
175
|
+
# revs_img_uris << img_uri
|
176
|
+
f_id = sprintf '%s_fragment_%02d', annotation_id, i
|
177
|
+
f_uri = RDF::URI.parse(f_id)
|
178
|
+
f_graph = RDF::Graph.new
|
179
|
+
# avoid creation of blank nodes?
|
180
|
+
# f_node = RDF::Node.new(f_uri)
|
181
|
+
# f_graph.insert([f_node, RDF.type, RDF::Vocab::OA.FragmentSelector])
|
182
|
+
# f_graph.insert([f_node, RDF::DC.conformsTo, RDF::MA.MediaFragment])
|
183
|
+
# f_graph.insert([f_node, RDF.value, RDF::Literal.new(f)])
|
184
|
+
# revs_img_graph.insert([revs_img_node, RDF::Vocab::OA.hasSelector, f_node])
|
185
|
+
f_graph.insert([f_uri, RDF.type, RDF::Vocab::OA.FragmentSelector])
|
186
|
+
f_graph.insert([f_uri, RDF::DC.conformsTo, RDF::MA.MediaFragment])
|
187
|
+
f_graph.insert([f_uri, RDF.value, RDF::Literal.new(f)])
|
188
|
+
revs_img_graph.insert([revs_uri, RDF::Vocab::OA.hasSelector, f_uri])
|
189
|
+
revs_fragment_graphs << f_graph
|
190
|
+
end
|
191
|
+
|
192
|
+
# oa#hasBody
|
193
|
+
# text --> value of cnt:chars property of a ContentAsText body of the annotation
|
194
|
+
body_id = sprintf '%s_comment', annotation_id
|
195
|
+
body_uri = RDF::URI.parse(body_id)
|
196
|
+
# TODO: add a language tag?
|
197
|
+
#body_text = RDF::Literal.new(annotation[:text], :language => :en)
|
198
|
+
body_text = RDF::Literal.new(annotation[:text])
|
199
|
+
body_graph = RDF::Graph.new
|
200
|
+
# avoid creation of blank nodes?
|
201
|
+
# body_node = RDF::Node.uuid
|
202
|
+
# body_node = RDF::Node.new(annotation[:id])
|
203
|
+
body_graph.insert([body_uri, RDF.type, RDF::Content.ContentAsText])
|
204
|
+
body_graph.insert([body_uri, RDF.type, RDF::DCMIType.Text])
|
205
|
+
body_graph.insert([body_uri, RDF::Content.chars, body_text])
|
206
|
+
body_graph.insert([body_uri, RDF::Content.characterEncoding, 'UTF-8'])
|
207
|
+
|
208
|
+
# oa#annotatedAt
|
209
|
+
# created_at --> discard if updated_at is always present
|
210
|
+
# updated_at --> oa:annotatedAt
|
211
|
+
#
|
212
|
+
# > annotation[:created_at].class
|
213
|
+
# => Time
|
214
|
+
# > annotation[:created_at].utc
|
215
|
+
# => 2014-03-25 01:56:01 UTC
|
216
|
+
# > annotation[:created_at].to_i # unix time since epoch
|
217
|
+
# => 1395712561
|
218
|
+
# > [annotation[:created_at].utc, annotation[:updated_at].utc]
|
219
|
+
# => [2014-03-25 01:56:01 UTC, 2014-03-25 01:56:14 UTC]
|
220
|
+
#
|
221
|
+
# create an RDF literal with datatype, see
|
222
|
+
# http://rdf.greggkellogg.net/yard/RDF/Literal.html
|
223
|
+
# > RDF::Literal.new(annotation[:created_at]).datatype
|
224
|
+
# => #<RDF::Vocabulary::Term:0x3f86333d6ca8 URI:http://www.w3.org/2001/XMLSchema#time>
|
225
|
+
# However, this automatic conversion discards the date!
|
226
|
+
# > RDF::Literal.new(annotation[:created_at]).to_s
|
227
|
+
# => "01:56:01Z"
|
228
|
+
# So, an explicit datatype is required, i.e.:
|
229
|
+
# > RDF::Literal.new(annotation[:created_at], :datatype => RDF::XSD.dateTime).to_s
|
230
|
+
# => "2014-03-25T01:56:01Z"
|
231
|
+
created_datetime = RDF::Literal.new(annotation[:created_at].utc, :datatype => RDF::XSD.dateTime)
|
232
|
+
updated_datetime = RDF::Literal.new(annotation[:updated_at].utc, :datatype => RDF::XSD.dateTime)
|
233
|
+
annotation_datetime = updated_datetime #if annotation[:created_at].utc < annotation[:updated_at].utc
|
234
|
+
|
235
|
+
# Create and populate an Open Annotation instance.
|
236
|
+
oa = Annotations2triannon::OpenAnnotation.new
|
237
|
+
oa.insert_hasTarget(revs_uri)
|
238
|
+
oa.insert_hasTarget(purl_uri)
|
239
|
+
oa.insert_hasTarget(revs_img_uri)
|
240
|
+
# oa.insert_hasTarget(revs_img_node)
|
241
|
+
oa.graph.insert(revs_img_graph)
|
242
|
+
revs_fragment_graphs.each {|g| oa.graph.insert(g) }
|
243
|
+
# to enable the blank node, change body_graph to use body_node instead of body_uri
|
244
|
+
# oa.insert_hasBody(body_node)
|
245
|
+
oa.insert_hasBody(body_uri)
|
246
|
+
oa.graph.insert(body_graph)
|
247
|
+
oa.insert_annotatedAt(annotation_datetime)
|
248
|
+
# to enable the blank node, change user_graph to use user_node instead of user_uri
|
249
|
+
# oa.insert_annotatedBy(user[:node])
|
250
|
+
oa.insert_annotatedBy(user[:uri])
|
251
|
+
oa.graph.insert(user[:graph])
|
252
|
+
oa
|
253
|
+
rescue => e
|
254
|
+
puts e.message
|
255
|
+
# binding.pry
|
256
|
+
raise e
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
end
|
261
|
+
|
262
|
+
end
|
263
|
+
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'logger'
|
2
|
+
require 'mysql2'
|
3
|
+
require 'sequel'
|
4
|
+
# An interface to the revs SQL database using Sequel
|
5
|
+
# @see http://sequel.jeremyevans.net/documentation.html Sequel RDoc
|
6
|
+
# @see http://sequel.jeremyevans.net/rdoc/files/README_rdoc.html Sequel README
|
7
|
+
# @see http://sequel.jeremyevans.net/rdoc/files/doc/code_order_rdoc.html Sequel code order
|
8
|
+
|
9
|
+
module Annotations2triannon
|
10
|
+
|
11
|
+
class RevsDb
|
12
|
+
|
13
|
+
@@log = Logger.new('log/revs_db.log')
|
14
|
+
|
15
|
+
attr_accessor :db
|
16
|
+
attr_accessor :db_config
|
17
|
+
|
18
|
+
def self.log_model_info(m)
|
19
|
+
@@log.info "table: #{m.table_name}, columns: #{m.columns}, pk: #{m.primary_key}"
|
20
|
+
end
|
21
|
+
|
22
|
+
def initialize
|
23
|
+
@db_config = {}
|
24
|
+
@db_config['host'] = ENV['REVS_DB_HOST'] || 'localhost'
|
25
|
+
@db_config['port'] = ENV['REVS_DB_PORT'] || '3306'
|
26
|
+
@db_config['user'] = ENV['REVS_DB_USER'] || 'revs'
|
27
|
+
@db_config['password'] = ENV['REVS_DB_PASS'] || ''
|
28
|
+
@db_config['database'] = ENV['REVS_DB_DATABASE'] || 'revs'
|
29
|
+
options = @db_config.merge(
|
30
|
+
{
|
31
|
+
:encoding => 'utf8',
|
32
|
+
:max_connections => 10,
|
33
|
+
:logger => @@log
|
34
|
+
})
|
35
|
+
@db = Sequel.mysql2(options)
|
36
|
+
@db.extension(:pagination)
|
37
|
+
# Ensure the connection is good on startup, raises exceptions on failure
|
38
|
+
@@log.info "#{@db} connected: #{@db.test_connection}"
|
39
|
+
end
|
40
|
+
|
41
|
+
def annotation(id)
|
42
|
+
@db[:annotations][:id => id]
|
43
|
+
end
|
44
|
+
|
45
|
+
def annotations
|
46
|
+
@db[:annotations]
|
47
|
+
end
|
48
|
+
|
49
|
+
def annotation_ids
|
50
|
+
@db[:annotations].order(:user_id).select(:user_id, :id)
|
51
|
+
end
|
52
|
+
|
53
|
+
def annotations_join_users
|
54
|
+
@db[:annotations].join_table(:inner, @db[:users], :id=>:user_id)
|
55
|
+
# @db[:annotations].join_table(:outer, @db[:users], :id=>:user_id)
|
56
|
+
end
|
57
|
+
|
58
|
+
def users
|
59
|
+
@db[:users]
|
60
|
+
end
|
61
|
+
|
62
|
+
def user(id)
|
63
|
+
@db[:users][:id => id]
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
|
2
|
+
module Annotations2triannon
|
3
|
+
|
4
|
+
# A filter to exclude any IIIF namespace content
|
5
|
+
class SharedCanvasAnnotationList < AnnotationList
|
6
|
+
|
7
|
+
def annotation_list?
|
8
|
+
sc_annotation_list?
|
9
|
+
end
|
10
|
+
|
11
|
+
def iiif_annotation_list?
|
12
|
+
false
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
@@ -0,0 +1,32 @@
|
|
1
|
+
|
2
|
+
module Annotations2triannon
|
3
|
+
|
4
|
+
# A filter to exclude any IIIF namespace content
|
5
|
+
class SharedCanvasManifest < Manifest
|
6
|
+
|
7
|
+
def manifest?
|
8
|
+
sc_manifest?
|
9
|
+
end
|
10
|
+
|
11
|
+
def iiif_manifest?
|
12
|
+
false
|
13
|
+
end
|
14
|
+
|
15
|
+
def annotation_lists
|
16
|
+
return @annotation_lists unless @annotation_lists.nil?
|
17
|
+
uris = collect_annotation_list_uris(query_sc_annotation_list)
|
18
|
+
@annotation_lists = uris.collect do |uri|
|
19
|
+
Annotations2triannon::AnnotationList.new(uri)
|
20
|
+
end
|
21
|
+
@annotation_lists
|
22
|
+
end
|
23
|
+
|
24
|
+
def iiif_annotation_lists
|
25
|
+
return @iiif_annotation_lists unless @iiif_annotation_lists.nil?
|
26
|
+
@iiif_annotation_lists = []
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'requires'
|
2
|
+
|
3
|
+
module Annotations2triannon
|
4
|
+
|
5
|
+
AGENT = RDF::URI.parse('https://github.com/sul-dlss/annotations2triannon')
|
6
|
+
|
7
|
+
# configuration at the module level, see
|
8
|
+
# http://brandonhilkert.com/blog/ruby-gem-configuration-patterns/
|
9
|
+
|
10
|
+
class << self
|
11
|
+
attr_writer :configuration
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.configuration
|
15
|
+
@configuration ||= Configuration.new
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.reset
|
19
|
+
@configuration = Configuration.new
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.configure
|
23
|
+
yield(configuration)
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
@@ -0,0 +1,112 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
# This file generated automatically using vocab-fetch from http://www.w3.org/2011/content
|
3
|
+
require 'rdf'
|
4
|
+
module RDF
|
5
|
+
class CONTENT < RDF::StrictVocabulary("http://www.w3.org/2011/content#")
|
6
|
+
|
7
|
+
# Class definitions
|
8
|
+
term :Content,
|
9
|
+
comment: %(The content.).freeze,
|
10
|
+
label: "Content".freeze,
|
11
|
+
type: ["rdfs:Class".freeze, "owl:Class".freeze]
|
12
|
+
term :ContentAsBase64,
|
13
|
+
comment: %(The base64 encoded content \(can be used for binary content\).).freeze,
|
14
|
+
label: "Base64 content".freeze,
|
15
|
+
subClassOf: "http://www.w3.org/2011/content#Content".freeze,
|
16
|
+
type: ["rdfs:Class".freeze, "owl:Class".freeze]
|
17
|
+
term :ContentAsText,
|
18
|
+
comment: %(The text content \(can be used for text content\).).freeze,
|
19
|
+
label: "Text content".freeze,
|
20
|
+
subClassOf: "http://www.w3.org/2011/content#Content".freeze,
|
21
|
+
type: ["rdfs:Class".freeze, "owl:Class".freeze]
|
22
|
+
term :ContentAsXML,
|
23
|
+
comment: %(The XML content \(can only be used for XML-wellformed content\).).freeze,
|
24
|
+
label: "XML content".freeze,
|
25
|
+
subClassOf: "http://www.w3.org/2011/content#Content".freeze,
|
26
|
+
type: ["rdfs:Class".freeze, "owl:Class".freeze]
|
27
|
+
term :DoctypeDecl,
|
28
|
+
comment: %(The document type declaration.).freeze,
|
29
|
+
label: "Document type declaration".freeze,
|
30
|
+
type: ["rdfs:Class".freeze, "owl:Class".freeze]
|
31
|
+
|
32
|
+
# Property definitions
|
33
|
+
property :bytes,
|
34
|
+
comment: %(The Base64 encoded byte sequence of the content.).freeze,
|
35
|
+
domain: "http://www.w3.org/2011/content#ContentAsBase64".freeze,
|
36
|
+
label: "Base64 encoded byte sequence".freeze,
|
37
|
+
range: "xsd:base64Binary".freeze,
|
38
|
+
type: ["rdf:Property".freeze, "owl:ObjectProperty".freeze]
|
39
|
+
property :characterEncoding,
|
40
|
+
comment: %(The character encoding used to create a character sequence from a byte sequence or vice versa.).freeze,
|
41
|
+
domain: "http://www.w3.org/2011/content#Content".freeze,
|
42
|
+
label: "Character encoding".freeze,
|
43
|
+
range: "rdfs:Literal".freeze,
|
44
|
+
type: ["rdf:Property".freeze, "owl:ObjectProperty".freeze]
|
45
|
+
property :chars,
|
46
|
+
comment: %(The character sequence of the text content.).freeze,
|
47
|
+
domain: "http://www.w3.org/2011/content#ContentAsText".freeze,
|
48
|
+
label: "Character sequence".freeze,
|
49
|
+
range: "rdfs:Literal".freeze,
|
50
|
+
type: ["rdf:Property".freeze, "owl:ObjectProperty".freeze]
|
51
|
+
property :declaredEncoding,
|
52
|
+
comment: %(The character encoding declared in the XML declaration.).freeze,
|
53
|
+
domain: "http://www.w3.org/2011/content#ContentAsXML".freeze,
|
54
|
+
label: "XML character encoding".freeze,
|
55
|
+
range: "rdfs:Literal".freeze,
|
56
|
+
type: ["rdf:Property".freeze, "owl:ObjectProperty".freeze]
|
57
|
+
property :doctypeName,
|
58
|
+
comment: %(The document type name.).freeze,
|
59
|
+
domain: "http://www.w3.org/2011/content#DoctypeDecl".freeze,
|
60
|
+
label: "Document type name".freeze,
|
61
|
+
range: "rdfs:Literal".freeze,
|
62
|
+
type: ["rdf:Property".freeze, "owl:ObjectProperty".freeze]
|
63
|
+
property :dtDecl,
|
64
|
+
comment: %(The document type declaration.).freeze,
|
65
|
+
domain: "http://www.w3.org/2011/content#ContentAsXML".freeze,
|
66
|
+
label: "Document type declaration".freeze,
|
67
|
+
range: "http://www.w3.org/2011/content#DoctypeDecl".freeze,
|
68
|
+
type: ["rdf:Property".freeze, "owl:ObjectProperty".freeze]
|
69
|
+
property :internalSubset,
|
70
|
+
comment: %(The internal document type definition subset within the document type declarations.).freeze,
|
71
|
+
domain: "http://www.w3.org/2011/content#DoctypeDecl".freeze,
|
72
|
+
label: "Internal DTD subset".freeze,
|
73
|
+
range: "rdfs:Literal".freeze,
|
74
|
+
type: ["rdf:Property".freeze, "owl:ObjectProperty".freeze]
|
75
|
+
property :leadingMisc,
|
76
|
+
comment: %(The XML content preceding the document type declaration.).freeze,
|
77
|
+
domain: "http://www.w3.org/2011/content#ContentAsXML".freeze,
|
78
|
+
label: "XML leading misc".freeze,
|
79
|
+
range: "rdfs:XMLLiteral".freeze,
|
80
|
+
type: ["rdf:Property".freeze, "owl:ObjectProperty".freeze]
|
81
|
+
property :publicId,
|
82
|
+
comment: %(The document type declarations's public identifier.).freeze,
|
83
|
+
domain: "http://www.w3.org/2011/content#DoctypeDecl".freeze,
|
84
|
+
label: "Public ID".freeze,
|
85
|
+
range: "rdfs:Literal".freeze,
|
86
|
+
type: ["rdf:Property".freeze, "owl:ObjectProperty".freeze]
|
87
|
+
property :rest,
|
88
|
+
comment: %(The XML content following the document type declaration.).freeze,
|
89
|
+
domain: "http://www.w3.org/2011/content#ContentAsXML".freeze,
|
90
|
+
label: "XML rest".freeze,
|
91
|
+
range: "rdfs:XMLLiteral".freeze,
|
92
|
+
type: ["rdf:Property".freeze, "owl:ObjectProperty".freeze]
|
93
|
+
property :standalone,
|
94
|
+
comment: %(The standalone declaration in the XML declaration.).freeze,
|
95
|
+
domain: "http://www.w3.org/2011/content#ContentAsXML".freeze,
|
96
|
+
label: "XML standalone document declaration".freeze,
|
97
|
+
range: "rdfs:Literal".freeze,
|
98
|
+
type: ["rdf:Property".freeze, "owl:ObjectProperty".freeze]
|
99
|
+
property :systemId,
|
100
|
+
comment: %(The document type declarations's system identifier \(typed: xsd:anyURI\)).freeze,
|
101
|
+
domain: "http://www.w3.org/2011/content#DoctypeDecl".freeze,
|
102
|
+
label: "System ID".freeze,
|
103
|
+
range: "xsd:anyURI".freeze,
|
104
|
+
type: ["rdf:Property".freeze, "owl:ObjectProperty".freeze]
|
105
|
+
property :version,
|
106
|
+
comment: %(The XML version declared in the XML declaration.).freeze,
|
107
|
+
domain: "http://www.w3.org/2011/content#ContentAsXML".freeze,
|
108
|
+
label: "XML version".freeze,
|
109
|
+
range: "rdfs:Literal".freeze,
|
110
|
+
type: ["rdf:Property".freeze, "owl:ObjectProperty".freeze]
|
111
|
+
end
|
112
|
+
end
|