when_exe 0.3.5 → 0.3.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (194) hide show
  1. data/bin/irb.rc +1 -0
  2. data/bin/locales.rb +8 -6
  3. data/bin/when.rb +1 -1
  4. data/lib/when_exe.rb +231 -146
  5. data/lib/when_exe/basictypes.rb +108 -18
  6. data/lib/when_exe/calendarnote.rb +263 -116
  7. data/lib/when_exe/calendartypes.rb +413 -22
  8. data/lib/when_exe/coordinates.rb +58 -36
  9. data/lib/when_exe/core/compatibility.rb +8 -6
  10. data/lib/when_exe/core/extension.rb +40 -15
  11. data/lib/when_exe/ephemeris.rb +20 -19
  12. data/lib/when_exe/{region → ephemeris}/moon.rb +4 -4
  13. data/lib/when_exe/{region/ephemeric_notes.rb → ephemeris/notes.rb} +25 -6
  14. data/lib/when_exe/{region → ephemeris}/planets.rb +0 -0
  15. data/lib/when_exe/{region → ephemeris}/sun.rb +7 -3
  16. data/lib/when_exe/{region → ephemeris}/v50.rb +0 -0
  17. data/lib/when_exe/googlecalendar.rb +2 -2
  18. data/lib/when_exe/icalendar.rb +3 -3
  19. data/lib/when_exe/inspect.rb +130 -70
  20. data/lib/when_exe/locales/af.rb +2 -2
  21. data/lib/when_exe/locales/akt.rb +176 -0
  22. data/lib/when_exe/locales/ar.rb +2 -2
  23. data/lib/when_exe/locales/{locales.rb → autoload.rb} +6 -2
  24. data/lib/when_exe/locales/az.rb +2 -2
  25. data/lib/when_exe/locales/bg.rb +2 -2
  26. data/lib/when_exe/locales/bn.rb +2 -2
  27. data/lib/when_exe/locales/bs.rb +2 -2
  28. data/lib/when_exe/locales/ca.rb +2 -2
  29. data/lib/when_exe/locales/cs.rb +2 -2
  30. data/lib/when_exe/locales/cy.rb +2 -2
  31. data/lib/when_exe/locales/da.rb +2 -2
  32. data/lib/when_exe/locales/de.rb +2 -2
  33. data/lib/when_exe/locales/de_AT.rb +2 -2
  34. data/lib/when_exe/locales/de_CH.rb +2 -2
  35. data/lib/when_exe/locales/el.rb +2 -2
  36. data/lib/when_exe/locales/en.rb +2 -2
  37. data/lib/when_exe/locales/en_AU.rb +2 -2
  38. data/lib/when_exe/locales/en_CA.rb +2 -2
  39. data/lib/when_exe/locales/en_GB.rb +2 -2
  40. data/lib/when_exe/locales/en_IE.rb +2 -2
  41. data/lib/when_exe/locales/en_IN.rb +3 -3
  42. data/lib/when_exe/locales/en_NZ.rb +2 -2
  43. data/lib/when_exe/locales/en_US.rb +2 -2
  44. data/lib/when_exe/locales/en_ZA.rb +88 -0
  45. data/lib/when_exe/locales/encoding_conversion.rb +126 -0
  46. data/lib/when_exe/locales/eo.rb +2 -2
  47. data/lib/when_exe/locales/es.rb +2 -2
  48. data/lib/when_exe/locales/es_419.rb +2 -2
  49. data/lib/when_exe/locales/es_AR.rb +2 -2
  50. data/lib/when_exe/locales/es_CL.rb +2 -2
  51. data/lib/when_exe/locales/es_CO.rb +2 -2
  52. data/lib/when_exe/locales/es_CR.rb +2 -2
  53. data/lib/when_exe/locales/es_EC.rb +2 -2
  54. data/lib/when_exe/locales/es_MX.rb +2 -2
  55. data/lib/when_exe/locales/es_PA.rb +2 -2
  56. data/lib/when_exe/locales/es_PE.rb +2 -2
  57. data/lib/when_exe/locales/es_US.rb +84 -0
  58. data/lib/when_exe/locales/es_VE.rb +2 -2
  59. data/lib/when_exe/locales/et.rb +2 -2
  60. data/lib/when_exe/locales/eu.rb +2 -2
  61. data/lib/when_exe/locales/fa.rb +2 -2
  62. data/lib/when_exe/locales/fi.rb +3 -3
  63. data/lib/when_exe/locales/fr.rb +2 -2
  64. data/lib/when_exe/locales/fr_CA.rb +2 -2
  65. data/lib/when_exe/locales/fr_CH.rb +2 -2
  66. data/lib/when_exe/locales/gl.rb +2 -2
  67. data/lib/when_exe/locales/he.rb +3 -3
  68. data/lib/when_exe/locales/hi.rb +2 -2
  69. data/lib/when_exe/locales/hi_IN.rb +2 -2
  70. data/lib/when_exe/locales/hr.rb +2 -2
  71. data/lib/when_exe/locales/hu.rb +6 -5
  72. data/lib/when_exe/locales/iast.rb +90 -0
  73. data/lib/when_exe/locales/id.rb +2 -2
  74. data/lib/when_exe/locales/is.rb +2 -2
  75. data/lib/when_exe/locales/it.rb +2 -2
  76. data/lib/when_exe/locales/it_CH.rb +2 -2
  77. data/lib/when_exe/locales/ja.rb +2 -2
  78. data/lib/when_exe/locales/kn.rb +2 -2
  79. data/lib/when_exe/locales/ko.rb +2 -2
  80. data/lib/when_exe/locales/links.rb +3 -3
  81. data/lib/when_exe/locales/lo.rb +2 -2
  82. data/lib/when_exe/{parts → locales}/locale.rb +77 -49
  83. data/lib/when_exe/locales/lt.rb +6 -2
  84. data/lib/when_exe/locales/lv.rb +2 -2
  85. data/lib/when_exe/locales/mk.rb +2 -2
  86. data/lib/when_exe/locales/mn.rb +2 -2
  87. data/lib/when_exe/locales/ms.rb +2 -2
  88. data/lib/when_exe/locales/nb.rb +2 -2
  89. data/lib/when_exe/locales/ne.rb +2 -2
  90. data/lib/when_exe/locales/nl.rb +2 -2
  91. data/lib/when_exe/locales/nn.rb +2 -2
  92. data/lib/when_exe/locales/or.rb +2 -2
  93. data/lib/when_exe/locales/pl.rb +2 -2
  94. data/lib/when_exe/locales/pt.rb +2 -2
  95. data/lib/when_exe/locales/pt_BR.rb +2 -2
  96. data/lib/when_exe/locales/rm.rb +2 -2
  97. data/lib/when_exe/locales/ro.rb +2 -2
  98. data/lib/when_exe/locales/ru.rb +2 -2
  99. data/lib/when_exe/locales/sk.rb +2 -2
  100. data/lib/when_exe/locales/sl.rb +2 -2
  101. data/lib/when_exe/locales/sr.rb +2 -2
  102. data/lib/when_exe/locales/sv.rb +2 -2
  103. data/lib/when_exe/locales/sw.rb +2 -2
  104. data/lib/when_exe/locales/ta.rb +95 -0
  105. data/lib/when_exe/locales/th.rb +2 -2
  106. data/lib/when_exe/locales/tl.rb +3 -3
  107. data/lib/when_exe/locales/tr.rb +2 -2
  108. data/lib/when_exe/locales/transliteration_table.rb +62 -0
  109. data/lib/when_exe/locales/uk.rb +15 -15
  110. data/lib/when_exe/locales/ur.rb +2 -2
  111. data/lib/when_exe/locales/uz.rb +2 -2
  112. data/lib/when_exe/locales/vi.rb +2 -2
  113. data/lib/when_exe/locales/wo.rb +2 -2
  114. data/lib/when_exe/locales/zh_CN.rb +2 -2
  115. data/lib/when_exe/locales/zh_HK.rb +15 -15
  116. data/lib/when_exe/locales/zh_TW.rb +2 -2
  117. data/lib/when_exe/locales/zh_YUE.rb +77 -0
  118. data/lib/when_exe/mini_application.rb +22 -12
  119. data/lib/when_exe/parts/geometric_complex.rb +16 -1
  120. data/lib/when_exe/parts/method_cash.rb +184 -238
  121. data/lib/when_exe/parts/resource.rb +65 -16
  122. data/lib/when_exe/region/armenian.rb +56 -0
  123. data/lib/when_exe/region/bahai.rb +13 -13
  124. data/lib/when_exe/region/balinese.rb +33 -35
  125. data/lib/when_exe/region/chinese.rb +82 -78
  126. data/lib/when_exe/region/{chinese_calendar.rb → chinese/calendars.rb} +59 -40
  127. data/lib/when_exe/region/{chinese_epoch.rb → chinese/epochs.rb} +3 -4
  128. data/lib/when_exe/region/{chinese_twin.rb → chinese/twins.rb} +48 -51
  129. data/lib/when_exe/region/christian.rb +236 -127
  130. data/lib/when_exe/region/coptic.rb +9 -10
  131. data/lib/when_exe/region/dee.rb +48 -0
  132. data/lib/when_exe/region/discordian.rb +225 -0
  133. data/lib/when_exe/region/far_east.rb +2 -6
  134. data/lib/when_exe/region/french.rb +7 -17
  135. data/lib/when_exe/region/geologicalage.rb +0 -1
  136. data/lib/when_exe/region/goddess.rb +58 -0
  137. data/lib/when_exe/region/indian.rb +323 -231
  138. data/lib/when_exe/region/iranian.rb +159 -22
  139. data/lib/when_exe/region/islamic.rb +7 -9
  140. data/lib/when_exe/region/japanese.rb +14 -803
  141. data/lib/when_exe/region/japanese/calendars.rb +397 -0
  142. data/lib/when_exe/region/japanese/epochs.rb +426 -0
  143. data/lib/when_exe/region/{nihon_shoki.rb → japanese/nihon_shoki.rb} +0 -2
  144. data/lib/when_exe/region/{japanese_notes.rb → japanese/notes.rb} +179 -150
  145. data/lib/when_exe/region/japanese/residues.rb +1306 -0
  146. data/lib/when_exe/region/{japanese_twin.rb → japanese/twins.rb} +12 -15
  147. data/lib/when_exe/region/javanese.rb +16 -14
  148. data/lib/when_exe/region/jewish.rb +8 -9
  149. data/lib/when_exe/region/korean.rb +146 -35
  150. data/lib/when_exe/region/m17n.rb +8 -10
  151. data/lib/when_exe/region/martian.rb +44 -16
  152. data/lib/when_exe/region/mayan.rb +12 -10
  153. data/lib/when_exe/region/pope.rb +0 -1
  154. data/lib/when_exe/region/residue.rb +4 -5
  155. data/lib/when_exe/region/roman.rb +20 -24
  156. data/lib/when_exe/region/ryukyu.rb +3 -4
  157. data/lib/when_exe/region/shire.rb +97 -94
  158. data/lib/when_exe/region/symmetry.rb +50 -0
  159. data/lib/when_exe/region/thai.rb +164 -56
  160. data/lib/when_exe/region/tibetan.rb +86 -86
  161. data/lib/when_exe/region/vietnamese.rb +9 -12
  162. data/lib/when_exe/region/weekdate.rb +80 -0
  163. data/lib/when_exe/region/world.rb +65 -70
  164. data/lib/when_exe/region/yerm.rb +98 -0
  165. data/lib/when_exe/region/zoroastrian.rb +203 -0
  166. data/lib/when_exe/timestandard.rb +4 -4
  167. data/lib/when_exe/tmobjects.rb +1 -3
  168. data/lib/when_exe/tmposition.rb +13 -12
  169. data/lib/when_exe/tmreference.rb +11 -10
  170. data/lib/when_exe/version.rb +1 -1
  171. data/link_to_online_documents +3 -3
  172. data/test/examples/Residue.m17n +1 -1
  173. data/test/examples/Terms.m17n +1 -1
  174. data/test/test.rb +2 -1
  175. data/test/test/basictypes.rb +18 -2
  176. data/test/test/calendarnote.rb +1 -1
  177. data/test/test/calendartypes.rb +1 -1
  178. data/test/test/coordinates.rb +7 -7
  179. data/test/test/{region → ephemeris}/moon.rb +0 -0
  180. data/test/test/{region → ephemeris}/planets.rb +0 -0
  181. data/test/test/{region → ephemeris}/sun.rb +0 -0
  182. data/test/test/parts.rb +8 -13
  183. data/test/test/region/christian.rb +245 -0
  184. data/test/test/region/french.rb +16 -16
  185. data/test/test/region/iran.rb +34 -34
  186. data/test/test/region/japanese.rb +6 -4
  187. data/test/test/region/m17n.rb +8 -7
  188. data/test/test/region/mayan.rb +12 -12
  189. data/test/test/region/residue.rb +20 -4
  190. data/test/test/region/thai.rb +25 -3
  191. data/test/test/region/yerm.rb +146 -0
  192. metadata +39 -20
  193. data/lib/when_exe/region/japanese_residues.rb +0 -1212
  194. data/test/test/region/civil.rb +0 -124
