when_exe 0.4.4 → 0.4.5

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.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/lib/when_exe.rb +89 -3
  3. data/lib/when_exe/basictypes.rb +37 -7
  4. data/lib/when_exe/calendarnote.rb +18 -13
  5. data/lib/when_exe/calendartypes.rb +3 -9
  6. data/lib/when_exe/coordinates.rb +23 -373
  7. data/lib/when_exe/ephemeris.rb +7 -7
  8. data/lib/when_exe/ephemeris/notes.rb +0 -14
  9. data/lib/when_exe/events.rb +1851 -0
  10. data/lib/when_exe/icalendar.rb +121 -4
  11. data/lib/when_exe/linkeddata.rb +29 -18
  12. data/lib/when_exe/locales/akt.rb +63 -0
  13. data/lib/when_exe/locales/locale.rb +60 -11
  14. data/lib/when_exe/mini_application.rb +14 -8
  15. data/lib/when_exe/namespace.rb +42 -0
  16. data/lib/when_exe/parts/enumerator.rb +13 -2
  17. data/lib/when_exe/parts/geometric_complex.rb +51 -1
  18. data/lib/when_exe/parts/method_cash.rb +15 -10
  19. data/lib/when_exe/parts/resource.rb +47 -29
  20. data/lib/when_exe/region/chinese.rb +4 -3
  21. data/lib/when_exe/region/chinese/calendars.rb +4 -4
  22. data/lib/when_exe/region/chinese/epochs.rb +6 -6
  23. data/lib/when_exe/region/chinese/notes.rb +3 -3
  24. data/lib/when_exe/region/chinese/twins.rb +6 -6
  25. data/lib/when_exe/region/islamic.rb +1 -1
  26. data/lib/when_exe/region/japanese.rb +4 -4
  27. data/lib/when_exe/region/japanese/eclipses.rb +2 -2
  28. data/lib/when_exe/region/japanese/location.rb +93 -0
  29. data/lib/when_exe/region/japanese/notes.rb +29 -11
  30. data/lib/when_exe/region/japanese/residues.rb +1 -1
  31. data/lib/when_exe/region/japanese/twins.rb +18 -6
  32. data/lib/when_exe/region/location.rb +40 -0
  33. data/lib/when_exe/region/martian.rb +1 -1
  34. data/lib/when_exe/region/ryukyu.rb +1 -1
  35. data/lib/when_exe/spatial.rb +611 -0
  36. data/lib/when_exe/timestandard.rb +3 -3
  37. data/lib/when_exe/tmobjects.rb +32 -0
  38. data/lib/when_exe/tmposition.rb +211 -1318
  39. data/lib/when_exe/tmptypes.rb +1265 -0
  40. data/lib/when_exe/tmreference.rb +35 -0
  41. data/lib/when_exe/version.rb +3 -3
  42. data/test/events/example-datasets +7 -0
  43. data/test/events/history-dataset.csv +22 -0
  44. data/test/events/japanese-holiday-index.csv +28 -0
  45. data/test/events/japanese-holiday.csv +77 -0
  46. data/test/events/japanese-holiday.ttl +778 -0
  47. data/test/events/make_events_ttl.rb +18 -0
  48. data/test/events/mori_wikichoshi.csv +14 -0
  49. data/test/events/ndl_koyomi.csv +220 -0
  50. data/test/events/ndl_koyomi_index.csv +44 -0
  51. data/test/events/primeminister-dataset.csv +19 -0
  52. data/test/events/shogun-dataset.csv +22 -0
  53. data/test/events/test-history-dataset-edge-sparql.csv +26 -0
  54. data/test/events/test-history-dataset-edge.csv +27 -0
  55. data/test/events/test-history-dataset-sparql.csv +22 -0
  56. data/test/events/test-history-dataset.csv +23 -0
  57. data/test/events/test-history-events-edge.ttl +89 -0
  58. data/test/events/test-history-events.csv +6 -0
  59. data/test/examples/Terms.m17n +1 -1
  60. data/test/test.rb +6 -0
  61. data/test/test/coordinates.rb +2 -2
  62. data/test/test/events.rb +32 -0
  63. data/test/test/region/japanese.rb +20 -0
  64. data/test/test/region/m17n.rb +2 -2
  65. data/test/test/region/mayan.rb +6 -6
  66. data/test/test/tmposition.rb +63 -1
  67. metadata +26 -2
