when_exe 0.2.100 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE.ja.txt +25 -25
- data/LICENSE.txt +31 -31
- data/bin/irb.rc +5 -0
- data/bin/locales.rb +2 -2
- data/bin/when.rb +16 -0
- data/bin/when.rb.config +7 -0
- data/lib/when_exe.rb +616 -14
- data/lib/when_exe/basictypes.rb +615 -0
- data/lib/when_exe/calendartypes.rb +1700 -0
- data/lib/when_exe/coordinates.rb +1936 -0
- data/lib/when_exe/core/compatibility.rb +54 -0
- data/lib/when_exe/core/duration.rb +72 -72
- data/lib/when_exe/core/extension.rb +382 -0
- data/lib/when_exe/ephemeris.rb +1845 -0
- data/lib/when_exe/googlecalendar.rb +140 -0
- data/lib/when_exe/icalendar.rb +1587 -0
- data/lib/when_exe/inspect.rb +1237 -0
- data/lib/when_exe/locales/af.rb +90 -0
- data/lib/when_exe/locales/ar.rb +145 -0
- data/lib/when_exe/locales/az.rb +90 -0
- data/lib/when_exe/locales/bg.rb +90 -0
- data/lib/when_exe/locales/bn.rb +94 -0
- data/lib/when_exe/locales/bs.rb +121 -0
- data/lib/when_exe/locales/ca.rb +92 -0
- data/lib/when_exe/locales/cs.rb +107 -0
- data/lib/when_exe/locales/cy.rb +150 -0
- data/lib/when_exe/locales/da.rb +84 -0
- data/lib/when_exe/locales/de.rb +92 -0
- data/lib/when_exe/locales/de_AT.rb +92 -0
- data/lib/when_exe/locales/de_CH.rb +92 -0
- data/lib/when_exe/locales/el.rb +93 -0
- data/lib/when_exe/locales/en.rb +88 -0
- data/lib/when_exe/locales/en_AU.rb +88 -0
- data/lib/when_exe/locales/en_CA.rb +88 -0
- data/lib/when_exe/locales/en_GB.rb +88 -0
- data/lib/when_exe/locales/en_IN.rb +88 -0
- data/lib/when_exe/locales/en_NZ.rb +88 -0
- data/lib/when_exe/locales/eo.rb +89 -0
- data/lib/when_exe/locales/es.rb +84 -0
- data/lib/when_exe/locales/es_419.rb +84 -0
- data/lib/when_exe/locales/es_AR.rb +84 -0
- data/lib/when_exe/locales/es_CL.rb +84 -0
- data/lib/when_exe/locales/es_CO.rb +84 -0
- data/lib/when_exe/locales/es_MX.rb +84 -0
- data/lib/when_exe/locales/es_PE.rb +85 -0
- data/lib/when_exe/locales/es_VE.rb +84 -0
- data/lib/when_exe/locales/et.rb +94 -0
- data/lib/when_exe/locales/eu.rb +95 -0
- data/lib/when_exe/locales/fa.rb +80 -0
- data/lib/when_exe/locales/fi.rb +89 -0
- data/lib/when_exe/locales/fr.rb +88 -0
- data/lib/when_exe/locales/fr_CA.rb +88 -0
- data/lib/when_exe/locales/fr_CH.rb +88 -0
- data/lib/when_exe/locales/gl.rb +81 -0
- data/lib/when_exe/locales/he.rb +84 -0
- data/lib/when_exe/locales/hi.rb +80 -0
- data/lib/when_exe/locales/hi_IN.rb +84 -0
- data/lib/when_exe/locales/hr.rb +128 -0
- data/lib/when_exe/locales/hu.rb +84 -0
- data/lib/when_exe/locales/id.rb +89 -0
- data/lib/when_exe/locales/is.rb +89 -0
- data/lib/when_exe/locales/it.rb +87 -0
- data/lib/when_exe/locales/it_CH.rb +87 -0
- data/lib/when_exe/locales/ja.rb +78 -0
- data/lib/when_exe/locales/kn.rb +86 -0
- data/lib/when_exe/locales/ko.rb +78 -0
- data/lib/when_exe/locales/links.rb +2342 -0
- data/lib/when_exe/locales/lo.rb +123 -0
- data/lib/when_exe/locales/locales.rb +91 -0
- data/lib/when_exe/locales/lt.rb +111 -0
- data/lib/when_exe/locales/lv.rb +118 -0
- data/lib/when_exe/locales/mk.rb +93 -0
- data/lib/when_exe/locales/mn.rb +80 -0
- data/lib/when_exe/locales/nb.rb +81 -0
- data/lib/when_exe/locales/ne.rb +81 -0
- data/lib/when_exe/locales/nl.rb +92 -0
- data/lib/when_exe/locales/nn.rb +73 -0
- data/lib/when_exe/locales/or.rb +84 -0
- data/lib/when_exe/locales/pl.rb +128 -0
- data/lib/when_exe/locales/pt.rb +88 -0
- data/lib/when_exe/locales/pt_BR.rb +88 -0
- data/lib/when_exe/locales/rm.rb +143 -0
- data/lib/when_exe/locales/ro.rb +105 -0
- data/lib/when_exe/locales/ru.rb +128 -0
- data/lib/when_exe/locales/sk.rb +109 -0
- data/lib/when_exe/locales/sl.rb +122 -0
- data/lib/when_exe/locales/sr.rb +122 -0
- data/lib/when_exe/locales/sv.rb +83 -0
- data/lib/when_exe/locales/sw.rb +89 -0
- data/lib/when_exe/locales/th.rb +78 -0
- data/lib/when_exe/locales/tl.rb +99 -0
- data/lib/when_exe/locales/tr.rb +96 -0
- data/lib/when_exe/locales/uk.rb +128 -0
- data/lib/when_exe/locales/uz.rb +128 -0
- data/lib/when_exe/locales/vi.rb +94 -0
- data/lib/when_exe/locales/wo.rb +82 -0
- data/lib/when_exe/locales/zh_CN.rb +77 -0
- data/lib/when_exe/locales/zh_HK.rb +77 -0
- data/lib/when_exe/locales/zh_TW.rb +77 -0
- data/lib/when_exe/mini_application.rb +252 -0
- data/lib/when_exe/parts/enumerator.rb +472 -0
- data/lib/when_exe/parts/geometric_complex.rb +379 -0
- data/lib/when_exe/parts/locale.rb +513 -0
- data/lib/when_exe/parts/method_cash.rb +207 -0
- data/lib/when_exe/parts/resource.rb +806 -0
- data/lib/when_exe/parts/timezone.rb +182 -0
- data/lib/when_exe/region/bahai.rb +145 -0
- data/lib/when_exe/region/balinese.rb +627 -0
- data/lib/when_exe/region/chinese.rb +896 -0
- data/lib/when_exe/region/chinese_calendar.rb +919 -0
- data/lib/when_exe/region/chinese_epoch.rb +1245 -0
- data/lib/when_exe/region/christian.rb +644 -0
- data/lib/when_exe/region/far_east.rb +192 -0
- data/lib/when_exe/region/french.rb +66 -0
- data/lib/when_exe/region/geologicalage.rb +639 -0
- data/lib/when_exe/region/indian.rb +1066 -0
- data/lib/when_exe/region/iranian.rb +66 -0
- data/lib/when_exe/region/islamic.rb +105 -0
- data/lib/when_exe/region/japanese.rb +851 -0
- data/lib/when_exe/region/japanese_notes.rb +964 -0
- data/lib/when_exe/region/japanese_residues.rb +1149 -0
- data/lib/when_exe/region/javanese.rb +228 -0
- data/lib/when_exe/region/jewish.rb +127 -0
- data/lib/when_exe/region/korean.rb +267 -0
- data/lib/when_exe/region/m17n.rb +115 -0
- data/lib/when_exe/region/martian.rb +215 -0
- data/lib/when_exe/region/mayan.rb +122 -0
- data/lib/when_exe/region/moon.rb +333 -0
- data/lib/when_exe/region/nihon_shoki.rb +73 -0
- data/lib/when_exe/region/planets.rb +585 -0
- data/lib/when_exe/region/pope.rb +298 -0
- data/lib/when_exe/region/residue.rb +229 -0
- data/lib/when_exe/region/roman.rb +325 -0
- data/lib/when_exe/region/ryukyu.rb +98 -0
- data/lib/when_exe/region/shire.rb +254 -0
- data/lib/when_exe/region/sun.rb +210 -0
- data/lib/when_exe/region/thai.rb +227 -0
- data/lib/when_exe/region/tibetan.rb +233 -0
- data/lib/when_exe/region/v50.rb +111 -0
- data/lib/when_exe/region/vietnamese.rb +173 -0
- data/lib/when_exe/region/world.rb +197 -0
- data/lib/when_exe/timestandard.rb +547 -0
- data/lib/when_exe/tmduration.rb +330 -330
- data/lib/when_exe/tmobjects.rb +1295 -0
- data/lib/when_exe/tmposition.rb +1955 -0
- data/lib/when_exe/tmreference.rb +1547 -0
- data/lib/when_exe/version.rb +10 -3
- data/link_to_online_documents +4 -0
- data/test/examples/JapanHolidays.ics +456 -0
- data/test/examples/Millennium.ics +17 -0
- data/test/examples/NewYork.ics +61 -0
- data/test/examples/Residue.m17n +135 -0
- data/test/examples/Spatial.m17n +179 -0
- data/test/examples/Terms.m17n +39 -0
- data/test/examples/Test.ics +53 -0
- data/test/examples/USA-DST.ics +61 -0
- data/test/examples/geometric_complex.rb +41 -0
- data/test/examples/sample.xml +14 -0
- data/test/examples/today.rb +61 -0
- data/test/test.rb +54 -19
- data/test/test.rb.config +1 -0
- data/test/test/basictypes.rb +368 -0
- data/test/test/calendartypes.rb +57 -0
- data/test/test/coordinates.rb +380 -0
- data/test/test/ephemeris.rb +127 -0
- data/test/test/googlecalendar.rb +167 -0
- data/test/test/icalendar.rb +848 -0
- data/test/test/inspect.rb +115 -0
- data/test/test/parts.rb +480 -0
- data/test/test/region/chinese.rb +161 -0
- data/test/test/region/french.rb +33 -0
- data/test/test/region/geologicalage.rb +14 -0
- data/test/test/region/indian.rb +55 -0
- data/test/test/region/iran.rb +54 -0
- data/test/test/region/islamic.rb +18 -0
- data/test/test/region/japanese.rb +62 -0
- data/test/test/region/jewish.rb +61 -0
- data/test/test/region/m17n.rb +181 -0
- data/test/test/region/mayan.rb +78 -0
- data/test/test/region/moon.rb +14 -0
- data/test/test/region/planets.rb +14 -0
- data/test/test/region/residue.rb +123 -0
- data/test/test/region/sun.rb +14 -0
- data/test/test/region/thai.rb +94 -0
- data/test/test/region/tibetan.rb +30 -0
- data/test/test/tmobjects.rb +356 -57
- data/test/test/tmposition.rb +237 -0
- data/test/test/tmreference.rb +95 -0
- data/when_exe.gemspec +2 -2
- metadata +187 -7
- data/doc/COPYING +0 -31
- data/doc/COPYING.ja +0 -25
- data/doc/document_url +0 -1
@@ -0,0 +1,379 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
=begin
|
3
|
+
Copyright (C) 2011-2013 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
|
+
#
|
9
|
+
# 本ライブラリのための諸々の部品
|
10
|
+
#
|
11
|
+
module When::Parts
|
12
|
+
|
13
|
+
#
|
14
|
+
# 任意個の端点から構成する [Range] の subclass
|
15
|
+
#
|
16
|
+
class GeometricComplex < Range
|
17
|
+
|
18
|
+
include Comparable
|
19
|
+
|
20
|
+
# 範囲の反転
|
21
|
+
# @return [Boolean]
|
22
|
+
# [ true - 反転する ]
|
23
|
+
# [ false - 反転しない ]
|
24
|
+
#
|
25
|
+
# @note
|
26
|
+
# 無限の過去(-Infinity)を範囲に含むか否かと同値である
|
27
|
+
#
|
28
|
+
attr_reader :reverse
|
29
|
+
|
30
|
+
#
|
31
|
+
# When::Parts::GeometricComplex を構成する端点の Array
|
32
|
+
#
|
33
|
+
# @return [Array<Array<Comparable, Boolean>>]
|
34
|
+
# - Comparable - 端点
|
35
|
+
# - Boolean
|
36
|
+
# @reverse == true の場合
|
37
|
+
# true - 範囲に含まない
|
38
|
+
# false - 範囲に含む
|
39
|
+
# @reverse == false の場合
|
40
|
+
# true - 範囲に含む
|
41
|
+
# false - 範囲に含まない
|
42
|
+
#
|
43
|
+
# @example +[[3,true],[4,false]] は Range(3+...4)に対応する
|
44
|
+
#
|
45
|
+
attr_reader :node
|
46
|
+
|
47
|
+
# 最小の端点
|
48
|
+
#
|
49
|
+
# @param [Comparable] default 端点が-∞の場合に返すべき値(指定がなければ nil)
|
50
|
+
#
|
51
|
+
# @return [Comparable] 最小の端点
|
52
|
+
#
|
53
|
+
# @note
|
54
|
+
# 含むか否かに関わらず、最小の端点を返す。
|
55
|
+
# default が指定されているが有効な区間がない場合、nil を返す。
|
56
|
+
#
|
57
|
+
def first(default=nil)
|
58
|
+
return (@node.length==0) ? nil : @node[0][0] unless default # 互換性
|
59
|
+
if reverse
|
60
|
+
return default
|
61
|
+
else
|
62
|
+
(@node.length==0) ? nil : @node[0][0]
|
63
|
+
end
|
64
|
+
end
|
65
|
+
alias :begin :first
|
66
|
+
|
67
|
+
# 最大の端点
|
68
|
+
#
|
69
|
+
# @param [Comparable] default 端点が+∞場合に返すべき値(指定がなければ nil)
|
70
|
+
#
|
71
|
+
# @return [Comparable] 最大の端点
|
72
|
+
#
|
73
|
+
# @note
|
74
|
+
# 含むか否かに関わらず、最大の端点を返す
|
75
|
+
# default が指定されているが有効な区間がない場合、nil を返す
|
76
|
+
#
|
77
|
+
def last(default=nil)
|
78
|
+
return (@node.length==0) ? nil : @node[-1][0] unless default # 互換性
|
79
|
+
if reverse
|
80
|
+
return (@node.length[0]==0) ? default : @node[-1][0]
|
81
|
+
else
|
82
|
+
return nil if (@node.length==0)
|
83
|
+
return (@node.length[0]==1) ? default : @node[-1][0]
|
84
|
+
end
|
85
|
+
end
|
86
|
+
alias :end :last
|
87
|
+
|
88
|
+
# 端点が範囲に含まれるか?
|
89
|
+
#
|
90
|
+
# @param [Integer] index 端点の番号(デフォルト : -1 - 最大の端点)
|
91
|
+
#
|
92
|
+
# @return [Boolean]
|
93
|
+
# [ true - 含まれる ]
|
94
|
+
# [ false - 含まれない ]
|
95
|
+
#
|
96
|
+
def exclude_end?(index=-1)
|
97
|
+
(@node.length==0) ? nil : !@node[index][1] ^ @reverse
|
98
|
+
end
|
99
|
+
|
100
|
+
# 分解能
|
101
|
+
#
|
102
|
+
# @return [Integer] 最小の端点の分解能を返す
|
103
|
+
#
|
104
|
+
# @note
|
105
|
+
# 分解能がない場合は、When::SYSTEM を返す
|
106
|
+
#
|
107
|
+
def precision
|
108
|
+
@node[0] && @node[0][0].respond_to?(:precision) ? @node[0][0].precision : Coordinates::SYSTEM
|
109
|
+
end
|
110
|
+
|
111
|
+
# 範囲を反転する
|
112
|
+
#
|
113
|
+
# @return [When::Parts::GeometricComplex]
|
114
|
+
#
|
115
|
+
def -@
|
116
|
+
GeometricComplex.new(self, true)
|
117
|
+
end
|
118
|
+
|
119
|
+
# 最小の端点と other を比較する
|
120
|
+
#
|
121
|
+
# @param [Comparable] other 比較対象
|
122
|
+
#
|
123
|
+
# @return [Integer] 比較結果を 負, 0, 正の値で返す
|
124
|
+
#
|
125
|
+
def <=>(other)
|
126
|
+
first <=> other
|
127
|
+
end
|
128
|
+
|
129
|
+
# 和集合
|
130
|
+
#
|
131
|
+
# @param [Range, When::Parts::GeometricComplex] other
|
132
|
+
#
|
133
|
+
# @return [When::Parts::GeometricComplex] self と other の和集合を返す
|
134
|
+
#
|
135
|
+
def |(other)
|
136
|
+
other = GeometricComplex.new(other) unless other.kind_of?(GeometricComplex)
|
137
|
+
return self if self.reverse && self.node.length==0
|
138
|
+
return other | self if !self.reverse && other.reverse
|
139
|
+
copy = self.node.dup
|
140
|
+
ref = other.node.dup
|
141
|
+
max = _max(copy.shift.dup, ref.shift.dup) if (other.reverse)
|
142
|
+
rev = max ? false : @reverse
|
143
|
+
while (ref.length > 0) do
|
144
|
+
first, last, *ref = ref
|
145
|
+
updated = _upper(copy, first, rev)
|
146
|
+
updated += _lower(copy, last, rev) if last
|
147
|
+
copy = updated
|
148
|
+
end
|
149
|
+
copy = _lower(copy, max, true) if max
|
150
|
+
return GeometricComplex.new(copy, self.reverse)
|
151
|
+
end
|
152
|
+
|
153
|
+
# ISO19108 の TM オブジェクトに変換する
|
154
|
+
#
|
155
|
+
# @param [Hash] options When::TM::TemporalPosition の生成を行う場合に使用する
|
156
|
+
# (see {When::TM::TemporalPosition._instance})
|
157
|
+
#
|
158
|
+
# @return [When::TM::Node, When::TM::Edge, When::TM::TopologicalComplex]
|
159
|
+
#
|
160
|
+
def to_tm_object(options={})
|
161
|
+
return nil unless !@reverse && @node.length>0 && @node.length[0]==0
|
162
|
+
objects = []
|
163
|
+
primitives = @node.dup
|
164
|
+
while (primitives) do
|
165
|
+
first, last, primitives = primitives
|
166
|
+
if (first[0].eql?(last[0]))
|
167
|
+
objects = When::TM::Node.new(When::TM::Instant.new(When.when?(first[0],options)))
|
168
|
+
else
|
169
|
+
objects = When::TM::Edge.new(When::TM::Node.new(When::TM::Instant.new(When.when?(first[0],options))),
|
170
|
+
When::TM::Node.new(When::TM::Instant.new(When.when?(last[0],options))))
|
171
|
+
end
|
172
|
+
end
|
173
|
+
return objects[0] if objects.length==1
|
174
|
+
return When::TM::TopologicalComplex.new(objects)
|
175
|
+
end
|
176
|
+
|
177
|
+
# 範囲に含まれるか?
|
178
|
+
#
|
179
|
+
# @param [Comparable] other 判断する Comparable
|
180
|
+
#
|
181
|
+
# @return [Boolean]
|
182
|
+
# [ true - 範囲に含まれる ]
|
183
|
+
# [ false - 範囲に含まれない ]
|
184
|
+
#
|
185
|
+
# @note 制限事項
|
186
|
+
# When::TM::TopologicalComplex どうしの包含判定は、和集合がもとの範囲と等しいか
|
187
|
+
# で判断している。分解能が When::SYSTEM でない場合、論理的には等しいものが、
|
188
|
+
# 内部表現が異なるために等しくないとみなされる事があり、その場合 true であるべき
|
189
|
+
# ものを false と誤判断する。実行速度上の制約もあり、現時点では対策しない。
|
190
|
+
#
|
191
|
+
def include?(other)
|
192
|
+
if (other.kind_of?(Comparable) && !other.kind_of?(GeometricComplex))
|
193
|
+
return (_include_point?(other) != false)
|
194
|
+
else
|
195
|
+
other = GeometricComplex.new(other) unless other.kind_of?(GeometricComplex)
|
196
|
+
return _include_range?(other)
|
197
|
+
end
|
198
|
+
end
|
199
|
+
alias :=== :include?
|
200
|
+
|
201
|
+
# Enumerator._exclude 専用
|
202
|
+
# @private
|
203
|
+
def _include?(other)
|
204
|
+
if (other.kind_of?(Comparable) && !other.kind_of?(GeometricComplex))
|
205
|
+
return _include_point?(other)
|
206
|
+
else
|
207
|
+
other = GeometricComplex.new(other) unless other.kind_of?(GeometricComplex)
|
208
|
+
return _include_range?(other) && _include_point?(other.first)
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
# オブジェクトの生成
|
213
|
+
#
|
214
|
+
# @overload initialize(range, reverse=false)
|
215
|
+
# @param [Range] range
|
216
|
+
#
|
217
|
+
# @overload initialize(point, reverse=false)
|
218
|
+
# range = Range(point..point) と同じ
|
219
|
+
# @param [Comparable] point
|
220
|
+
#
|
221
|
+
# @overload initialize(first, last, reverse=false)
|
222
|
+
# range = Range(first...last) と同じ
|
223
|
+
# @param [Comparable] first
|
224
|
+
# @param [Comparable] last
|
225
|
+
#
|
226
|
+
# @overload initialize(first, duration, reverse=false)
|
227
|
+
# range = Range(first...(first+duration)) と同じ
|
228
|
+
# @param [Comparable] first
|
229
|
+
# @param [When::TM::Duration] duration
|
230
|
+
#
|
231
|
+
# @overload initialize(other, reverse=false)
|
232
|
+
# もとの When::Parts::GeometricComplex のコピー
|
233
|
+
# @param [When::Parts::GeometricComplex] other
|
234
|
+
#
|
235
|
+
# @overload initialize(node, reverse=false)
|
236
|
+
# 指定した node 構造の When::Parts::GeometricComplex を生成
|
237
|
+
# @param [Array<Array<Comparable, Boolean>>] note
|
238
|
+
# - Comparable - 端点
|
239
|
+
# - Boolean
|
240
|
+
# @reverse == true の場合
|
241
|
+
# true - 範囲に含まない
|
242
|
+
# false - 範囲に含む
|
243
|
+
# @reverse == false の場合
|
244
|
+
# true - 範囲に含む
|
245
|
+
# false - 範囲に含まない
|
246
|
+
# @note
|
247
|
+
# すべての呼び出しパターンに共通の最終引数 reverse を付けることができる
|
248
|
+
# reverse [Boolean]
|
249
|
+
# true - 反転する
|
250
|
+
# false - 反転しない
|
251
|
+
#
|
252
|
+
def initialize(*args)
|
253
|
+
|
254
|
+
@reverse = (args[-1]==true || args[-1]==false) ? args.pop : false
|
255
|
+
|
256
|
+
case args[0]
|
257
|
+
when GeometricComplex
|
258
|
+
@node = args[0].node
|
259
|
+
@reverse ^= args[0].reverse
|
260
|
+
super(self.first, self.last, exclude_end?) if self.first && self.last
|
261
|
+
return
|
262
|
+
|
263
|
+
when Array
|
264
|
+
@node = args[0]
|
265
|
+
super(self.first, self.last, exclude_end?) if self.first && self.last
|
266
|
+
return
|
267
|
+
|
268
|
+
when Range
|
269
|
+
first = [args[0].first, true]
|
270
|
+
last = [args[0].last, !args[0].exclude_end?]
|
271
|
+
|
272
|
+
when Comparable
|
273
|
+
first, last, rest = args
|
274
|
+
raise ArgumentError, "Too many argument: #{rest}" if rest
|
275
|
+
first = [first, true]
|
276
|
+
case last
|
277
|
+
when Comparable ; last = [last, false]
|
278
|
+
when When::TM::Duration ; last = [first[0] + last, false]
|
279
|
+
when nil ; last = first
|
280
|
+
else ; raise TypeError, "Irregal GeometricComplex Type for last element: #{last.class}"
|
281
|
+
end
|
282
|
+
|
283
|
+
when nil ;
|
284
|
+
else ; raise TypeError, "Irregal GeometricComplex Type: #{first.class}"
|
285
|
+
end
|
286
|
+
|
287
|
+
first, last = last, first if (first && last && first[0] > last[0])
|
288
|
+
@node = []
|
289
|
+
@node << first if first
|
290
|
+
@node << last if last
|
291
|
+
super(self.first, self.last, exclude_end?) if first && last
|
292
|
+
end
|
293
|
+
|
294
|
+
private
|
295
|
+
|
296
|
+
def _include_range?(other)
|
297
|
+
union = self | other
|
298
|
+
return false unless self.node == union.node
|
299
|
+
return self.reverse == union.reverse
|
300
|
+
end
|
301
|
+
|
302
|
+
def _include_point?(other)
|
303
|
+
@node.each_index do |i|
|
304
|
+
current = @node[i]
|
305
|
+
verify = other <=> current[0]
|
306
|
+
if (verify < 0)
|
307
|
+
return false if ((i[0]==0) ^ @reverse)
|
308
|
+
return @node[[0,i-1].max][0]
|
309
|
+
elsif (verify == 0)
|
310
|
+
return false unless (@reverse ^ current[1])
|
311
|
+
return current[0]
|
312
|
+
end
|
313
|
+
end
|
314
|
+
return (@reverse ? nil : false) if @node.length==0
|
315
|
+
return false if ((@node.length[0]==0) ^ @reverse)
|
316
|
+
return @node[-1][0]
|
317
|
+
end
|
318
|
+
|
319
|
+
def _upper(node, point, reverse)
|
320
|
+
node = node.dup
|
321
|
+
point = point.dup
|
322
|
+
point[1] = !point[1] if reverse
|
323
|
+
node.each_index do |i|
|
324
|
+
if (_verify(point, node[i], reverse) <= 0)
|
325
|
+
node[i..-1] = ((i[0]==0) ^ reverse) ? [point] : []
|
326
|
+
return node
|
327
|
+
end
|
328
|
+
end
|
329
|
+
node.push(point) if (node.length[0]==0) ^ @everse
|
330
|
+
return node
|
331
|
+
end
|
332
|
+
|
333
|
+
def _lower(node, point, reverse)
|
334
|
+
node = node.dup
|
335
|
+
point = point.dup
|
336
|
+
point[1] = !point[1] if reverse
|
337
|
+
(node.length-1).downto(0) do |i|
|
338
|
+
if (_verify(point, node[i], reverse) >= 0)
|
339
|
+
node[0..i] = ((i[0]==1) ^ reverse) ? [point] : []
|
340
|
+
return node
|
341
|
+
end
|
342
|
+
end
|
343
|
+
node.unshift(point) if (node.length[0]==0) ^ reverse
|
344
|
+
return node
|
345
|
+
end
|
346
|
+
|
347
|
+
def _verify(point, node, reverse)
|
348
|
+
verify = point[0] <=> node[0]
|
349
|
+
return verify unless verify == 0
|
350
|
+
if point[0].respond_to?(:precision) && node[0].respond_to?(:precision)
|
351
|
+
point[0] = node[0] if point[0].precision >= node[0].precision
|
352
|
+
end
|
353
|
+
if reverse
|
354
|
+
point[1] &= node[1]
|
355
|
+
else
|
356
|
+
point[1] |= node[1]
|
357
|
+
end
|
358
|
+
return verify
|
359
|
+
end
|
360
|
+
|
361
|
+
def _max(p1, p2)
|
362
|
+
p1[1] = !p1[1]
|
363
|
+
p2[1] = !p2[1]
|
364
|
+
verify = p1[0] <=> p2[0]
|
365
|
+
return p1 if (verify>0)
|
366
|
+
return p2 if (verify<0)
|
367
|
+
p1[1] |= p2[1]
|
368
|
+
return p1
|
369
|
+
end
|
370
|
+
|
371
|
+
# その他のメソッド
|
372
|
+
# When::Parts::GeometricComplex で定義されていないメソッドは
|
373
|
+
# 処理を first (type: When::TM::(Temporal)Position) に委譲する
|
374
|
+
#
|
375
|
+
def method_missing(name, *args, &block)
|
376
|
+
first.send(name.to_sym, *args, &block)
|
377
|
+
end
|
378
|
+
end
|
379
|
+
end
|
@@ -0,0 +1,513 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
=begin
|
3
|
+
Copyright (C) 2011-2012 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
|
+
#
|
9
|
+
# 本ライブラリのための諸々の部品
|
10
|
+
#
|
11
|
+
module When::Parts
|
12
|
+
|
13
|
+
#
|
14
|
+
# Multilingualization(M17n) 対応モジュール
|
15
|
+
#
|
16
|
+
# When::BasicTypes::M17n の実装のうち When::BasicTypes 内部で
|
17
|
+
# 定義すべきでない部分を切り出してモジュールとしている
|
18
|
+
#
|
19
|
+
module Locale
|
20
|
+
|
21
|
+
# Locale 読み替えの初期設定
|
22
|
+
Alias = {'alias'=>'ja', '日本語'=>'ja', '英語'=>'en'}
|
23
|
+
|
24
|
+
# 漢字の包摂
|
25
|
+
DefaultUnification = {
|
26
|
+
'煕' => '熙',
|
27
|
+
'廣' => '広',
|
28
|
+
'寶' => '宝',
|
29
|
+
'國' => '国',
|
30
|
+
'應' => '応',
|
31
|
+
'觀' => '観',
|
32
|
+
'龜' => '亀',
|
33
|
+
'齊' => '斉',
|
34
|
+
'靈' => '霊',
|
35
|
+
'攝' => '摂',
|
36
|
+
'壽' => '寿',
|
37
|
+
'萬' => '万',
|
38
|
+
'廢' => '廃',
|
39
|
+
'顯' => '顕',
|
40
|
+
'會' => '会',
|
41
|
+
'聰' => '聡',
|
42
|
+
'總' => '総',
|
43
|
+
'證' => '証',
|
44
|
+
'禮' => '礼',
|
45
|
+
'竜' => '龍',
|
46
|
+
}
|
47
|
+
|
48
|
+
# @private
|
49
|
+
Escape = '__!_ESCAPE_%2C_!__'
|
50
|
+
|
51
|
+
class << self
|
52
|
+
|
53
|
+
# When::Parts::Locale Module のグローバルな設定を行う
|
54
|
+
#
|
55
|
+
# @param [Hash] aliases
|
56
|
+
# Locale の読み替えパターンを Hash で指定する。
|
57
|
+
# aliases の指定がない場合、aliases は Alias(モジュール定数)と解釈する。
|
58
|
+
#
|
59
|
+
def _setup_(aliases=nil)
|
60
|
+
@aliases = aliases || Alias
|
61
|
+
end
|
62
|
+
|
63
|
+
# 特定 locale に対応した文字列の取得
|
64
|
+
#
|
65
|
+
# @param [String] source もとにする String または M17n
|
66
|
+
#
|
67
|
+
# @param[String] loc locale の指定 ( lang[-|_]country.encode )
|
68
|
+
# [ lang - 言語 ]
|
69
|
+
# [ country - 国(省略可) ]
|
70
|
+
# [ encode - 文字コード(省略可) ]
|
71
|
+
#
|
72
|
+
# @return [String] loc に対応した文字列
|
73
|
+
#
|
74
|
+
# @note source が Hash や Array の場合、その構成要素を変換して返す
|
75
|
+
#
|
76
|
+
def translate(source, loc='')
|
77
|
+
return source unless loc
|
78
|
+
case source
|
79
|
+
when Hash
|
80
|
+
result = {}
|
81
|
+
source.each_pair do |key, value|
|
82
|
+
result[translate(key, loc)] = translate(value, loc)
|
83
|
+
end
|
84
|
+
return result
|
85
|
+
when Array
|
86
|
+
return source.map {|value| translate(value, loc)}
|
87
|
+
when Locale
|
88
|
+
return source.translate(loc)
|
89
|
+
when String
|
90
|
+
return source.encode($1) if loc =~ /\.(.+)$/
|
91
|
+
end
|
92
|
+
source
|
93
|
+
end
|
94
|
+
|
95
|
+
# 包摂リストに登録されている文字を包摂する
|
96
|
+
#
|
97
|
+
# @param [When::Parts::Locale] source 文字を包摂しようとする国際化文字列
|
98
|
+
# @param [String] source 文字を包摂しようとする文字列
|
99
|
+
# @param [Regexp] source 文字を包摂しようとする正規表現
|
100
|
+
# @param [Hash] pattern 包摂ルール
|
101
|
+
#
|
102
|
+
# @return [When::Parts::Locale] 文字を包摂した国際化文字列
|
103
|
+
# @return [String] 文字を包摂した文字列
|
104
|
+
# @return [Regexp] 文字を包摂した正規表現
|
105
|
+
#
|
106
|
+
def ideographic_unification(source, pattern=DefaultUnification)
|
107
|
+
case source
|
108
|
+
when When::Parts::Locale
|
109
|
+
source.ideographic_unification(pattern)
|
110
|
+
when Regexp
|
111
|
+
Regexp.compile(ideographic_unification(source.source.encode('UTF-8'), pattern), source.options)
|
112
|
+
when String
|
113
|
+
source.gsub(/./) do |c|
|
114
|
+
pattern[c] ? pattern[c] : c
|
115
|
+
end
|
116
|
+
else
|
117
|
+
source
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
# 文字列で表現された namespace 指定を Hash に変換する
|
122
|
+
# @private
|
123
|
+
def _namespace(source=nil)
|
124
|
+
case source
|
125
|
+
when Hash ; return source
|
126
|
+
when nil ; return {}
|
127
|
+
when String
|
128
|
+
namespace = {}
|
129
|
+
source = $1 if (source=~/\A\s*\[?(.+?)\]?\s*\z/m)
|
130
|
+
source.split(/[\n\r,]+/).each do |v|
|
131
|
+
v.strip!
|
132
|
+
next if (v=~/^#/)
|
133
|
+
pair = [''] + v.split(/\s*=\s*/, 2)
|
134
|
+
namespace[pair[-2]] = pair[-1]
|
135
|
+
end
|
136
|
+
return namespace
|
137
|
+
else ; raise TypeError, "Irregal Namespace Type"
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
# locale 指定を Array に変換する
|
142
|
+
# @private
|
143
|
+
def _locale(source=nil)
|
144
|
+
# default の Locale
|
145
|
+
return [[nil, '', nil]] unless source
|
146
|
+
|
147
|
+
# source の配列化
|
148
|
+
if source.kind_of?(String)
|
149
|
+
source = $1 if (source=~/\A\s*\[?(.+?)\]?\s*\z/m)
|
150
|
+
source = source.split(/[\n\r,]+/)
|
151
|
+
end
|
152
|
+
|
153
|
+
# 各Localeの展開
|
154
|
+
source.map {|v|
|
155
|
+
if v.kind_of?(String)
|
156
|
+
v = v.strip
|
157
|
+
next if (v=~/^#/)
|
158
|
+
(v =~ /^(\*)?(.*?)(?:\s*=\s*(.+))?$/) ? $~[1..3] : [[nil, '', nil]]
|
159
|
+
else
|
160
|
+
v
|
161
|
+
end
|
162
|
+
}.compact
|
163
|
+
end
|
164
|
+
|
165
|
+
# 文字列 [.., .., ..] を分割する
|
166
|
+
# @private
|
167
|
+
def _split(line)
|
168
|
+
line = line.dup
|
169
|
+
b = d = s = 0
|
170
|
+
(line.length-1).downto(0) do |i|
|
171
|
+
bs = 0
|
172
|
+
(i-1).downto(0) do |k|
|
173
|
+
break unless (line[k,1] == '\\')
|
174
|
+
bs += 1
|
175
|
+
end
|
176
|
+
next if (bs[0] == 1)
|
177
|
+
case line[i,1]
|
178
|
+
when "'" ; s = 1-s if (d == 0)
|
179
|
+
when '"' ; d = 1-d if (s == 0)
|
180
|
+
when ']' ; b += 1 if (d+s == 0)
|
181
|
+
when '[' ; b -= 1 if (d+s == 0 && b > 0)
|
182
|
+
when ',' ; line[i,1] = Escape if (b+d+s == 0)
|
183
|
+
end
|
184
|
+
end
|
185
|
+
return (line =='') ? [''] : line.split(Escape, -1)
|
186
|
+
end
|
187
|
+
|
188
|
+
# locale 指定を解析して Hash の値を取り出す
|
189
|
+
# @private
|
190
|
+
def _hash_value(hash, locale, default='')
|
191
|
+
locale = locale.sub(/\..*/, '').sub(/-/,'_')
|
192
|
+
return hash[locale] if (hash[locale])
|
193
|
+
return _hash_value(hash, _alias[locale], default) if (_alias[locale])
|
194
|
+
language = locale.sub(/_.*/, '')
|
195
|
+
return hash[language] if (hash[language])
|
196
|
+
return hash[default]
|
197
|
+
end
|
198
|
+
|
199
|
+
private
|
200
|
+
|
201
|
+
def _alias
|
202
|
+
@aliases || Alias
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
# ローケール指定時の文字列
|
207
|
+
#
|
208
|
+
# @return [Hash]
|
209
|
+
attr_reader :names
|
210
|
+
|
211
|
+
# 有効なローケール指定
|
212
|
+
#
|
213
|
+
# @return [Array<String>]
|
214
|
+
attr_reader :keys
|
215
|
+
|
216
|
+
# 有効な文字列 - additional attribute
|
217
|
+
#
|
218
|
+
# @return [Array<String>]
|
219
|
+
attr_reader :values
|
220
|
+
|
221
|
+
# 文字列の説明 - additional attribute
|
222
|
+
#
|
223
|
+
# @return [Hash] { anyURI }
|
224
|
+
attr_reader :link
|
225
|
+
|
226
|
+
# Rails 用 I18n 定義へのアクセス・キー
|
227
|
+
#
|
228
|
+
# @return [String]
|
229
|
+
attr_reader :access_key
|
230
|
+
protected :access_key
|
231
|
+
|
232
|
+
# 特定 locale に対応した文字列の取得
|
233
|
+
#
|
234
|
+
# @param [String] loc locale の指定 ( lang[-|_]country.encode )
|
235
|
+
# [ lang - 言語 ]
|
236
|
+
# [ country - 国(省略可) ]
|
237
|
+
# [ encode - 文字コード(省略可) ]
|
238
|
+
#
|
239
|
+
# @return [String] loc に対応した文字列
|
240
|
+
#
|
241
|
+
def translate(loc='')
|
242
|
+
return to_s unless loc
|
243
|
+
lang, code = loc.split(/\./)
|
244
|
+
result = _label_value(loc)
|
245
|
+
return result if !code || @names.member?(loc)
|
246
|
+
return result.encode(code)
|
247
|
+
end
|
248
|
+
alias :/ :translate
|
249
|
+
|
250
|
+
# 特定 locale に対応した reference URI の取得
|
251
|
+
#
|
252
|
+
# @param [String] loc locale の指定
|
253
|
+
#
|
254
|
+
# @return [String] loc に対応した reference URI
|
255
|
+
#
|
256
|
+
def reference(loc='')
|
257
|
+
loc ||= ''
|
258
|
+
return Locale._hash_value(@link, loc)
|
259
|
+
end
|
260
|
+
|
261
|
+
# 部分文字列
|
262
|
+
#
|
263
|
+
# @param [Range] range String#[] と同様の指定方法で範囲を指定する
|
264
|
+
#
|
265
|
+
# @return [When::Parts::Locale] 指定範囲に対応した部分文字列
|
266
|
+
#
|
267
|
+
def [](range)
|
268
|
+
dup._copy({
|
269
|
+
:label => to_s[range],
|
270
|
+
:names => @names.keys.inject({}) {|l,k|
|
271
|
+
l[k] = @names[k][range]
|
272
|
+
l
|
273
|
+
}
|
274
|
+
})
|
275
|
+
end
|
276
|
+
|
277
|
+
# 文字列の一致
|
278
|
+
#
|
279
|
+
# @param [String, Regexp] regexp マッチする正規表現
|
280
|
+
#
|
281
|
+
# @return [Integer] マッチした位置のindex(いずれかの locale でマッチが成功した場合)
|
282
|
+
# @return [nil] すべての locale でマッチに失敗した場合
|
283
|
+
#
|
284
|
+
def =~(regexp)
|
285
|
+
@keys.each do |key|
|
286
|
+
index = (@names[key] =~ regexp)
|
287
|
+
return index if index
|
288
|
+
end
|
289
|
+
return nil
|
290
|
+
end
|
291
|
+
|
292
|
+
# 文字列の連結
|
293
|
+
#
|
294
|
+
# @param [String, When::Toos::Locale] other 連結する文字列
|
295
|
+
#
|
296
|
+
# @return [When::Toos::Locale] 連結された文字列
|
297
|
+
#
|
298
|
+
def +(other)
|
299
|
+
names = {}
|
300
|
+
case other
|
301
|
+
when Locale
|
302
|
+
(@names.keys + other.names.keys).uniq.each do |key|
|
303
|
+
names[key] = _label_value(key) + other._label_value(key)
|
304
|
+
end
|
305
|
+
else
|
306
|
+
@names.keys.each do |key|
|
307
|
+
names[key] = _label_value(key) + other.to_s
|
308
|
+
end
|
309
|
+
end
|
310
|
+
return dup._copy({:names=>names, :label=>to_s + other.to_s})
|
311
|
+
end
|
312
|
+
|
313
|
+
# 書式指定による文字列化
|
314
|
+
#
|
315
|
+
# @param [Array<Object>] other 文字列化する Object の Array
|
316
|
+
# @param [Array<String>] locale 文字列化を行う locale の指定(デフォルト : すべて)
|
317
|
+
#
|
318
|
+
# @return [When::Toos::Locale] 文字列化された Object
|
319
|
+
#
|
320
|
+
def _printf(other, locale=nil)
|
321
|
+
# 処理する配列
|
322
|
+
terms = other.kind_of?(Array) ? [self] + other : [self, other]
|
323
|
+
|
324
|
+
# locale key の配列
|
325
|
+
if locale == []
|
326
|
+
keys = []
|
327
|
+
else
|
328
|
+
keys = terms.inject([]) {|k,t|
|
329
|
+
k += t.keys if t.kind_of?(Locale)
|
330
|
+
k
|
331
|
+
}.uniq
|
332
|
+
if locale
|
333
|
+
locale = [locale] unless locale.kind_of?(Array)
|
334
|
+
keys = locale | (locale & keys)
|
335
|
+
end
|
336
|
+
end
|
337
|
+
keys << nil if keys.include?('')
|
338
|
+
|
339
|
+
# names ハッシュ
|
340
|
+
names = keys.inject({}) {|l,k|
|
341
|
+
l[k] = When::Coordinates::Pair._format(
|
342
|
+
(block_given? ? yield(k, *terms) : terms).map {|t|
|
343
|
+
t.kind_of?(Locale) ? t.translate(k) : t
|
344
|
+
}
|
345
|
+
)
|
346
|
+
l
|
347
|
+
}
|
348
|
+
|
349
|
+
# 生成
|
350
|
+
# @private
|
351
|
+
dup._copy({
|
352
|
+
:label => keys.include?('') ? names.delete(nil) : (names[''] = names[keys[0]]),
|
353
|
+
:names => names
|
354
|
+
})
|
355
|
+
end
|
356
|
+
alias :% :_printf
|
357
|
+
|
358
|
+
# ローケールの更新
|
359
|
+
#
|
360
|
+
# @param [Hash] options 下記の通り
|
361
|
+
# @option options [String] カントリーコード 表現文字列
|
362
|
+
# @option options [Hash] :link { カントリーコード => 参照URL文字列 }
|
363
|
+
# @option options [String] :code_space 規格や辞書を特定するコードスペースのURL文字列
|
364
|
+
# @option options [String] :label 代表文字列
|
365
|
+
# @note Hashキーはすべて Optional で、存在するもののみ更新します
|
366
|
+
#
|
367
|
+
# @return [self] 更新された Object
|
368
|
+
#
|
369
|
+
def update(options={})
|
370
|
+
options = options.dup
|
371
|
+
@link.update(options.delete(:link)) if (options.key?(:link))
|
372
|
+
@code_space = options.delete(:code_space) if (options.key?(:code_space))
|
373
|
+
self[0..-1] = options.delete(:label) if (options.key?(:label))
|
374
|
+
unless (options.empty?)
|
375
|
+
@names.update(options)
|
376
|
+
@keys = @names.keys.sort
|
377
|
+
@values = @names.values.sort.reverse
|
378
|
+
end
|
379
|
+
return self
|
380
|
+
end
|
381
|
+
|
382
|
+
# 包摂リストに登録されている文字を包摂する(自己破壊)
|
383
|
+
#
|
384
|
+
# @param [Hash] pattern 包摂ルール
|
385
|
+
#
|
386
|
+
# @return [When::Parts::Locale] self
|
387
|
+
# @private
|
388
|
+
def ideographic_unification!(pattern=DefaultUnification)
|
389
|
+
names = {}
|
390
|
+
@names.each_pair do |key, value|
|
391
|
+
names[key] = Locale.ideographic_unification(value, pattern)
|
392
|
+
end
|
393
|
+
@names = names
|
394
|
+
@values = @names.values.sort.reverse
|
395
|
+
self[0..-1] = Locale.ideographic_unification(self.to_s[0..-1], pattern)
|
396
|
+
return self
|
397
|
+
end
|
398
|
+
protected :ideographic_unification!
|
399
|
+
|
400
|
+
# 包摂リストに登録されている文字を包摂する(自己保存)
|
401
|
+
#
|
402
|
+
# @param [Hash] pattern 包摂ルール
|
403
|
+
#
|
404
|
+
# @return [When::Parts::Locale] 包摂結果
|
405
|
+
#
|
406
|
+
def ideographic_unification(pattern=DefaultUnification)
|
407
|
+
dup.ideographic_unification!(pattern)
|
408
|
+
end
|
409
|
+
|
410
|
+
# 閏の表記を扱うための書式付整形
|
411
|
+
# @private
|
412
|
+
def prefix(other, locale=nil)
|
413
|
+
return self.dup unless other
|
414
|
+
other = m17n(other) unless other.kind_of?(Locale)
|
415
|
+
other._printf(self, locale) do |k, *t|
|
416
|
+
t[0] = t[0].translate(k)
|
417
|
+
t[0] += "%s" unless t[0] =~ /%[-+]?[.\d]*s/
|
418
|
+
t
|
419
|
+
end
|
420
|
+
end
|
421
|
+
|
422
|
+
protected
|
423
|
+
|
424
|
+
# @private
|
425
|
+
def _copy(options={})
|
426
|
+
if (options.key?(:names))
|
427
|
+
@names = options[:names]
|
428
|
+
@keys = @names.keys.sort
|
429
|
+
@values = @names.values.compact.sort.reverse
|
430
|
+
end
|
431
|
+
@link = options[:link] if (options.key?(:link))
|
432
|
+
@code_space = options[:code_space] if (options.key?(:code_space))
|
433
|
+
@access_key = options[:access_key] if (options.key?(:access_key))
|
434
|
+
self[0..-1] = options[:label] if (options.key?(:label))
|
435
|
+
return self
|
436
|
+
end
|
437
|
+
|
438
|
+
# @private
|
439
|
+
def _copy_all(other)
|
440
|
+
_copy({:names => other.names,
|
441
|
+
:link => other.link,
|
442
|
+
:code_space => other.code_space,
|
443
|
+
:access_key => other.access_key,
|
444
|
+
:label => other.to_s
|
445
|
+
})
|
446
|
+
end
|
447
|
+
|
448
|
+
# locale 指定を解析して @names の値を取り出す
|
449
|
+
# @private
|
450
|
+
def _label_value(locale)
|
451
|
+
label = Locale._hash_value(@names, locale, nil)
|
452
|
+
return label if label
|
453
|
+
addition = When::BasicTypes::M17n._get_locale(locale, @access_key)
|
454
|
+
return @names[''] unless addition
|
455
|
+
update(addition)
|
456
|
+
return Locale._hash_value(@names, locale)
|
457
|
+
end
|
458
|
+
|
459
|
+
private
|
460
|
+
|
461
|
+
def _names(names, namespace, default_locale)
|
462
|
+
|
463
|
+
# names, link の組み立て
|
464
|
+
@names = {}
|
465
|
+
@link = {}
|
466
|
+
|
467
|
+
if (names.kind_of?(String))
|
468
|
+
unless (names=~/\A\s*\[(.+?)\]\s*\z/m)
|
469
|
+
names = names.strip
|
470
|
+
@names[''] = names
|
471
|
+
@keys = ['']
|
472
|
+
@values = [names]
|
473
|
+
return names
|
474
|
+
end
|
475
|
+
names = $1.split(/[\n\r,]+/)
|
476
|
+
end
|
477
|
+
|
478
|
+
mark = []
|
479
|
+
asterisk = []
|
480
|
+
default_locale = default_locale.dup
|
481
|
+
names.each do |v|
|
482
|
+
v.strip!
|
483
|
+
case v
|
484
|
+
when '', /^#/ ;
|
485
|
+
when /^\/(.+)/; @access_key = $1
|
486
|
+
when /^(\*)?(?:([^=%]*?)\s*:)?\s*(.+?)\s*(=\s*(.+?)?)?$/
|
487
|
+
asterisk[0], locale, name, assignment, ref = $~[1..5]
|
488
|
+
asterisk[1], locale, default_ref = default_locale.shift unless locale
|
489
|
+
locale ||= ''
|
490
|
+
ref ||= default_ref unless (assignment)
|
491
|
+
ref ||= ''
|
492
|
+
mark[0] = locale if asterisk[0]
|
493
|
+
mark[1] = locale if asterisk[1]
|
494
|
+
mark[2] = locale unless mark[2]
|
495
|
+
@names[locale] = name
|
496
|
+
if (ref =~ /^(.+):/)
|
497
|
+
prefix = namespace[$1]
|
498
|
+
ref.sub!(/^.+:/, prefix) if (prefix)
|
499
|
+
end
|
500
|
+
ref += URI.encode(name) if (ref =~ /[\/#:]$/)
|
501
|
+
@link[locale] = ref
|
502
|
+
else ; raise ArgumentError, "Irregal locale format"
|
503
|
+
end
|
504
|
+
end
|
505
|
+
|
506
|
+
# keys, values の準備
|
507
|
+
@keys = @names.keys.sort
|
508
|
+
@values = @names.values.sort.reverse
|
509
|
+
|
510
|
+
return @names[mark[0] || mark[1] || mark[2]]
|
511
|
+
end
|
512
|
+
end
|
513
|
+
end
|