@@ -27,6 +27,7 @@ module When
27
27
  # @option options [String, Array<String, Integer>] :era_name デフォルトの年号(Integerは0年に対応する通年)
28
28
  # @option options [Array<Numeric>] :abbr 上位省略形式で使用する上位部分
29
29
  # @option options [Integer] :extra_year_digits ISO8601拡大表記のための年の構成要素拡大桁数(省略時 1桁)
30
+ # @option options [Integer] :ordinal_date_digits ISO8601拡大表記の年内通日の桁数(省略時 3桁)
30
31
  #
31
32
  # @return [Array] format, date, time, clock, era
32
33
  #
@@ -47,7 +48,7 @@ module When
47
48
  def _to_array(date_time, options={})
48
49
  raise TypeError, "Argument is not ISO 8601 String" unless date_time.kind_of?(String)
49
50
  if options[:abbr].kind_of?(When::TimeValue)
50
- options[:abbr] = ((options[:frame]||When.Calendar('Gregorian')) ^ options[:abbr]).cal_date
51
+ options[:abbr] = ((options[:frame]||When::Gregorian) ^ options[:abbr]).cal_date
51
52
  end
52
53
  date_time = date_time.gsub(/_([\d])/, '\1')
53
54
  begin
@@ -93,8 +94,12 @@ module When
93
94
 