@@ -528,6 +528,17 @@ module When::V
528
528
  'resources', 'rdate']]
529
529
  # Classes = [V::Root, V::Alarm]
530
530
 
531
+ RegisteredNotes = {
532
+ 'term' => 'SolarTerms',
533
+ 'phase' => 'LunarPhases',
534
+ 'easter' => 'Christian',
535
+ 'christmas' => 'Christian'
536
+ }
537
+
538
+ RegisteredNoteMethods = /\A(#{RegisteredNotes.keys.sort.reverse.join('|')})/
539
+
540
+ DayOfWeek = %w(SU MO TU WE TH FR SA)
541
+
531
542
  class << self
532
543
  include When::Parts::Resource::Pool
533
544
 
@@ -565,6 +576,101 @@ module When::V
565
576
  def default_until
566
577
  @default_until ||= 1000*When::TM::Duration::YEAR
567
578
  end
579
+
580
+ # ISO8601へ埋め込まれた指定に対応する iterator を生成する
581
+ #
582
+ # @param [When::TM::TemporalPosition] base イベントの始点
583
+ # @param [When::TM::Duration] duration イベントの期間
584
+ # @param [Hash] delayed_options 遅延適用するオブジェクト変換オプション
585
+ #
586
+ # @return [When::Parts::Enumerator]
587
+ #
588
+ def iterator_for_ISO8601(base, duration, delayed_options)
589
+ duration.to_s =~ /\A-?P(\d+)([YM])\z/
590
+ event_options = {'rrule'=>
591
+ case $2
592
+ when 'Y' ; {'FREQ'=>'YEARLY', 'INTERVAL'=>$1.to_i}
593
+ when 'M' ; {'FREQ'=>'MONTHLY', 'INTERVAL'=>$1.to_i}
594
+ else ; duration ? {'FREQ'=>duration.set_repeat(false).abs} : {'FREQ'=>'YEARLY'}
595
+ end
596
+ }
597
+ residue_options = delayed_options[:residue]
598
+ if residue_options
599
+ event_options['rrule'].update(_byyear(residue_options)) if residue_options[0]
600
+ event_options['rrule'].update(_byday(residue_options )) if residue_options[2]
601
+ delayed_options.delete(:residue)
602
+ end
603
+ if base.precision == When::MONTH && event_options['rrule']['FREQ'] == 'YEARLY'
604
+ event_options['rrule'].update({'BYMONTH'=>base[When::MONTH]})
605
+ base = base.floor if event_options['rrule']['BYMONTHDAY']
606
+ end
607
+ case base
608
+ when When::TM::TemporalPosition ; event_options.update({'dtstart' =>base})
609
+ else ; event_options.update({'dtstart' =>base.first,
610
+ 'duration' =>base.last-base.first})
611
+ end
612
+ event_options['duration'] = delayed_options.delete(:duration) if delayed_options[:duration]
613
+ behavior_options = {'1st'=>delayed_options.delete(:first) || "don't care"}
614
+ behavior_options[:delayed] = delayed_options unless delayed_options.empty?
615
+ behavior_options[:direction] = :reverse if duration && duration.sign < 0
616
+ return new(event_options).enum_for(event_options['dtstart'], behavior_options)
617
+ end
618
+
619
+ private
620
+
621
+ # オブジェクト変換オプションの遅延適用のBYYEAR要素
622
+ #
623
+ def _byyear(options)
624
+ {'BYYEAR'=>_to_ical_hash(When.Residue(options.delete(0)), 'year', 4)}
625
+ end
626
+
627
+ # オブジェクト変換オプションの遅延適用のBYDAY要素
628
+ #
629
+ def _byday(options)
630
+ operation = options.delete(2)
631
+ return {'BYDAY'=>_to_ical_hash(operation, 'day', 11)} if operation.kind_of?(When::Coordinates::Residue)
632
+
633
+ residues = []
634
+ result = {}
635
+ byday = {}
636
+
637
+ # イベント、日付
638
+ operation.split('&').each do |element|
639
+ element.strip!
640
+ case element
641
+ when RegisteredNoteMethods ; byday.update({nil=>element})
642
+ when /\A(.+?)#(.+)\z/ ; byday.update({$1=>$2})
643
+ when /\A[-+,\d]+\z/ ; result['BYMONTHDAY'] = element
644
+ else ; residues << element
645
+ end
646
+ end
647
+
648
+ # 剰余類
649
+ unless residues.empty?
650
+ residue = residues.join('&')
651
+ if residue =~ /\A[-+]?\d*(MO|TU|WE|TH|FR|SA|SU)\z/
652
+ result['BYWEEKDAY'] = residue
653
+ else
654
+ resource = When.Residue(residue)
655
+ if resource
656
+ byday.update(_to_ical_hash(resource, 'day', 11))
657
+ else
658
+ result['BYWEEKDAY'] = residue
659
+ end
660
+ end
661
+ end
662
+
663
+ result['BYDAY'] = byday unless byday.empty?
664
+ return result
665
+ end
666
+
667
+ # 剰余のハッシュ化
668
+ def _to_ical_hash(residue, unit, offset)
669
+ operation = ''
670
+ operation << "#{residue.carry < 0 ? residue.carry : residue.carry+1}*" if residue.shifted
671
+ operation << "#{(residue.remainder-offset+residue.units[unit]) % residue.divisor}"
672
+ {residue.divisor=>operation}
673
+ end
568
674
  end
569
675
 
570
676
  # SUMMARY Property
@@ -1065,6 +1171,7 @@ module When::V
1065
1171
  @options = When::Parts::Enumerator._options(args)
1066
1172
  @exdate = @options.delete(:exdate)
1067
1173
  @exevent = @options.delete(:exevent)
1174
+ @delayed = @options.delete(:delayed)
1068
1175
  @parent, @rule, @dtstart, @duration, *rest = args
1069
1176
  @dtstart = When.when?(@dtstart)
1070
1177
  @rule = self.class._decode_rule(@rule, @dtstart) if (@rule.kind_of?(String))
@@ -1267,7 +1374,7 @@ module When::V
1267
1374
  position = rule[(by_part == 'BYYEAR') ? 'YEARPOS' : 'DAYPOS'][ref]
1268
1375
  start = rule[(by_part == 'BYYEAR') ? 'YEARST' : 'DAYST' ][ref]
1269
1376
  rule[by_part][ref] = ((ref.to_i==0) ? Logic::Enumerator :
1270
- Logic::Residue).new(by_part, list, position, ref, start)
1377
+ Logic::Residue).new(by_part, list, position, ref, start, dtstart)
1271
1378
  end
