Module: When::Parts::Locale

Included in:
BasicTypes::M17n
Defined in:
lib/when_exe/parts/locale.rb

Overview

Multilingualization(M17n) 対応モジュール

When::BasicTypes::M17n の実装のうち When::BasicTypes 内部で
定義すべきでない部分を切り出してモジュールとしている

Constant Summary collapse

DefaultAlias =

Locale 読み替えの初期設定

{'alias'=>'ja', '日本語'=>'ja', '英語'=>'en'}
DefaultUnification =

漢字の包摂

{
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '寿',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
}
Escape =

Escape

{
  "\\\\" => "\\",
  "\\n"  => "\n",
  "\\r"  => "\r",
  "\\,"  => ","
}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#keysArray<String> (readonly)

有効なローケール指定

Returns:



240
241
242
# File 'lib/when_exe/parts/locale.rb', line 240

def keys
  @keys
end

文字列の説明 - additional attribute

Returns:

  • (Hash)

    { anyURI }



250
251
252
# File 'lib/when_exe/parts/locale.rb', line 250

def link
  @link
end

#namesHash (readonly)

ローケール指定時の文字列

Returns:

  • (Hash)


235
236
237
# File 'lib/when_exe/parts/locale.rb', line 235

def names
  @names
end

#valuesArray<String> (readonly)

有効な文字列 - additional attribute

Returns:



245
246
247
# File 'lib/when_exe/parts/locale.rb', line 245

def values
  @values
end

Class Method Details

._aliasObject



226
227
228
# File 'lib/when_exe/parts/locale.rb', line 226

def _alias
  @aliases || DefaultAlias
end

._hash_value(hash, locale, default = '') ⇒ Object

locale 指定を解析して Hash の値を取り出す



212
213
214
215
216
217
218
219
# File 'lib/when_exe/parts/locale.rb', line 212

def _hash_value(hash, locale, default='')
  locale = locale.sub(/\..*/, '').sub(/-/,'_')
  return hash[locale] if (hash[locale])
  return _hash_value(hash, _alias[locale], default) if (_alias[locale])
  language = locale.sub(/_.*/, '')
  return hash[language] if (hash[language])
  return hash[default]
end

._locale(source = nil) ⇒ Object

locale 指定を Array に変換する



157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/when_exe/parts/locale.rb', line 157