94
95
  case date_time
95
96
  # extended date & time format (ISO 8601)
96
- when /^([-+*&%@!>=<?\dW.]+)(?:(T([:*=.,\d]+)?)([A-Z]+(\?.+)?|[-+][:\d]+)?)?$/
97
+ when /^([-+*&%@!>=<?\dW.\(\)]+)(?:(T([:*=.,\d]+)?)([A-Z]+(\?.+)?|[-+][:\d]+)?)?$/
97
98
  d, t, time, clock = $~[1..4]
99
+ if d =~ /[\(\)]/
100
+ d = When::CalendarTypes::Yerm.parse(d, options[:abbr])
101
+ options[:frame] ||= 'Yerm'
102
+ end
98
103
  format, date = Date._to_array_extended_ISO8601(d, options)
99
104
 
100
105
  # extended date & time format (JIS X0301)
@@ -147,6 +152,11 @@ module When
147
152
  end
148
153
  }
149
154
 
155
+ # @private
156
+ Ordinal_Date_Digits = Hash.new {|hash, key|
157
+ hash[key] = /^(\d{#{(key || 3).to_i}})$/
158
+ }
159
+
150
160
  class << self
151
161
  # ISO 8601 基本形式の表現を分解して配列化する
152
162
  def _to_array_basic_ISO8601(date, options={})
@@ -220,7 +230,7 @@ module When
220
230
  dd << Coordinates::Pair._en_pair(_completion($1, abbr.shift), $2)
221
231
  dd << Coordinates::Pair._en_pair($3, $4)
222
232
  return :week, dd
223
- when /^(\d{3})$/
233
+ when Ordinal_Date_Digits[options[:ordinal_date_digits]]
224
234
  dd << $1.to_i
225
235
  return :day, dd
226
236
  when /^(\d+#{abbr[0] ? '|-' : ''})([-+*&%@!>=<?.])?$/
@@ -403,26 +413,82 @@ module When
403
413
  # 代表的な authority の URI
404
414
  # @namespace[''] である
405
415
  #
406
- # see {When::Parts::Locale}, {When::Parts::Resource}
416
+ # see {When::Locale}, {When::Parts::Resource}
407
417
  #
408
418
  class M17n < Code
409
- include Parts::Locale
419
+ include When::Locale
410
420
  include Parts::Resource
411
421
 
412
422
  # @private
413
- def self._get_locale(locale, access_key)
414
- return nil unless access_key
415
- access_key = access_key.split(/\//).map {|key| key =~ /^[0-9]+$/ ? key.to_i : key}
416
- locale = locale.sub(/\..*/, '').sub(/-/,'_')
417
- [locale, locale.sub(/_.*/, '')].each do |loc|
418
- symbol = ('Locale_' + loc).to_sym
419
- return {loc=>access_key.inject(const_get(symbol)) {|hash, key| hash = hash[key]}} if (const_defined?(symbol))
420
- end
421
- return nil
422
- end
423
+ HashProperty = [:label, :names, :link, :access_key, :code_space]
423
424
 
424
425
  # @private
425
- HashProperty = [:label, :names, :link, :access_key, :code_space]
426
+ LabelTypes = {
427
+ 'Residue' => ['Coordinates', '%s', '_co:%s%s' ],
428
+ 'Week' => ['CalendarNote', '%sWeek', '_n:%sWeek%s' ],
429
+ 'Notes' => ['CalendarNote', '%s', '_n:%s/Notes%s'],
430
+ nil => ['BasicTypes::M17n', '%s', '_m:%s%s' ]
431
+ }
432
+
433
+ class << self
434
+
435
+ #
436
+ # resource の取得
437
+ #
438
+ # @param [When::Parts::Resource, String] source
439
+ #
440
+ # @return [When::Parts::Resource]
441
+ #
442
+ # @private
443
+ def _label(source)
444
+ case source
445
+ when Parts::Resource, nil ; return source
446
+ when Parts::Resource::IRIHeader ; return Parts::Resource._instance(source)
447
+ end
448
+ iri = Parts::Resource._abbreviation_to_iri(source, LabelTypes)
449
+ iri ? Parts::Resource._instance(iri) : nil
450
+ end
451
+
452
+ #
453
+ # label の取得
454
+ #
455
+ # @param [When::Parts::Resource, String] source
456
+ #
457
+ # @return [When::BasicTypes::M17n, String]
458
+ #
459
+ def label(source)
460
+ resource = _label(source)
461
+ case resource
462
+ when nil ; return source
463
+ when M17n ; return resource
464
+ when Parts::Resource ; return resource.label
465
+ else ; return resource
466
+ end
467
+ end
468
+
469
+ #
470
+ # label の Array の取得
471
+ #
472
+ # @param [When::Parts::Resource, Array] source
473
+ #
474
+ # @return [Array]
475
+ #
476
+ def labels(source)
477
+ array =
478
+ if source.kind_of?(Array)
479
+ source
480
+ else
481
+ resource = _label(source)
482
+ return nil unless resource
483
+ resource.child
484
+ end
485
+ case array[0]
486
+ when M17n ; return array
487
+ when Parts::Resource ; return array.map {|v| v.label}
488
+ else ; return array
489
+ end
490
+ end
491
+ end
426
492
 
427
493
  #
428
494
  # 代表名
@@ -447,6 +513,30 @@ module When
447
513
  self
448
514
  end
449
515
 
516
+ #
517
+ # 内部エンコーディング文字列化
518
+ #
519
+ def to_internal_encoding
520
+ _copy({:label => When::EncodingConversion.to_internal_encoding(to_s),
521
+ :names => Hash[*(names.keys.map {|name| [name, When::EncodingConversion.to_internal_encoding(names[name])]}).flatten],
522
+ :link => link,
523
+ :access_key => access_key,
524
+ :code_space => code_space
525
+ })
526
+ end
527
+
528
+ #
529
+ # 外部エンコーディング文字列化
530
+ #
531
+ def to_external_encoding
532
+ _copy({:label => When::EncodingConversion.to_external_encoding(to_s),
533
+ :names => Hash[*(names.keys.map {|name| [name, When::EncodingConversion.to_external_encoding(names[name])]}).flatten],
534
+ :link => link,
535
+ :access_key => access_key,
536
+ :code_space => code_space
537
+ })
538
+ end
539
+
450
540
  # オブジェクトの生成
451
541
  #
452
542
  # @overload initialize(names, namespace={}, locale=[])
@@ -512,8 +602,8 @@ module When
512
602
  else
513
603
  names, namespace, locale = rest
514
604
  @names = names if names
515
- @namespace ||= Parts::Locale._namespace(namespace) if namespace
516
- @locale ||= Parts::Locale._locale(locale) if locale
605
+ @namespace ||= When::Locale._namespace(namespace) if namespace
606
+ @locale ||= When::Locale._locale(locale) if locale
517
607
  end
518
608
  @namespace ||= {}
519
609
  @locale ||= []
@@ -53,7 +53,7 @@ module When
53
53
  #
54
54
  # 暦注検索結果を保存するコンテナ
55
55
  #
56
- module Notes
56
+ module NotesContainer
57
57
 
58
58
  class << self
59
59
  #
@@ -83,6 +83,7 @@ module When
83
83
  # @private
84
84
  def verify(pattern, value)
85
85
  value = value.label if !value.kind_of?(When::BasicTypes::M17n) && value.respond_to?(:label)
86
+ pattern = When::EncodingConversion.to_internal_encoding(pattern)
86
87
  pattern.kind_of?(Regexp) ? value =~ pattern : value == pattern
87
88
  end
88
89
  end
@@ -91,18 +92,18 @@ module When
91
92
  #
92
93
  # @param [Boolean] compact 余分な nil や空配列を除去するか否か
93
94
  #
94
- # @return [Notes]
95
+ # @return [NotesContainer]
95
96
  #
96
97
  def simplify(compact=true)
97
98
  if kind_of?(Hash) && !key?(:note)
98
- # Persistent Notes
99
+ # Persistent NotesContainer
99
100
  simplified = {}
100
101
  each_pair do |key, value|
101
- value = value.simplify(compact) if value.kind_of?(Notes)
102
+ value = value.simplify(compact) if value.kind_of?(NotesContainer)
102
103
  simplified[key] = value if value
103
104
  end
104
105
  else
105
- # Non-Persistent Notes
106
+ # Non-Persistent NotesContainer
106
107
  simplified = self
107
108
  simplified = _compact(simplified) if compact
108
109
  simplified = simplified[0] while simplified.kind_of?(Array) && simplified.size <= 1
@@ -121,13 +122,13 @@ module When
121
122
  #
122
123
  def value(compact=true, symbol=:value)
123
124
  if kind_of?(Hash) && !key?(:note)
124
- # Persistent Notes
125
+ # Persistent NotesContainer
125
126
  sliced = {}
126
127
  each_pair do |key, val|
127
128
  sliced[key] = val[symbol]
128
129
  end
129
130
  else
130
- # Non-Persistent Notes
131
+ # Non-Persistent NotesContainer
131
132
  return _bless(slice(symbol)) if symbol.kind_of?(Integer)
132
133
  sliced = _dig(self) {|target| target.fetch(symbol, nil)}
133
134
  end
@@ -156,16 +157,16 @@ module When
156
157
  #
157
158
  def subset(condition, compact=true)
158
159
  if kind_of?(Hash) && !key?(:note)
159
- # Persistent Notes
160
+ # Persistent NotesContainer
160
161
  result = {}
161
162
  each_pair do |key, value|
162
- value = value.subset(condition, compact) if value.kind_of?(Notes)
163
+ value = value.subset(condition, compact) if value.kind_of?(NotesContainer)
163
164
  result[key] = value if value
164
165
  end
165
166
  else
166
- # Non-Persistent Notes
167
+ # Non-Persistent NotesContainer
167
168
  result = _dig(self) {|target|
168
- (condition.each_pair {|key, pattern| break nil unless Notes.verify(pattern, target[key])}) ? target : nil
169
+ (condition.each_pair {|key, pattern| break nil unless NotesContainer.verify(pattern, target[key])}) ? target : nil
169
170
  }
170
171
  result = _compact(result) if compact
171
172
  end
@@ -175,10 +176,10 @@ module When
175
176
  private
176
177
 
177
178
  #
178
- # 対象オブジェクトを Notes にする
179
+ # 対象オブジェクトを NotesContainer にする
179
180
  #
180
181
  def _bless(target)
181
- target.extend(Notes) if target && !equal?(target)
182
+ target.extend(NotesContainer) if target && !equal?(target)
182
183
  target
183
184
  end
184
185
 
@@ -201,6 +202,11 @@ module When
201
202
  end
202
203
  end
203
204
 
205
+ #
206
+ # 暦法によってイベントの動作を変えるか否か
207
+ #
208
+ CalendarDepend = false
209
+
204
210
  # デフォルトイベント名
205
211
  #
206
212
  # @return [String]
@@ -307,13 +313,13 @@ module When
307
313
  # see {When::TM::TemporalPosition._instance}
308
314
  #
309
315
  # @note CalendarNoteオブジェクト生成時に _normalize メソッド内で @prime 変数を設定しておけば、
310
- # 本メソッドの :prime オプションで参照される。(BalineseNote#_normalize等参照)
316
+ # 本メソッドの :prime オプションで参照される。(Balinese#_normalize等参照)
311
317
  #
312
- # @note 暦注のビットアドレスは、暦注サブクラスのNoteObjects定数の中の定義順序による。
318
+ # @note 暦注のビットアドレスは、暦注サブクラスのNotes定数の中の定義順序による。
313
319
  # When::CalendarNote クラスの場合 new の引数とした暦注要素リストの定義順序による。
314
320
  # ビットアドレスの値が 1 の暦注が計算対象となる。
315
321
  #
316
- # @return [Array<Array<Hash>>] 暦注計算結果(When::CalendarNote::Notesモジュールをextendしている)
322
+ # @return [Array<Array<Hash>>] 暦注計算結果(When::CalendarNote::NotesContainerモジュールをextendしている)
317
323
  # [ :note => 暦注要素 (When::Coordinates::Residue, String, When::BasicTypes::M17n) ]
318
324
  # [ :value => 暦注の値 (When::Coordinates::Residue, String, When::BasicTypes::M17n, When::TM::TemporalPosition) ]
319
325
  #
@@ -325,23 +331,13 @@ module When
325
331
  #
326
332
  def notes(date, options={})
327
333
  dates, indices, notes, persistence, conditions, options = _parse_note(date, options)
328
- retrieved = Notes.retrieve(persistence, date.to_i)
334
+ retrieved = NotesContainer.retrieve(persistence, date.to_i)
329
335
  return retrieved unless retrieved == false
330
- Notes.register(indices.map {|i|
336
+ NotesContainer.register(indices.map {|i|
331
337
  next [] unless i <= date.precision
332
338
  _note_values(dates, notes[i-1], _all_keys[i-1], _elements[i-1]) do |dates, focused_notes, notes_hash|
333
339
  focused_notes.each do |note|
334
- unless notes_hash[note]
335
- void, event, *parameter = note.split(/^([^\d]+)/)
336
- method = event.downcase
337
- parameter << conditions unless conditions.empty?
338
- notes_hash[note] =
339
- if respond_to?(method)
340
- send(method, dates, *parameter)
341
- else
342
- _elements[i-1][note].send(When::Coordinates::PRECISION_NAME[i].downcase, dates)
343
- end
344
- end
340
+ notes_hash[note] ||= _note_element(note, i, conditions, dates)
345
341
  end
346
342
  notes_hash
347
343
  end
@@ -365,7 +361,7 @@ module When
365
361
  # [ false - 暦注が不一致 ]
366
362
  #
367
363
  def note?(date, options={})
368
- options = _find_note(options) if options.kind_of?(String)
364
+ options = _find_note(options) if options.kind_of?(String) || options.kind_of?(Regexp)
369
365
  pattern = options.delete(:value) if options.kind_of?(Hash)
370
366
  result = notes(date, options)
371
367
  result.flatten!
@@ -373,7 +369,7 @@ module When
373
369
  return false unless result.size > 0
374
370
  return true unless pattern
375
371
  result.each do |hash|
376
- return true if Notes.verify(pattern, hash[:value])
372
+ return true if NotesContainer.verify(pattern, hash[:value])
377
373
  end
378
374
  return false
379
375
  end
@@ -404,12 +400,60 @@ module When
404
400
 
405
401
  private
406
402
 
403
+ #
404
+ # 年月日暦注計算の共通処理 - コールバック元
405
+ #
406
+ def _note_values(dates, focused_notes, all_notes, note_objects)
407
+ return [] unless dates && all_notes
408
+
409
+ # prepare focused notes
410
+ case focused_notes
411
+ when Integer
412
+ bits = ~focused_notes << 1
413
+ focused_notes = all_notes.dup.delete_if { (bits>>=1)[0] == 1 }
414
+ when []
415
+ focused_notes = all_notes
416
+ when nil
417
+ focused_notes = []
418
+ end
419
+ focused_notes = focused_notes.dup
420
+ not_focused_notes = all_notes - focused_notes
421
+ notes = {}
422
+ not_focused_notes.each do |note|
423
+ notes[note] = true
424
+ end
425
+ focused_notes.each do |note|
426
+ notes[note] = nil
427
+ end
428
+
429
+ # update notes
430
+ focused_notes_actual = focused_notes.dup
431
+ notes = yield(dates, focused_notes_actual, notes)
432
+ notes.keys.each do |note|
433
+ notes.delete(note) unless focused_notes_actual.include?(note)
434
+ end
435
+
436
+ # return Array of Hash
437
+ focused_notes.map {|note|
438
+ case notes[note]
439
+ when nil, false ; {}
440
+ when Hash ; {:note=>note_objects[note].label}.merge(notes[note])
441
+ else
442
+ if note_objects[note].respond_to?(:to_note_hash)
443
+ note_objects[note].to_note_hash(notes[note], dates)
444
+ else
445
+ {:note=>note_objects[note].label, :value=>notes[note]}
446
+ end
447
+ end
448
+ }
449
+ end
450
+
407
451
  #
408
452
  # オブジェクトの正規化
409
453
  #
410
454
  def _normalize(args=[], options={})
411
- @_elements = (args.size == 0 && self.class.const_defined?(:NoteObjects)) ?
412
- When::Parts::Resource.base_uri + self.class.to_s.split(/::/)[1..-1].join('/') + '/NoteObjects' :
455
+ @_elements = (args.size == 0 && self.class.const_defined?(:Notes)) ?
456
+ When::Parts::Resource.base_uri + self.class.to_s.split(/::/)[1..-1].join('/') + '/Notes' :
413
457
  _to_iri(args, options[:prefix] || '_co:')
414
458
  if @_elements.kind_of?(Array)
415
459
  @_elements.each do |e|
@@ -418,6 +462,34 @@ module When
418
462
  end
419
463
  end
420
464
 
465
+ #
466
+ # 再帰的に配列の中を Resource化する
467
+ #
468
+ def _to_iri(args, prefix)
469
+ args.map {|arg|
470
+ case arg
471
+ when String
472
+ arg, method = $1, $2 if (arg =~ /^(.+)#([_A-Z0-9]+)$/i)
473
+ obj = When.Resource(arg, prefix)
474
+ obj = obj.copy(method) if method
475
+ obj
476
+ when Array
477
+ _to_iri(arg, prefix)
478
+ else
479
+ arg
480
+ end
481
+ }
482
+ end
483
+
484
+ #
485
+ # 暦日を当該暦注計算用クラスに変換
486
+ #
487
+ # 基底クラスである本クラスでは何もしないで、引数をそのまま返す
488
+ #
489
+ def _to_date_for_note(date)
490
+ date
491
+ end
492
+
421
493
  # 暦注要素
422
494
  #
423
495
  # @return [Array<Array<When::Parts::Resource>>]
@@ -457,8 +529,8 @@ module When
457
529
  def _parse_note(date, options)
458
530
  options =
459
531
  case options
460
- when Hash ; options
461
- when String ; {:notes => options}
532
+ when Hash ; When::EncodingConversion.to_internal_encoding(options)
533
+ when String ; {:notes => When::EncodingConversion.to_internal_encoding(options)}
462
534
  when Integer ; {:indices => options}
463
535
  else ; {}
464
536
  end
@@ -473,12 +545,27 @@ module When
473
545
  [_to_date_for_note(date), indices, notes, persistence, conditions, options]
474
546
  end
475
547
 
548
+ #
549
+ # 暦注を計算する暦座標の配列
550
+ #
551
+ # @return [Array<Integer>]
552
+ #
553
+ def _indices(indices, notes)
554
+ case indices
555
+ when nil ; (0...notes.size).to_a.reverse.map {|i| -i}
556
+ when Range ; indices.to_a
557
+ when Array ; indices
558
+ else ; [indices.to_i]
559
+ end
560
+ end
561
+
476
562
  #
477
563
  # notes メソッドの 文字列引数の意味を解釈する
478
564
  #
479
565
  # @return [Hash] options for note String
480
566
  #
481
567
  def _find_note(note)
568
+ note = When::EncodingConversion.to_internal_encoding(note)
482
569
  _elements.each_index do |index|
483
570
  return {:notes=>note, :indices => [-index]} if _elements[-1-index]._pool[note]
484
571
  end
@@ -501,88 +588,20 @@ module When
501
588
  end
502
589
 
503
590
  #
504
- # 暦注を計算する暦座標の配列
505
- #
506
- # @return [Array<Integer>]
507
- #
508
- def _indices(indices, notes)
509
- case indices
510
- when nil ; (0...notes.size).to_a.reverse.map {|i| -i}
511
- when Range ; indices.to_a
512
- when Array ; indices
513
- else ; [indices.to_i]
514
- end
515
- end
516
-
517
- #
518
- # 年月日暦注計算の共通処理 - コールバック元
519
- #
520
- def _note_values(dates, focused_notes, all_notes, note_objects)
521
- return [] unless dates && all_notes
522
-
523
- # prepare focused notes
524
- case focused_notes
525
- when Integer
526
- bits = ~focused_notes << 1
527
- focused_notes = all_notes.dup.delete_if { (bits>>=1)[0] == 1 }
528
- when []
529
- focused_notes = all_notes
530
- when nil
531
- focused_notes = []
532
- end
533
- focused_notes = focused_notes.dup
534
- not_focused_notes = all_notes - focused_notes
535
- notes = {}
536
- not_focused_notes.each do |note|
537
- notes[note] = true
538
- end
539
- focused_notes.each do |note|
540
- notes[note] = nil
541
- end
542
-
543
- # update notes
544
- notes = yield(dates, focused_notes, notes)
545
- notes.keys.each do |note|
546
- notes.delete(note) unless focused_notes.include?(note)
547
- end
548
-
549
- # return Array of Hash
550
- focused_notes.map {|note|
551
- next {} unless notes[note]
552
- if note_objects[note].respond_to?(:to_note_hash)
553
- note_objects[note].to_note_hash(notes[note], dates)
554
- else
555
- {:note=>note_objects[note].label, :value=>notes[note]}
556
- end
557
- }
558
- end
559
-
560
- #
561
- # 再帰的に配列の中を Resource化する
562
- #
563
- def _to_iri(args, prefix)
564
- args.map {|arg|
565
- case arg
566
- when String
567
- arg, method = $1, $2 if (arg =~ /^(.+)#([_A-Z0-9]+)$/i)
568
- obj = When.Resource(arg, prefix)
569
- obj = obj.copy(method) if method
570
- obj
571
- when Array
572
- _to_iri(arg, prefix)
573
- else
574
- arg
575
- end
576
- }
577
- end
578
-
579
- #
580
- # 暦日を当該暦注計算用クラスに変換
581
- #
582
- # 基底クラスである本クラスでは何もしないで、引数をそのまま返す
591
+ # 暦注の計算
583
592
  #
584
- def _to_date_for_note(date)
585
- date
593
+ # @return [Object] 暦注の値
594
+ #
595
+ def _note_element(note, index, conditions, dates)
596
+ void, event, *parameter = note.split(/^([^\d]+)/)
597
+ method = event.downcase
598
+ parameter << conditions unless conditions.empty?
599
+ return send(method, dates, *parameter) if respond_to?(method)
600
+ root = _elements[index-1][note]
601
+ parent, leaf = root.iri.split('/Notes') if root.kind_of?(When::Parts::Resource)
602
+ parent = When.Resource(parent) if leaf
603
+ return parent.send(method, dates, *parameter) if parent.respond_to?(method)
604
+ root.send(When::Coordinates::PRECISION_NAME[index].downcase, dates)
586
605
  end
587
606
 
588
607
  #
@@ -650,5 +669,133 @@ module When
650
669
  super(@parent, date, direction, options)
651
670
  end
652
671
  end
672
+
673
+ #
674
+ # 暦週
675
+ #
676
+ class Week < CalendarNote
677
+
678
+ #
679
+ # 暦週要素
680
+ #
681
+ class DayOfWeek < When::BasicTypes::M17n
682
+
683
+ # 当該暦週要素の標準的な出現間隔
684
+ #
685
+ # @return [Integer]
686
+ #
687
+ attr_reader :delta
688
+
689
+ # 所属する暦週オブジェクト
690
+ #
691
+ # @return [When::CalendarNote]
692
+ #
693
+ def week_note
694
+ @week_note ||= When.CalendarNote(iri.split('/Notes').first)
695
+ end
696
+
697
+ # 当日または直前に当該暦週要素が現れる日付
698
+ #
699
+ # @return [When::TM::TemporalPosition]
700
+ #
701
+ def just_or_last(date)
702
+ date = week_note._to_date_for_note(date)
703
+ ([parent.child.length, @delta[When::DAY]].max*2).times do
704
+ if equal?(week_note.week(date))
705
+ date.events ||= []
706
+ date.events << self
707
+ return date
708
+ end
709
+ date -= When::P1D
710
+ end
711
+ raise ArgumentError, "#{self} not found"
712
+ end
713
+
714
+ private
715
+
716
+ #
717
+ # オブジェクトの正規化
718
+ #
719
+ def initialize(*args)
720
+ super
721
+ @delta = When::P1D * @delta.to_i if @delta && ! @delta.kind_of?(When::TM::Duration)
722
+ end
723
+ end
724
+
725
+ #
726
+ # 曜日の名前の一覧
727
+ #
728
+ # @param [When::TM::TemporalPosition] date
729
+ #
730
+ # @return [Array<When::CalendarNote::Week::DayOfWeek>]
731
+ #
732
+ def week_labels(date)
733
+ @days_of_week.child[0...week(date)[:position].last]
734
+ end
735
+
736
+ # 七曜
737
+ #
738
+ # @param [When::TM::TemporalPosition] date
739
+ #
740
+ # @return [When::Coordinates::Residue] 七曜
741
+ #
742
+ def standard_week(date)
743
+ When.Residue('Week')[date.to_i % 7]
744
+ end
745
+
746
+ #
747
+ # オブジェクトの正規化
748
+ #
749
+ def _normalize(args=[], options={})
750
+ super
751
+ @days_of_week = When.CalendarNote("#{self.class.to_s.split('::').last}/Notes::day::Week")
752
+ @days_of_week.child.length.times do |index|
753
+ name = @days_of_week.child[index].label.to_s.downcase.gsub(/[- ]/, '_')
754
+ self.class.module_eval %Q{
755
+ def #{name}(date, parameter=nil)
756
+ @days_of_week.child[#{index}].just_or_last(date)
757
+ end
758
+ } unless respond_to?(name)
759
+ self.class.module_eval %Q{
760
+ def #{name}_delta(parameter=nil)
761
+ @days_of_week.child[#{index}].delta
762
+ end
763
+ } unless respond_to?(name + '_delta')
764
+ end
765
+ end
766
+
767
+ #
768
+ # イベントを取得する Enumerator
769
+ #
770
+ class Enumerator < When::CalendarNote::Enumerator
771
+
772
+ #
773
+ # 次のイベントを得る
774
+ #
775
+ # @return [When::TM::TemporalPosition]
776
+ #
777
+ def succ
778
+ value = @current
779
+ plus = @delta.sign > 0
780
+ if @current==:first
781
+ @first = event_eval(@first) unless plus
782
+ @current = @first
783
+ else
784
+ if plus
785
+ @current = event_eval(@current + @delta)
786
+ else
787
+ @last = event_eval(@current - When::P1D)
788
+ @current = event_eval(@current + @delta)
789
+ unless [@current.to_i, value.to_i].include?(@last.to_i)
790
+ @current = @last
791
+ return value
792
+ end
793
+ end
794
+ @current = event_eval(@current + @delta * 2) if @current.to_i == value.to_i
795
+ end
796
+ return value
797
+ end
798
+ end
799
+ end
653
800
  end
654
801
  end