1272
1379
  end
1273
1380
  end
@@ -1457,7 +1564,7 @@ module When::V
1457
1564
  end
1458
1565
 
1459
1566
  # @private
1460
- def initialize(by_part, list, position, ref, start)
1567
+ def initialize(by_part, list, position, ref, start, dtstart)
1461
1568
  @by_part = by_part
1462
1569
  divisor = When::Coordinates::Pair._en_number(ref)
1463
1570
  @list = list.split(/,/).map {|w|
@@ -1519,9 +1626,19 @@ module When::V
1519
1626
  end
1520
1627
 
1521
1628
  # @private
1522
- def initialize(by_part, list, position, ref, start)
1629
+ def initialize(by_part, list, position, ref, start, dtstart)
1523
1630
  @by_part = by_part
1524
- @ref = When.Resource(ref, '_n:')
1631
+ @ref =
1632
+ if ref
1633
+ When.Resource(ref, '_n:')
1634
+ else
1635
+ method = list[/\A[^-+\d]+/]
1636
+ if dtstart.frame.note.respond_to?(method)
1637
+ dtstart.frame.note
1638
+ else
1639
+ When.Resource(When::V::Event::RegisteredNotes[method], '_n:')
1640
+ end
1641
+ end
1525
1642
  @start = start
1526
1643
  @list = list.split(/,/).map {|w|
1527
1644
  raise ArgumentError, "The #{by_part} rule format error" unless w =~ /\A(([-+]?\d+)\*)?(.+?)([-+]\d+)?\z/
@@ -40,12 +40,19 @@ module When
40
40
  'latitude' => "Coordinates/Spatial#latitude-instance_method",
41
41
  'altitide' => "Coordinates/Spatial#latitude-instance_method",
42
42
  'event' => "CalendarNote#event-instance_method",
43
+ 'note' => "CalendarNote/NoteElement",
44
+ 'id' => "Events/Event#id-instance_method",
45
+ 'group' => "Events/Event#group-instance_method",
46
+ 'start' => "Events/Range#start-instance_method",
47
+ 'until' => "Events/Range#until-instance_method",
48
+ 'west' => "Coordinates/Spatial/Range#west-instance_method",
49
+ 'east' => "Coordinates/Spatial/Range#east-instance_method",
50
+ 'south' => "Coordinates/Spatial/Range#south-instance_method",
51
+ 'north' => "Coordinates/Spatial/Range#north-instance_method",
52
+ 'bottom' => "Coordinates/Spatial/Range#bottom-instance_method",
53
+ 'top' => "Coordinates/Spatial/Range#top-instance_method"
43
54
  }
44
55
 
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
56
  #
50
57
  # @private
51
58
  #
@@ -85,8 +92,9 @@ module When
85
92
  def schema(iri=nil)
86
93
  ts = base_uri.sub(/When\/$/, 'ts#')
87
94
  hash =
88
- {'@context'=>{'ts' => ts},
89
- '@graph' => Schema.keys.map {|id| {'@id'=>'ts:'+id, 'ts:reference'=>{'@id'=>DocRoot + Schema[id]}}}
95
+ {'@context'=>{'rdf'=>When::Namespace::RDF, 'ts' => ts},
96
+ '@graph' => Schema.keys.map {|id| {'@id'=>'ts:'+id, 'rdf:type'=>{'@id'=>'rdf:Property'},
97
+ 'ts:reference'=>{'@id'=>DocRoot + Schema[id]}}}
90
98
  }
91
99
  bless(hash, iri || ts[0..-2])
92
100
  end
@@ -117,7 +125,7 @@ module When
117
125
  JSON.generate(jsonld_hash)
118
126
  else
119
127
  array = JSON::LD::API.toRdf(jsonld_hash)
120
- graph = ::RDF::Graph.new << array
128
+ graph = RDF::Graph.new << array
121
129
  args = [writer]
122
130
  args << {:prefixes=>prefixes} if prefixes
123
131
  graph.dump(*args)
@@ -162,13 +170,13 @@ module When
162
170
  def namespace_prefixes(*resources)
163
171
  base = base_uri.sub(/When\/$/, '')
164
172
  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/'],
173
+ 'xsd' => [When::Namespace::XSD ],
174
+ 'rdf' => [When::Namespace::RDF ],
175
+ 'rdfs' => [When::Namespace::RDFS],
176
+ 'owl' => [When::Namespace::OWL ],
177
+ 'dc' => [When::Namespace::DC ],
178
+ 'dcq' => [When::Namespace::DCQ ],
179
+ 'dct' => [When::Namespace::DCT ],
172
180
  # 'tp' => [base + 'tp/'],
173
181
  'ts' => [base + 'ts#']
174
182
  }) {|namespace, resource|
@@ -315,6 +323,8 @@ module When
315
323
  hash[key] = value if /^@/ =~ key.to_s
316
324
  end
317
325
  hash[RDF + 'type'] = {'@id'=>base + 'ts/' + self.class.to_s.gsub(/::/, '/')}
326
+ hash[RDFS + 'subPropertyOf'] = {'@id'=>base + 'ts#note'} if kind_of?(When::CalendarNote::NoteElement) ||
327
+ kind_of?(When::Parts::Resource) && /\/notes\// =~ iri && !leaf?
318
328
  if options[:context]
319
329
  options[:prefixes] ||= When::Parts::Resource.namespace_prefixes
320
330
  context = hash['@context'] || {}
@@ -371,9 +381,10 @@ module When
371
381
  def compact_namespace_to_prefix(source, prefixes, context=nil)
372
382
  return source unless prefixes
373
383
  prefixes.each_pair do |key, value|
374
- Array(value).each do |prefix|
375
- start = source.index(prefix)
376
- body = source[prefix.length..-1]
384
+ Array(value).each do |namespace|
385
+ namespace = namespace.sub(/([a-z0-9])\z/i, '\1#')
386
+ start = source.index(namespace)
387
+ body = source[namespace.length..-1]
377
388
  return key + ':' + body if start == 0 && body !~ /[:#\/]/
378
389
  end
379
390
  end
@@ -459,7 +470,7 @@ module When
459
470
  #
460
471
  def to_uri_linkeddata(*args)
461
472
  date, frame = _to_uri(to_s(*args)).split('^^', 2)
462
- frame += '_' if frame =~ /\d\z/
473
+ frame += '_' if /\d\z/ =~ frame
463
474
  date = "#{frame}(#{date})" if frame
464
475
  When::Parts::Resource.base_uri.sub(/When\/$/, 'tp/') + date
465
476
  end
@@ -147,6 +147,35 @@ module When
147
147
  # @private
148
148
  IAST_K_keys = transliteration_keys(IAST_K)
149
149
 
150
+ # @private
151
+ NumAlter1 = [['〇','零'], [/[壱壹]/,'一'], [/[弐貳]/,'二'], [/[弎参參]/,'三'], ['肆','四'],
152
+ ['伍','五'], ['陸','六'], ['柒','七'], ['捌','八'], ['玖','九'], ['拾','十'],
153
+ ['廿', '二十'], [/[卅丗]/, '三十'], ['卌', '四十'],
154
+ ['佰', '百'], ['仟', '千'], ['萬', '万'], ['秭', '𥝱']]
155
+
156
+ # @private
157
+ NumAlter2 = [['零〇','0'], ['一壱壹','1'], ['二弐貳','2'], ['三弎参參','3'], ['四肆','4'],
158
+ ['五伍','5'], ['六陸','6'], ['七柒','7'], ['八捌','8'], ['九玖','9']]
159
+
160
+ # @private
161
+ Numbers = %w(零 一 二 三 四 五 六 七 八 九 十 百 千 万 億 兆 京 垓 𥝱
162
+ 穣 溝 澗 正 載 極 恒河沙 阿僧祇 那由他 不可思議 無量大数)
163
+
164
+ # @private
165
+ NumRExp1 = /#{Numbers[10..12].reverse.map {|num| "(?:(.*)#{num})"}.join('?')}?(.*)/
166
+
167
+ # public
168
+ NumRExp3 = /([#{Numbers[0..12].join('')}廿卅丗卌]+)/
169
+
170
+ # @private
171
+ NumRExp4 = /#{Numbers[13..-1].reverse.map {|num| "(?:(.*)#{num})"}.join('?')}?(.*)/
172
+
173
+ # @private
174
+ NumMap = Hash[*(Numbers[0..9].zip((0..9).to_a)).flatten]
175
+
176
+ # @private
177
+ DigitMap = [1,1,1,0]
178
+
150
179
  #
151
180
  # Convert AKT string to katakana scripts
152
181
  #
@@ -173,5 +202,39 @@ module When
173
202
  gsub(/([rm])y/, '\1uy'),
174
203
  locale)
175
204
  end
205
+
206
+ #
207
+ # Convert kanji scripts to numeric
208
+ #
209
+ def self.k2a_digits(figures, force_alter=false)
210
+ if force_alter
211
+ figures = figures.dup
212
+ NumAlter1.each {|alter| figures.gsub!(*alter)}
213
+ end
214
+ sum = 0
215
+ NumRExp4 =~ figures
216
+ $~.to_a[1..-1].each do |wide_match|
217
+ if NumRExp1 =~ wide_match
218
+ $~.to_a[1..-1].each_with_index do |match,digit|
219
+ sum *= 10
220
+ sum += (NumMap[match] || DigitMap[digit]) if match
221
+ end
222
+ else
223
+ sum *= 10000
224
+ end
225
+ end
226
+ sum
227
+ end
228
+
229
+ #
230
+ # Convert zenkaku figures to numeric
231
+ #
232
+ def self.z2h_digits(figures, force_alter=false)
233
+ if force_alter
234
+ figures = figures.dup
235
+ NumAlter2.each {|alter| figures.tr!(*alter)}
236
+ end
237
+ figures.tr('0123456789', '0123456789').to_i
238
+ end
176
239
  end
177
240
  end
@@ -63,6 +63,10 @@ module When
63
63
  # @private
64
64
  Link = /<li class="interlanguage-link interwiki-(.+?)"><a href="\/\/(.+?)\.wikipedia\.org\/wiki\/(.+?)" title="(.+?) – /
65
65
 
66
+ # NUL for Escape
67
+ # @private
68
+ NUL = 0.chr
69
+
66
70
  class << self
67
71
 
68
72
  # Wikipedia の連続的な参照を抑制するための遅延時間/秒
@@ -134,6 +138,29 @@ module When
134
138
  source
135
139
  end
136
140
 
141
+ # 暦要素を含む文字列を Hash に分解する
142
+ #
143
+ # @param [String] date_time 暦要素を含む文字列
144
+ # @param [String or Hash] format 分解する書式
145
+ # @param [String] locale 言語指定
146
+ #
147
+ # @return [Hash] 暦要素を分解格納した Hash
148
+ #
149
+ def _to_date_time_hash(date_time, format, locale=nil)
150
+ if locale
151
+ format = format.kind_of?(String) ?
152
+ translate(format, locale) :
153
+ _hash_value(format, locale)
154
+ unless locale == 'en'
155
+ regexp, hash = _trans_table(locale)
156
+ date_time = date_time.gsub(regexp) {|match| hash[match]}
157
+ end
158
+ end
159
+ ::DateTime._strptime(date_time, format)
160
+ rescue NameError
161
+ raise "Please require standard library 'Date' or 'DateTime'"
162
+ end
163
+
137
164
  # 包摂リストに登録されている文字を包摂する
138
165
  #
139
166
  # @param [When::Locale] source 文字を包摂しようとする国際化文字列
@@ -243,20 +270,27 @@ module When
243
270
  }
244
271
  end
245
272
 
246
- # locale 指定を解析して Hash の値を取り出す
273
+ # locale 指定を解析して key の値を取り出す
247
274
  # @private
248
- def _hash_value(hash, locale, defaults=['', 'en'])
275
+ def _hash_key(hash, locale, defaults=['', 'en'])
249
276
  locale = locale.sub(/\..*/, '')
250
- return hash[locale] if hash[locale]
251
- return _hash_value(hash, _alias[locale], defaults) if _alias[locale]
252
- language = locale.sub(/-.*/, '')
253
- return hash[language] if hash[language]
277
+ return locale if hash.key?(locale)
278
+ return _hash_key(hash, _alias[locale], defaults) if _alias.key?(locale)
279
+ language = locale.sub(/[-_].*/, '')
280
+ return language if hash.key?(language)
254
281
  defaults.each do |default|
255
- return hash[default] if hash[default]
282
+ return default if hash.key?(default)
256
283
  end
257
284
  return nil
258
285
  end
259
286
 
287
+ # locale 指定を解析して Hash の値を取り出す
288
+ # @private
289
+ def _hash_value(hash, locale, defaults=['', 'en'])
290
+ key = _hash_key(hash, locale, defaults)
291
+ key ? hash[key] : nil
292
+ end
293
+
260
294
  # 漢字の包摂パターン
261
295
  # @private
262
296
  def _unification
@@ -269,7 +303,7 @@ module When
269
303
  access_key = access_key.split(/\//).map {|key| key =~ /\A[0-9]+\z/ ? key.to_i : key}
270
304
  locale = locale.sub(/\..*/, '')
271
305
  [locale, locale.sub(/-.*/, '')].each do |loc|
272
- symbol = ('Locale_' + loc.sub(/-/,'_')).to_sym
306
+ symbol = ('Locale_' + loc.gsub(/-/,'_')).to_sym
273
307
  return {locale=>access_key.inject(const_get(symbol)) {|hash, key| hash = hash[key]}} if const_defined?(symbol)
274
308
  end
275
309
  return nil
@@ -283,7 +317,7 @@ module When
283
317
  # @private
284
318
  def _dbpedia(source)
285
319
  return nil unless Ref =~ source
286
- return "http://#{$1=='en' ? '' : $1+'.'}dbpedia.org/resource/#{URI.decode($2)}"
320
+ return "http://#{$1=='en' ? '' : $1+'.'}dbpedia.org/resource/#{CGI.unescape($2)}"
287
321
  end
288
322
 
289
323
  private
@@ -309,7 +343,7 @@ module When
309
343
  # wikipedia の読み込み
310
344
  def _wikipedia_object(path, locale, file, query, interval, options)
311
345
  # 採取済みデータ
312
- title = URI.decode(file.gsub('_', ' '))
346
+ title = CGI.unescape(file.gsub('_', ' '))
313
347
  mode = "".respond_to?(:force_encoding) ? ':utf-8' : ''
314
348
  dir = When::Parts::Resource.root_dir + '/data/wikipedia/' + locale
315
349
  FileUtils.mkdir_p(dir) unless FileTest.exist?(dir)
@@ -391,6 +425,21 @@ module When
391
425
  object._pool['..'] += '?' + query if query
392
426
  object
393
427
  end
428
+
429
+ # 月名と週名の翻訳テーブル
430
+ def _trans_table(locale)
431
+ return @trans_table[locale] if @trans_table && @trans_table[locale]
432
+ hash = Hash[*(%w(_m:Calendar::Month::* _m:Calendar::Abbr_Month::*
433
+ _co:Common::Week::* _co:Common::Abbr_Day::*).inject([]) {|list, iri|
434
+ list.concat(When.Resource(iri).map {|resource|
435
+ label = resource.kind_of?(When::BasicTypes::M17n) ? resource : resource.label
436
+ [label.translate(locale), label.translate('en')]
437
+ })
438
+ }.sort_by {|pair| -(pair.first.length*100+pair.last.length)}).flatten]
439
+ regexp = /#{hash.keys.sort_by {|key| -key.length}.join('|')}/
440
+ @trans_table ||= {}
441
+ @trans_table[locale] = [regexp, hash]
442
+ end
394
443
  end
395
444
 
396
445
  # ローケール指定時の文字列
@@ -785,7 +834,7 @@ module When
785
834
  # encode URI from patterns %%(...) or %.(...) and replace space to '_'
786
835
  def _encode(source)
787
836
  source.gsub(' ','_').gsub(/%.<.+?>/) { |match|
788
- URI.encode(match[3..-2]).gsub('%', match[1..1])
837
+ CGI.escape(match[3..-2]).gsub('%', match[1..1])
789
838
  }
790
839
  end
791
840
  end