when_exe 0.4.0 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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