when_exe 0.4.0 → 0.4.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.
- checksums.yaml +4 -4
- data/README.md +333 -212
- data/bin/make_ttl.rb +37 -0
- data/bin/make_ttl.rb.config +9 -0
- data/lib/when_exe.rb +923 -925
- data/lib/when_exe/calendarnote.rb +9 -5
- data/lib/when_exe/coordinates.rb +2437 -2446
- data/lib/when_exe/inspect.rb +1480 -1408
- data/lib/when_exe/linkeddata.rb +574 -0
- data/lib/when_exe/locales/akt.rb +177 -176
- data/lib/when_exe/locales/locale.rb +751 -751
- data/lib/when_exe/mini_application.rb +307 -307
- data/lib/when_exe/parts/resource.rb +1115 -1103
- data/lib/when_exe/region/chinese/epochs.rb +6 -5
- data/lib/when_exe/region/christian.rb +831 -829
- data/lib/when_exe/region/japanese.rb +93 -93
- data/lib/when_exe/region/japanese/notes.rb +1510 -1495
- data/lib/when_exe/region/japanese/residues.rb +13 -13
- data/lib/when_exe/tmposition.rb +2307 -2273
- data/lib/when_exe/tmreference.rb +1744 -1734
- data/lib/when_exe/version.rb +2 -2
- data/link_to_online_documents +1 -1
- data/test/scripts/3.ext.rb +6 -6
- data/test/scripts/3.rb +6 -6
- data/test/test.rb +76 -75
- data/test/test/icalendar.rb +883 -879
- data/test/test/linkeddata.rb +224 -0
- data/test/test/region/m17n.rb +193 -193
- data/when_exe.gemspec +3 -2
- metadata +13 -6
@@ -0,0 +1,574 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
=begin
|
3
|
+
Copyright (C) 2014-2015 Takashi SUGA
|
4
|
+
|
5
|
+
You may use and/or modify this file according to the license described in the LICENSE.txt file included in this archive.
|
6
|
+
=end
|
7
|
+
|
8
|
+
module When
|
9
|
+
#
|
10
|
+
# When::Parts::Resource への追加
|
11
|
+
#
|
12
|
+
module Parts::Resource
|
13
|
+
|
14
|
+
DocRoot = "http://www.rubydoc.info/gems/when_exe/#{When::VERSION}/When/"
|
15
|
+
|
16
|
+
Schema = {
|
17
|
+
'reference' => "Locale#reference-instance_method",
|
18
|
+
'label' => "BasicTypes/M17n#label-instance_method",
|
19
|
+
'prev' => "TM/TemporalPosition#prev-instance_method",
|
20
|
+
'succ' => "TM/TemporalPosition#succ-instance_method",
|
21
|
+
'frame' => "TM/TemporalPosition#frame-instance_method",
|
22
|
+
'ruler' => "TM/TemporalPosition#query-instance_method",
|
23
|
+
'coordinate' => "TM/CalDate#cal_date-instance_method",
|
24
|
+
'sdn' => "TM/CalDate#to_i-instance_method",
|
25
|
+
'calendarEra' => "TM/CalDate#calendar_era-instance_method",
|
26
|
+
'referenceEvent' => "TM/Clock#reference_event-instance_method",
|
27
|
+
'referenceTime' => "TM/Clock#reference_time-instance_method",
|
28
|
+
'utcReference' => "TM/Clock#utc_reference-instance_method",
|
29
|
+
'dateBasis' => "TM/Clock#date_basis-instance_method",
|
30
|
+
'referenceFrame' => "TM/Calendar#reference_frame-instance_method",
|
31
|
+
'timeBasis' => "TM/Calendar#time_basis-instance_method",
|
32
|
+
'referenceEvent' => "TM/CalendarEra#reference_event-instance_method",
|
33
|
+
'referenceDate' => "TM/CalendarEra#reference_date-instance_method",
|
34
|
+
'julianReference' => "TM/CalendarEra#julian_reference-instance_method",
|
35
|
+
'datingSystem' => "TM/CalendarEra#dating_system-instance_method",
|
36
|
+
'epoch' => "TM/CalendarEra#epoch-instance_method",
|
37
|
+
'remainder' => "Coordinates/Residue#remainder-instance_method",
|
38
|
+
'divisor' => "Coordinates/Residue#divisor-instance_method",
|
39
|
+
'longitude' => "Coordinates/Spatial#longitude-instance_method",
|
40
|
+
'latitude' => "Coordinates/Spatial#latitude-instance_method",
|
41
|
+
'altitide' => "Coordinates/Spatial#latitude-instance_method",
|
42
|
+
'event' => "CalendarNote#event-instance_method",
|
43
|
+
}
|
44
|
+
|
45
|
+
XSD = 'http://www.w3.org/2001/XMLSchema'
|
46
|
+
RDFS = 'http://www.w3.org/2000/01/rdf-schema#'
|
47
|
+
RDF = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'
|
48
|
+
|
49
|
+
#
|
50
|
+
# @private
|
51
|
+
#
|
52
|
+
module MinimumLinkedDataAPI
|
53
|
+
|
54
|
+
attr_accessor :iri
|
55
|
+
private :iri=
|
56
|
+
|
57
|
+
def rdf_graph(options={})
|
58
|
+
self
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
class << self
|
63
|
+
|
64
|
+
# context オブジェクトを生成する
|
65
|
+
#
|
66
|
+
# @param [String] iri self に与える iri
|
67
|
+
#
|
68
|
+
# @return [Hash]
|
69
|
+
#
|
70
|
+
def context(iri=nil)
|
71
|
+
ts = base_uri.sub(/When\/$/, 'ts#')
|
72
|
+
hash = {'ts' => ts}
|
73
|
+
Schema.each_pair do |key, ref|
|
74
|
+
hash['ts:' + key] = {'@type' => '@id'}
|
75
|
+
end
|
76
|
+
bless(hash, iri || ts[0..-2])
|
77
|
+
end
|
78
|
+
|
79
|
+
# Schema オブジェクトを生成する
|
80
|
+
#
|
81
|
+
# @param [String] iri self に与える iri
|
82
|
+
#
|
83
|
+
# @return [Hash]
|
84
|
+
#
|
85
|
+
def schema(iri=nil)
|
86
|
+
ts = base_uri.sub(/When\/$/, 'ts#')
|
87
|
+
hash =
|
88
|
+
{'@context'=>{'ts' => ts},
|
89
|
+
'@graph' => Schema.keys.map {|id| {'@id'=>'ts:'+id, 'ts:reference'=>{'@id'=>DocRoot + Schema[id]}}}
|
90
|
+
}
|
91
|
+
bless(hash, iri || ts[0..-2])
|
92
|
+
end
|
93
|
+
|
94
|
+
# Hash に最低限のメソッドを追加する
|
95
|
+
#
|
96
|
+
# @param [Hash] hash メソッドを追加される Hash
|
97
|
+
# @param [String] iri hash に与える iri
|
98
|
+
#
|
99
|
+
# @return [Hash]
|
100
|
+
#
|
101
|
+
def bless(hash, iri)
|
102
|
+
hash.extend(MinimumLinkedDataAPI)
|
103
|
+
hash.send(:iri=, iri)
|
104
|
+
hash
|
105
|
+
end
|
106
|
+
|
107
|
+
# jsonld を表現する Hash を各種のRDF表現形式に変換する
|
108
|
+
#
|
109
|
+
# @param [Hash] jsonld_hash jsonld を表現する Hash
|
110
|
+
# @param [Symbol] writer RDF表現形式 (デフォルト :jsonld - 単に Hash を JSON化)
|
111
|
+
# @param [Hash] prefixes prefix から namespace を引く Hash
|
112
|
+
#
|
113
|
+
# @return [String] writer で指定されたRDF表現形式の文字列
|
114
|
+
#
|
115
|
+
def to_linked_data(jsonld_hash, writer=:jsonld, prefixes=nil)
|
116
|
+
if writer == :jsonld
|
117
|
+
JSON.generate(jsonld_hash)
|
118
|
+
else
|
119
|
+
array = JSON::LD::API.toRdf(jsonld_hash)
|
120
|
+
graph = ::RDF::Graph.new << array
|
121
|
+
args = [writer]
|
122
|
+
args << {:prefixes=>prefixes} if prefixes
|
123
|
+
graph.dump(*args)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
# 指定の範囲のResourceオブジェクトのグラフの jsonld を表現する Hash を生成する
|
128
|
+
#
|
129
|
+
# @param [Range or Array] objects jsonld を表現する Hash を生成するResourceオブジェクトの範囲または配列
|
130
|
+
# @param [Hash] options 以下の通り
|
131
|
+
# @option options [Boolean] :include 自身が含むResourceオブジェクトをグラフに含める(デフォルト nil)
|
132
|
+
# @option options [Object] @... そのまま戻り値のHashに追加
|
133
|
+
# @option options [Symbol] その他 {When::TM::CalDate#to_jsonld_hash} などを参照
|
134
|
+
#
|
135
|
+
# @return [Hash] jsonld を表現する Hash
|
136
|
+
#
|
137
|
+
def rdf_graph(objects, options={})
|
138
|
+
jsonld_hash = {}
|
139
|
+
sub_options = {}
|
140
|
+
options.each_pair do |key, value|
|
141
|
+
(/^@/ =~ key.to_s ? jsonld_hash : sub_options)[key] = value
|
142
|
+
end
|
143
|
+
jsonld_hash['@graph'] ||= []
|
144
|
+
sub_options[:prefixes] ||= When::Parts::Resource.namespace_prefixes if options[:context]
|
145
|
+
objects.each do |object|
|
146
|
+
object.register_graph(jsonld_hash['@graph'], sub_options)
|
147
|
+
end
|
148
|
+
if options['@context'] && options[:context]
|
149
|
+
sub_options[:prefixes].each_pair do |key, value|
|
150
|
+
options['@context'][key] ||= value.last
|
151
|
+
end
|
152
|
+
end
|
153
|
+
jsonld_hash
|
154
|
+
end
|
155
|
+
|
156
|
+
# Linked Data 用 namespace URI の Array の Hash を生成する
|
157
|
+
#
|
158
|
+
# @param [Array<When::Parts::Resource or String>] resources namespace を抽出する resource の Array
|
159
|
+
#
|
160
|
+
# @return [Hash]
|
161
|
+
#
|
162
|
+
def namespace_prefixes(*resources)
|
163
|
+
base = base_uri.sub(/When\/$/, '')
|
164
|
+
resources.inject({
|
165
|
+
'xsd' => [XSD],
|
166
|
+
'rdf' => [RDF],
|
167
|
+
'rdfs' => [RDFS],
|
168
|
+
'owl' => ['http://www.w3.org/2002/07/owl#'],
|
169
|
+
'dc' => ['http://purl.org/dc/elements/1.1/'],
|
170
|
+
'dcq' => ['http://purl.org/dc/terms/'],
|
171
|
+
'dct' => ['http://purl.org/dc/dcmitype/'],
|
172
|
+
# 'tp' => [base + 'tp/'],
|
173
|
+
'ts' => [base + 'ts#']
|
174
|
+
}) {|namespace, resource|
|
175
|
+
resource = When.Resource(resource) if resource.kind_of?(String)
|
176
|
+
hash = resource.namespace_prefixes
|
177
|
+
hash.each_pair do |key, value|
|
178
|
+
namespace[key] = namespace[key] ? (namespace[key] + value).uniq.sort_by {|ns| -ns.length} : value
|
179
|
+
end
|
180
|
+
namespace
|
181
|
+
}
|
182
|
+
end
|
183
|
+
|
184
|
+
# URIのArrayの最後の要素を prefix に対応する namespace とみなして json-ld の @context に適合する形式に変換する
|
185
|
+
#
|
186
|
+
# @param [Hash<String=>Array<String>>] prefixes Linked Data 用 namespace URIのArrayのHash
|
187
|
+
#
|
188
|
+
# @return [Hash<String=>String>] prefix と namespace の1対1対応
|
189
|
+
#
|
190
|
+
def prefixs_to_context(prefixes)
|
191
|
+
Hash[*(prefixes.keys.map {|key| [key, prefixes[key].last]}.flatten)]
|
192
|
+
end
|
193
|
+
|
194
|
+
# json-ld の @context に適合する形式で記述された 1対1対応する prefix と namespace を Linked Data 用 namespace URIのArrayのHash化する
|
195
|
+
#
|
196
|
+
# @param [Hash<String=>String>] prefixes prefix と namespace の1対1対応
|
197
|
+
#
|
198
|
+
# @return [Hash<String=>Array<String>>] Linked Data 用 namespace URIのArrayのHash
|
199
|
+
#
|
200
|
+
def context_to_prefixs(prefixes)
|
201
|
+
hash = {}
|
202
|
+
prefixes.each_pair do |key, value|
|
203
|
+
hash[key] = [value]
|
204
|
+
end
|
205
|
+
hash
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
# Linked Data 用 namespace URI の Array の Hash を生成する
|
210
|
+
#
|
211
|
+
# @return [Hash]
|
212
|
+
#
|
213
|
+
def namespace_prefixes
|
214
|
+
prefixes = {}
|
215
|
+
child.each do |c|
|
216
|
+
next if c.iri =~ / /
|
217
|
+
iri = c.child ? c.iri : self.iri
|
218
|
+
prefixes[((c.kind_of?(When::BasicTypes::M17n) ? c : c.label) / 'en').split(/ +/).first] = [iri + '::']
|
219
|
+
end
|
220
|
+
prefixes
|
221
|
+
end
|
222
|
+
|
223
|
+
# 自身を root とするグラフの jsonld を表現する Hash を各種のRDF表現形式に変換する
|
224
|
+
#
|
225
|
+
# @param [Symbol] writer RDF表現形式 (デフォルト :jsonld - 単に Hash を JSON化)
|
226
|
+
# @param [Hash] options 内部で呼び出す #to_jsonld_hash にそのまま渡す
|
227
|
+
#
|
228
|
+
# @return [String] writer で指定されたRDF表現形式の文字列
|
229
|
+
#
|
230
|
+
def to_linked_data(writer=:jsonld, options={})
|
231
|
+
jsonld_hash = rdf_graph(options)
|
232
|
+
When::Parts::Resource.to_linked_data(jsonld_hash, writer, jsonld_hash['@context'])
|
233
|
+
end
|
234
|
+
|
235
|
+
# 自身を root とするグラフの jsonld を表現する Hash を生成する
|
236
|
+
#
|
237
|
+
# @param [Hash] options {When::Parts::Resource.rdf_graph} を参照
|
238
|
+
#
|
239
|
+
# @return [Hash] jsonld を表現する Hash
|
240
|
+
#
|
241
|
+
def rdf_graph(options={})
|
242
|
+
When::Parts::Resource.rdf_graph([self], options)
|
243
|
+
end
|
244
|
+
|
245
|
+
# Resourceオブジェクトの jsonld をグラフに追加する
|
246
|
+
#
|
247
|
+
# @param [Array<Hash>] graph 個別のResourceオブジェクトの jsonld hash の Array
|
248
|
+
# @param [Hash] options {When::Parts::Resource.rdf_graph} を参照
|
249
|
+
#
|
250
|
+
# @return [Array] jsonld hash の Array
|
251
|
+
#
|
252
|
+
def register_graph(graph, options={})
|
253
|
+
jsonld_hash = to_jsonld_hash(options)
|
254
|
+
graph << jsonld_hash
|
255
|
+
if options[:include] && child
|
256
|
+
included_opt = {:included=>jsonld_hash['@id']}.update(options)
|
257
|
+
child.each do |included|
|
258
|
+
included.register_graph(graph, included_opt)
|
259
|
+
end
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
# Resourceオブジェクトの jsonld を表現する Hash を生成する
|
264
|
+
#
|
265
|
+
# @param [Hash] options 以下の通り
|
266
|
+
# @option options [Hash] :prefixes Linked Data 用 namespace URI の Array の Hash ('@context'互換でも可)
|
267
|
+
# @option options [Boolean] :context true なら 可能な限り namespace を prefix に変換する
|
268
|
+
# @option options [String or Boolean] :prev ひとつ前のResourceオブジェクトのIRI
|
269
|
+
# @option options [String or Boolean] :succ ひとつ後のResourceオブジェクトのIRI
|
270
|
+
# @option options [String or Boolean] :included 自身を含む親ResourceオブジェクトのIRI
|
271
|
+
# @option options [Object] @... そのまま戻り値のHashに反映
|
272
|
+
#
|
273
|
+
# @note :prev,:succ,:included が true のときは自身で当該IRIを計算する。
|
274
|
+
# nil,false のときは当該情報を戻り値のHashに追加しない。
|
275
|
+
#
|
276
|
+
# @return [Hash] jsonld を表現する Hash
|
277
|
+
#
|
278
|
+
def to_jsonld_hash(options={})
|
279
|
+
neighbor = {
|
280
|
+
:succ => options[:succ],
|
281
|
+
:prev => options[:prev],
|
282
|
+
:parent => options[:included]
|
283
|
+
}
|
284
|
+
neighbor.each_pair do |key, value|
|
285
|
+
neighbor[key] = send(key) if value == true
|
286
|
+
neighbor[key] = neighbor[key].iri if neighbor[key].kind_of?(When::Parts::Resource)
|
287
|
+
end
|
288
|
+
hash, context, base = hash_and_variables(options)
|
289
|
+
ts = base + 'ts#'
|
290
|
+
hash['@id'] = iri
|
291
|
+
hash[ts + 'succ'] = {'@id'=>neighbor[:succ]} if neighbor[:succ]
|
292
|
+
hash[ts + 'prev'] = {'@id'=>neighbor[:prev]} if neighbor[:prev]
|
293
|
+
hash['@reverse' ] = (hash['@reverse'] || {}).merge(
|
294
|
+
{RDFS + 'member'=>{'@id'=>neighbor[:parent]}}) if neighbor[:parent]
|
295
|
+
hash.update(hash_for_jsonld(ts, options))
|
296
|
+
compact_predicate(hash, context, options[:prefixes])
|
297
|
+
hash
|
298
|
+
end
|
299
|
+
|
300
|
+
private
|
301
|
+
|
302
|
+
#
|
303
|
+
# jsonld_hash と context, base を準備する
|
304
|
+
#
|
305
|
+
def hash_and_variables(options)
|
306
|
+
base = When::Parts::Resource.base_uri.sub(/When\/$/, '')
|
307
|
+
hash = {}
|
308
|
+
options.each_pair do |key, value|
|
309
|
+
hash[key] = value if /^@/ =~ key.to_s
|
310
|
+
end
|
311
|
+
hash[RDF + 'type'] = {'@id'=>base + 'ts/' + self.class.to_s.gsub(/::/, '/')}
|
312
|
+
if options[:context]
|
313
|
+
options[:prefixes] ||= When::Parts::Resource.namespace_prefixes
|
314
|
+
context = hash['@context'] || {}
|
315
|
+
end
|
316
|
+
[hash, context, base]
|
317
|
+
end
|
318
|
+
|
319
|
+
#
|
320
|
+
# jsonld_hash の個別部分
|
321
|
+
#
|
322
|
+
def hash_for_jsonld(ts, options)
|
323
|
+
tp = ts.sub('ts#', 'tp/')
|
324
|
+
hash = {}
|
325
|
+
to_h({:method=>:iri}.update(options)).each_pair do |key, value|
|
326
|
+
tskey = ts + key.to_s
|
327
|
+
case value
|
328
|
+
when Array ; hash[tskey] = value.map {|v|
|
329
|
+
case v
|
330
|
+
when When::TM::CalDate ; {'@id'=>tp + v.to_uri_escape}
|
331
|
+
when /:\/\// ; {'@id'=>v}
|
332
|
+
else ; nil
|
333
|
+
end
|
334
|
+
}.compact unless value.empty?
|
335
|
+
when Hash ;
|
336
|
+
when /:\/\// ; hash[tskey] = {'@id'=>value}
|
337
|
+
when When::TM::JulianDate ; hash[tskey] = value.precision <= When::DAY ? value.to_i : value.to_f
|
338
|
+
when When::Coordinates::Pair ; hash[tskey] = value.to_s
|
339
|
+
when Numeric ; hash[tskey] = value
|
340
|
+
else ; hash[tskey] = value.to_s
|
341
|
+
end
|
342
|
+
end
|
343
|
+
hash
|
344
|
+
end
|
345
|
+
|
346
|
+
#
|
347
|
+
# 述語をコンパクト化する
|
348
|
+
#
|
349
|
+
def compact_predicate(hash, context, prefixes)
|
350
|
+
[hash, hash['@reverse']].each do |h|
|
351
|
+
h.keys.each do |key|
|
352
|
+
id = compact_namespace_to_prefix(key, prefixes, context)
|
353
|
+
if context && id != key
|
354
|
+
prefix = id.split(':').first
|
355
|
+
context[prefix] = prefixes[prefix].last
|
356
|
+
end
|
357
|
+
h[id] = h.delete(key)
|
358
|
+
end if h
|
359
|
+
end
|
360
|
+
end
|
361
|
+
|
362
|
+
#
|
363
|
+
# namespace を prefix にコンパクト化する
|
364
|
+
#
|
365
|
+
def compact_namespace_to_prefix(source, prefixes, context=nil)
|
366
|
+
return source unless prefixes
|
367
|
+
prefixes.each_pair do |key, value|
|
368
|
+
Array(value).each do |prefix|
|
369
|
+
start = source.index(prefix)
|
370
|
+
body = source[prefix.length..-1]
|
371
|
+
return key + ':' + body if start == 0 && body !~ /:/
|
372
|
+
end
|
373
|
+
end
|
374
|
+
return source unless context
|
375
|
+
source =~ /\A((.+)([:#\/]))([^:#\/]+)\z/
|
376
|
+
namespace, item = $1.to_s, $4
|
377
|
+
if namespace =~ /^Ahttp:\/\/([^.]+)\.wikipedia\.org/
|
378
|
+
prefix = "wiki_#{$1}"
|
379
|
+
elsif namespace && namespace.index(When::Parts::Resource.base_uri) == 0
|
380
|
+
label = begin When.Resource(namespace.sub(/::\z/, '')) rescue return source end
|
381
|
+
label = label.label unless label.kind_of?(When::BasicTypes::M17n)
|
382
|
+
prefix = label.to_m17n / 'en'
|
383
|
+
return source unless prefix =~ /\A[-A-Z\d_]+\z/i
|
384
|
+
else
|
385
|
+
return source
|
386
|
+
end
|
387
|
+
prefixes[prefix] ||= []
|
388
|
+
prefixes[prefix] << namespace
|
389
|
+
prefixes[prefix] = prefixes[prefix].sort_by {|value| -value.length}
|
390
|
+
context[prefix] = prefixes[prefix].last
|
391
|
+
prefix + ':' + item
|
392
|
+
end
|
393
|
+
end
|
394
|
+
|
395
|
+
#
|
396
|
+
# When::BasicTypes::M17n への追加
|
397
|
+
#
|
398
|
+
class BasicTypes::M17n
|
399
|
+
|
400
|
+
private
|
401
|
+
|
402
|
+
#
|
403
|
+
# jsonld_hash の個別部分
|
404
|
+
#
|
405
|
+
def hash_for_jsonld(ts, options)
|
406
|
+
hash = {}
|
407
|
+
hash[RDFS + 'label'] = names.keys.map {|key| key=='' ? names[key] : {'@language'=>key, '@value'=>names[key]}}
|
408
|
+
hash[ts + 'label'] = label
|
409
|
+
hash[ts + 'reference'] = link.values.map {|ref| {'@id'=>ref}}
|
410
|
+
hash
|
411
|
+
end
|
412
|
+
end
|
413
|
+
|
414
|
+
#
|
415
|
+
# When::TM::Clock への追加
|
416
|
+
#
|
417
|
+
class TM::Clock
|
418
|
+
|
419
|
+
private
|
420
|
+
|
421
|
+
#
|
422
|
+
# jsonld_hash の個別部分
|
423
|
+
#
|
424
|
+
def hash_for_jsonld(ts, options)
|
425
|
+
hash = {}
|
426
|
+
self.class::HashProperty.each do |sym|
|
427
|
+
hash[ts + sym.to_s] = send(sym).to_s if send(sym)
|
428
|
+
end
|
429
|
+
hash
|
430
|
+
end
|
431
|
+
end
|
432
|
+
|
433
|
+
#
|
434
|
+
# When::TM::CalDate への追加
|
435
|
+
#
|
436
|
+
class TM::CalDate
|
437
|
+
|
438
|
+
# URI - linked data 用
|
439
|
+
#
|
440
|
+
# @overload to_uri_linkeddata()
|
441
|
+
#
|
442
|
+
# @return [String]
|
443
|
+
#
|
444
|
+
def to_uri_linkeddata(*args)
|
445
|
+
date, frame = _to_uri(to_s(*args)).split('^^', 2)
|
446
|
+
frame += '_' if frame =~ /\d\z/
|
447
|
+
date = "#{frame}(#{date})" if frame
|
448
|
+
When::Parts::Resource.base_uri.sub(/When\/$/, 'tp/') + date
|
449
|
+
end
|
450
|
+
|
451
|
+
# 自身を root とするグラフの jsonld を表現する Hash を各種のRDF表現形式に変換する
|
452
|
+
#
|
453
|
+
# @param [Symbol] writer RDF表現形式 (デフォルト :jsonld - 単に Hash を JSON化)
|
454
|
+
# @param [Hash] options 内部で呼び出す #to_jsonld_hash にそのまま渡す。ただし、
|
455
|
+
# @option options [Boolean] :include 自身が含む分解能が高いCalDateオブジェクトをグラフに含める(デフォルト true)
|
456
|
+
#
|
457
|
+
# @return [String] writer で指定されたRDF表現形式の文字列
|
458
|
+
#
|
459
|
+
def to_linked_data(writer=:jsonld, options={})
|
460
|
+
hash = rdf_graph({:include=>true}.update(options))
|
461
|
+
When::Parts::Resource.to_linked_data(hash, writer, hash['@context'])
|
462
|
+
end
|
463
|
+
|
464
|
+
# 自身を root とするグラフの jsonld を表現する Hash を生成する
|
465
|
+
#
|
466
|
+
# @param [Hash] options {When::Parts::Resource.rdf_graph} を参照
|
467
|
+
#
|
468
|
+
# @return [Hash] jsonld を表現する Hash
|
469
|
+
#
|
470
|
+
def rdf_graph(options={})
|
471
|
+
root = options[:include] && precision < When::YEAR ? floor(When::YEAR) : self
|
472
|
+
When::Parts::Resource.rdf_graph([root], options)
|
473
|
+
end
|
474
|
+
|
475
|
+
# CalDateオブジェクトの jsonld をグラフに追加する
|
476
|
+
#
|
477
|
+
# @param [Array<Hash>] graph 個別のCalDateオブジェクトの jsonld hash の Array
|
478
|
+
# @param [Hash] options {When::Parts::Resource.rdf_graph} を参照
|
479
|
+
#
|
480
|
+
# @return [Array] jsonld hash の Array
|
481
|
+
#
|
482
|
+
def register_graph(graph, options={})
|
483
|
+
jsonld_hash = to_jsonld_hash(options)
|
484
|
+
graph << jsonld_hash
|
485
|
+
if options[:include] && precision < When::DAY
|
486
|
+
included = floor(precision+1)
|
487
|
+
included_opt = {:included=>jsonld_hash['@id']}.update(options)
|
488
|
+
while include?(included) do
|
489
|
+
included.register_graph(graph, included_opt)
|
490
|
+
included = included.succ
|
491
|
+
end
|
492
|
+
end
|
493
|
+
end
|
494
|
+
|
495
|
+
# CalDateオブジェクトの jsonld を表現する Hash を生成する
|
496
|
+
#
|
497
|
+
# @param [Hash] options 以下の通り
|
498
|
+
# @option options [Hash] :prefixes Linked Data 用 namespace URI の Array の Hash ('@context'互換でも可)
|
499
|
+
# @option options [Boolean] :context true なら 可能な限り namespace を prefix に変換する
|
500
|
+
# @option options [String or Boolean] :prev ひとつ前のCalDateオブジェクトのIRI
|
501
|
+
# @option options [String or Boolean] :succ ひとつ後のCalDateオブジェクトのIRI
|
502
|
+
# @option options [String or Boolean] :included 自身を含む分解能が1低いCalDateオブジェクトのIRI
|
503
|
+
# @option options [Hash] :note 暦注計算のオプション {When::Parts::Resource#notes} を参照
|
504
|
+
# @option options [Object] @... そのまま戻り値のHashに反映
|
505
|
+
#
|
506
|
+
# @note :prev,:succ,:included が true のときは自身で当該IRIを計算する。
|
507
|
+
# nil,false のときは当該情報を戻り値のHashに追加しない。
|
508
|
+
#
|
509
|
+
# @return [Hash] jsonld を表現する Hash
|
510
|
+
#
|
511
|
+
def to_jsonld_hash(options={})
|
512
|
+
hash, context, base = hash_and_variables(options)
|
513
|
+
tp = base + 'tp/'
|
514
|
+
ts = base + 'ts#'
|
515
|
+
hash['@id'] ||= tp + to_uri_escape
|
516
|
+
hash[ts + 'sdn'] = precision <= When::DAY ? to_i : to_f
|
517
|
+
hash[ts + 'frame'] = {'@id'=>frame.iri(false)}
|
518
|
+
hash[ts + 'calendarEra'] = {'@id'=>calendar_era.iri(false)} if calendar_era
|
519
|
+
hash[ts + 'coordinate'] = self[precision].to_s
|
520
|
+
hash[ts + 'ruler'] = {'@id'=>query['name'].iri} if query && query['name'].kind_of?(When::BasicTypes::M17n)
|
521
|
+
hash[ts + 'succ'] = options[:succ].kind_of?(String) ?
|
522
|
+
options[:succ] : {'@id'=>tp + succ.to_uri_escape} if options[:succ]
|
523
|
+
hash[ts + 'prev'] = options[:prev].kind_of?(String) ?
|
524
|
+
options[:prev] : {'@id'=>tp + prev.to_uri_escape} if options[:prev]
|
525
|
+
hash['@reverse'] = (hash['@reverse'] || {}).merge(
|
526
|
+
{RDFS + 'member'=>
|
527
|
+
{'@id'=>options[:included].kind_of?(String) ?
|
528
|
+
options[:included] :
|
529
|
+
tp + floor(precision-1).to_uri_escape
|
530
|
+
}
|
531
|
+
}) if options[:included] && precision + frame.indices.size > 0
|
532
|
+
compact_predicate(hash, context, options[:prefixes])
|
533
|
+
note_options = {:indices=>precision, :notes=>:all}
|
534
|
+
note_options.update(options[:note]) if options[:note]
|
535
|
+
notes(note_options).first.each do |note|
|
536
|
+
next unless note[:note]
|
537
|
+
if note[:value].kind_of?(Array)
|
538
|
+
value = note[:value].flatten.reject {|v| v.kind_of?(Hash) || v =~ /-\z/ }.map {|v| _value_str(note[:note], v)}
|
539
|
+
value = value.first if value.size == 1
|
540
|
+
else
|
541
|
+
value =_value_str(note[:note], note[:value])
|
542
|
+
end
|
543
|
+
id = compact_namespace_to_prefix(value, options[:prefixes], context)
|
544
|
+
hash[compact_namespace_to_prefix(_note_str(note[:note]), options[:prefixes], context)] = (id == value && id !~ /:\/\//) ? id : {'@id'=>id}
|
545
|
+
end
|
546
|
+
hash
|
547
|
+
end
|
548
|
+
|
549
|
+
private
|
550
|
+
|
551
|
+
#
|
552
|
+
# できるだけ上位の IRI を note の IRI とする
|
553
|
+
#
|
554
|
+
def _note_str(note)
|
555
|
+
note = note.parent if note.equal?(note.parent.label)
|
556
|
+
note.iri
|
557
|
+
end
|
558
|
+
|
559
|
+
#
|
560
|
+
# できるだけ IRI を使用するようにしつつ value を JSON 可能な型に変換する
|
561
|
+
#
|
562
|
+
def _value_str(note, value)
|
563
|
+
case value
|
564
|
+
when Integer, Float ; value
|
565
|
+
when When::Parts::Resource
|
566
|
+
value.parent.equal?(note.parent) ? value.to_s :
|
567
|
+
!value.parent.kind_of?(When::BasicTypes::M17n) ? value.parent.iri :
|
568
|
+
value.registered? ? value.iri :
|
569
|
+
value.to_s
|
570
|
+
else ; value.to_s
|
571
|
+
end
|
572
|
+
end
|
573
|
+
end
|
574
|
+
end
|