def _locale(source=nil)
  # default の Locale
  return [[nil, '', nil]] unless source

  # source の配列化
  if source.kind_of?(String)
    source = $1 if (source=~/\A\s*\[?(.+?)\]?\s*\z/m)
    source = source.scan(/((?:[^\\\n\r,]|\\.)+)(?:[\n\r,]+(?!\z))?|[\n\r,]+/m).flatten.map {|token|
      (token||'').gsub(/\\./) {|escape| Escape[escape] || escape}
    }
  end

  # 各Localeの展開
  source.map {|v|
    if v.kind_of?(String)
      v = v.strip
      next if (v=~/^#/)
      (v =~ /^(\*)?(.*?)(?:\s*=\s*(.+))?$/) ? $~[1..3] : [[nil, '', nil]]
    else
      v
    end
  }.compact
end

._namespace(source = nil) ⇒ Object

文字列で表現された namespace 指定を Hash に変換する



135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/when_exe/parts/locale.rb', line 135

def _namespace(source=nil)
  case source
  when Hash ; source
  when nil  ; {}
  when String
    namespace = {}
    source = $1 if (source=~/\A\s*\[?(.+?)\]?\s*\z/m)
    source.split(/[\n\r,]+/).each do |v|
      v.strip!
      next if (v=~/^#/)
      pair = [''] + v.split(/\s*=\s*/, 2)
      namespace[pair[-2]] = pair[-1]
    end
    namespace
  when When::Parts::Resource::ContentLine
    source.object.names
  else ; raise TypeError, "Irregal Namespace Type: #{source.class}"
  end
end

._setup_(options = {}) ⇒ Object

Note:

:alias の指定がない場合、aliases は DefaultAlias(モジュール定数)と解釈する。 :unification の指定がない場合、unifications は DefaultUnification(モジュール定数)と解釈する。

When::Parts::Locale Module のグローバルな設定を行う

Parameters:

  • options (Hash) (defaults to: {})

    下記の通り

Options Hash (options):

  • :alias (Hash)

    Locale の読み替えパターンを Hash で指定する。

  • :unification (Hash)

    漢字の包摂パターンを Hash で指定する。



69
70
71
72
# File 'lib/when_exe/parts/locale.rb', line 69

def _setup_(options={})
  @aliases      = options[:alias]       || DefaultAlias
  @unifications = options[:unification] || DefaultUnification
end

._split(source) ⇒ Object

文字列 [.., .., ..] を分割する



183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
# File 'lib/when_exe/parts/locale.rb', line 183

def _split(source)
  line  = source.dup
  return [line] unless line =~ /,/
  list  = []
  b = d = s = 0
  (source.length-1).downto(0) do |i|
    bs = 0
    (i-1).downto(0) do |k|
      break unless (line[k,1] == '\\')
      bs += 1
    end
    next if (bs[0] == 1)
    case line[i,1]
    when "'"         ; s  = 1-s  if (d == 0)
    when '"'         ; d  = 1-d  if (s == 0)
    when ']','}',')' ; b += 1 if  (d+s == 0)
    when '[','{','(' ; b -= 1 if  (d+s == 0 && b > 0)
    when ','
      if (b+d+s == 0)
        list.unshift(line[i+1..-1])
        line = i > 0 ? line[0..i-1] : ''
      end
    end
  end
  list.unshift(line)
end

._unificationObject



222
223
224
# File 'lib/when_exe/parts/locale.rb', line 222

def _unification
  @unifications || DefaultUnification
end

.ideographic_unification(source, pattern = _unification) ⇒ When::Parts::Locale, ...

包摂リストに登録されている文字を包摂する

Parameters:

  • source (When::Parts::Locale)

    文字を包摂しようとする国際化文字列

  • source (String)

    文字を包摂しようとする文字列

  • source (Regexp)

    文字を包摂しようとする正規表現

  • pattern (Hash) (defaults to: _unification)

    包摂ルール

Returns:

  • (When::Parts::Locale)

    文字を包摂した国際化文字列

  • (String)

    文字を包摂した文字列

  • (Regexp)

    文字を包摂した正規表現



118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/when_exe/parts/locale.rb', line 118

def ideographic_unification(source, pattern=_unification)
  case source
  when When::Parts::Locale
    source.ideographic_unification(pattern)
  when Regexp
    Regexp.compile(ideographic_unification(source.source.encode('UTF-8'), pattern), source.options)
  when String
    source.gsub(/./) do |c|
      pattern[c] ? pattern[c] : c
    end
  else
    source
  end
end

.translate(source, loc = '') ⇒ String

Note:

source が Hash や Array の場合、その構成要素を変換して返す

Note:

encode は通常大文字だが、大文字/小文字の変換は行わず指定されたまま使用している

特定 locale に対応した文字列の取得

@param loc locale の指定 ( langcountry.encode )

[ lang    - 言語               ]
[ country - (省略可)         ]
[ encode  - 文字コード(省略可) ]

Parameters:

  • source (String)

    もとにする String または M17n

Returns:

  • (String)

    loc に対応した文字列



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/when_exe/parts/locale.rb', line 88

def translate(source, loc='')
  return source unless loc
  case source
  when Hash
    result = {}
    source.each_pair do |key, value|
      result[translate(key, loc)] = translate(value, loc)
    end
    return result
  when Array
    return source.map {|value| translate(value, loc)}
  when Locale
    return source.translate(loc)
  when String
    return source.encode($1) if loc =~ /\.(.+)$/
  end
  source
end

Instance Method Details

#+(other) ⇒ When::Toos::Locale

文字列の連結

Parameters:

  • other (String, When::Toos::Locale)

    連結する文字列

Returns:

  • (When::Toos::Locale)

    連結された文字列



339
340
341
342
343
344
345
346
347
348
349
350
351
352
# File 'lib/when_exe/parts/locale.rb', line 339

def +(other)
  names = {}
  case other
  when Locale
    (@names.keys + other.names.keys).uniq.each do |key|
      names[key] = _label_value(key) + other._label_value(key)
    end
  else
    @names.keys.each do |key|
      names[key] = _label_value(key) + other.to_s
    end
  end
  return dup._copy({:names=>names, :label=>to_s + other.to_s})
end

#=~(regexp) ⇒ Integer?

文字列の一致

Parameters:

Returns:

  • (Integer)

    マッチした位置のindex(いずれかの locale でマッチが成功した場合)

  • (nil)

    すべての locale でマッチに失敗した場合



310
311
312
313
314
315
316
# File 'lib/when_exe/parts/locale.rb', line 310

def =~(regexp)
  @keys.each do |key|
    index = (@names[key] =~ regexp)
    return index if index
  end
  return nil
end

#[](range) ⇒ When::Parts::Locale

部分文字列

Parameters:

  • range (Range)

    String#[] と同様の指定方法で範囲を指定する

Returns:



293
294
295
296
297
298
299
300
301
# File 'lib/when_exe/parts/locale.rb', line 293

def [](range)
  dup._copy({
    :label => to_s[range],
    :names => @names.keys.inject({}) {|l,k|
      l[k] =  @names[k][range]
      l
    }
  })
end

#_printf(other, locale = nil) ⇒ When::Toos::Locale Also known as: %

書式指定による文字列化

Parameters:

  • other (Array<Object>)

    文字列化する Object の Array

  • locale (Array<String>) (defaults to: nil)

    文字列化を行う locale の指定(デフォルト : すべて)

Returns:

  • (When::Toos::Locale)

    文字列化された Object



361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
# File 'lib/when_exe/parts/locale.rb', line 361

def _printf(other, locale=nil)
  # 処理する配列
  terms = other.kind_of?(Array) ? [self] + other : [self, other]

  # locale key の配列
  if locale == []
    keys = []
  else
    keys = terms.inject([]) {|k,t|
      k += t.keys if t.kind_of?(Locale)
      k
    }.uniq
    if locale
      locale = [locale] unless locale.kind_of?(Array)
      keys   = locale | (locale & keys)
    end
  end
  keys << nil if keys.include?('')

  # names ハッシュ
  names = keys.inject({}) {|l,k|
    l[k] = When::Coordinates::Pair._format(
             (block_given? ? yield(k, *terms) : terms).map {|t|
               t.kind_of?(Locale) ? t.translate(k) : t
             }
           )
    l
  }

  # 生成
  # @private
  dup._copy({
    :label => keys.include?('') ? names.delete(nil) : (names[''] = names[keys[0]]),
    :names => names
  })
end

#ideographic_unification(pattern = _unification) ⇒ When::Parts::Locale

包摂リストに登録されている文字を包摂する(自己保存)

Parameters:

  • pattern (Hash) (defaults to: _unification)

    包摂ルール

Returns:



447
448
449
# File 'lib/when_exe/parts/locale.rb', line 447

def ideographic_unification(pattern=_unification)
  dup.ideographic_unification!(pattern)
end

#index(other) ⇒ Integer?

部分文字列の位置

Parameters:

  • other (String)

    部分文字列

Returns:

  • (Integer)

    部分文字列の先頭のindex(いずれかの locale で部分文字列を含んだ場合)

  • (nil)

    すべての locale で部分文字列を含まない場合



325
326
327
328
329
330
331
# File 'lib/when_exe/parts/locale.rb', line 325

def index(other)
  @keys.each do |key|
    index = @names[key].index(Locale.translate(other, key))
    return index if index
  end
  return nil
end

#prefix(other, locale = nil) ⇒ Object

閏の表記を扱うための書式付整形



453
454
455
456
457
458
459
460
461
# File 'lib/when_exe/parts/locale.rb', line 453

def prefix(other, locale=nil)
  return self.dup unless other
  other = m17n(other) unless other.kind_of?(Locale)
  other._printf(self, locale) do |k, *t|
    t[0]  = t[0].translate(k)
    t[0] += "%s" unless t[0] =~ /%[-+]?[.\d]*s/
    t
  end
end

#reference(loc = '') ⇒ String

特定 locale に対応した reference URI の取得

Parameters:

  • loc (String) (defaults to: '')

    locale の指定

Returns:

  • (String)

    loc に対応した reference URI



282
283
284
285
# File 'lib/when_exe/parts/locale.rb', line 282

def reference(loc='')
  loc ||= ''
  return Locale._hash_value(@link, loc)
end

#translate(loc = '') ⇒ String Also known as: /

特定 locale に対応した文字列の取得

Parameters:

  • loc (String) (defaults to: '')

    locale の指定 ( langcountry.encode )

    lang - 言語
    country - 国(省略可)
    encode - 文字コード(省略可)

Returns:

  • (String)

    loc に対応した文字列



267
268
269
270
271
272
273
# File 'lib/when_exe/parts/locale.rb', line 267

def translate(loc='')
  return to_s unless loc
  lang, code = loc.split(/\./)
  result = _label_value(loc)
  return result if !code || @names.member?(loc)
  return result.encode(code)
end

#update(options = {}) ⇒ self

Note:

Hashキーはすべて Optional で、存在するもののみ更新します

ローケールの更新

Parameters:

  • options (Hash) (defaults to: {})

    下記の通り

Options Hash (options):

  • カントリーコード (String)

    表現文字列

  • :link (Hash)

    { カントリーコード => 参照URL文字列 }

  • :code_space (String)

    規格や辞書を特定するコードスペースのURL文字列

  • :label (String)

    代表文字列

Returns:

  • (self)

    更新された Object



410
411
412
413
414
415
416
417
418
419
420
421
# File 'lib/when_exe/parts/locale.rb', line 410

def update(options={})
  options = options.dup
  @link.update(options.delete(:link))       if (options.key?(:link))
  @code_space = options.delete(:code_space) if (options.key?(:code_space))
  self[0..-1] = options.delete(:label)      if (options.key?(:label))
  unless (options.empty?)
    @names.update(options)
    @keys     = @names.keys.sort
    @values   = @names.values.sort.reverse
  end
  return self
end