1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
|
=begin
textdomain.rb - GetText::Textdomain
Copyright (C) 2001-2009 Masao Mutoh
Copyright (C) 2001-2003 Masahiro Sakai
Masahiro Sakai <s01397ms@sfc.keio.ac.jp>
Masao Mutoh <mutomasa at gmail.com>
You may redistribute it and/or modify it under the same
license terms as Ruby or LGPL.
=end
require 'gettext/core_ext/string'
require 'gettext/runtime/mofile'
require 'gettext/runtime/locale_path'
module GetText
# GetText::TextDomain class manages mo-files of a textdomain.
#
# Usually, you don't need to use this class directly.
#
# Notice: This class is unstable. APIs will be changed.
class TextDomain
attr_reader :output_charset
attr_reader :mofiles
attr_reader :name
@@cached = ! $DEBUG
# Cache the mo-file or not.
# Default is true. If $DEBUG is set then false.
def self.cached?
@@cached
end
# Set to cache the mo-file or not.
# * val: true if cached, otherwise false.
def self.cached=(val)
@@cached = val
end
# Add default locale path. Usually you should use GetText.add_default_locale_path instead.
# * path: a new locale path. (e.g.) "/usr/share/locale/%{lang}/LC_MESSAGES/%{name}.mo"
# ('locale' => "ja_JP", 'name' => "textdomain")
# * Returns: the new DEFAULT_LOCALE_PATHS
def self.add_default_locale_path(path)
warn "Deprecated. Use GetText::LocalePath.add_default_rule instead."
LocalePath.add_default_rule(path)
end
# Creates a new GetText::TextDomain.
# * name: the textdomain name.
# * topdir: the locale path ("%{topdir}/%{lang}/LC_MESSAGES/%{name}.mo") or nil.
# * output_charset: output charset.
# * Returns: a newly created GetText::TextDomain object.
def initialize(name, topdir = nil, output_charset = nil)
@name, @output_charset = name, output_charset
@locale_path = LocalePath.new(@name, topdir)
@mofiles = {}
end
# Translates the translated string.
# * lang: Locale::Tag::Simple's subclass.
# * msgid: the original message.
# * Returns: the translated string or nil.
def translate_singluar_message(lang, msgid)
return "" if msgid == "" or msgid.nil?
lang_key = lang.to_s
mofile = nil
if self.class.cached?
mofile = @mofiles[lang_key]
end
unless mofile
mofile = load_mo(lang)
end
if (! mofile) or (mofile ==:empty)
return nil
end
msgstr = mofile[msgid]
if msgstr and (msgstr.size > 0)
msgstr
elsif msgid.include?("\000")
# Check "aaa\000bbb" and show warning but return the singluar part.
ret = nil
msgid_single = msgid.split("\000")[0]
mofile.each{|key, val|
if key =~ /^#{Regexp.quote(msgid_single)}\000/
# Usually, this is not caused to make po-files from rgettext.
warn %Q[Warning: n_("#{msgid_single}", "#{msgid.split("\000")[1]}") and n_("#{key.gsub(/\000/, '", "')}") are duplicated.]
ret = val
break
end
}
ret
else
ret = nil
mofile.each{|key, val|
if key =~ /^#{Regexp.quote(msgid)}\000/
ret = val.split("\000")[0]
break
end
}
ret
end
end
DEFAULT_PLURAL_CALC = Proc.new{|n| n != 1}
DEFAULT_SINGLE_CALC = Proc.new{|n| 0}
# Translates the translated string.
# * lang: Locale::Tag::Simple's subclass.
# * msgid: the original message.
# * msgid_plural: the original message(plural).
# * Returns: the translated string as an Array ([[msgstr1, msgstr2, ...], cond]) or nil.
def translate_plural_message(lang, msgid, msgid_plural) #:nodoc:
key = msgid + "\000" + msgid_plural
msg = translate_singluar_message(lang, key)
ret = nil
if ! msg
ret = nil
elsif msg.include?("\000")
# [[msgstr[0], msgstr[1], msgstr[2],...], cond]
mofile = @mofiles[lang.to_posix.to_s]
cond = (mofile and mofile != :empty) ? mofile.plural_as_proc : DEFAULT_PLURAL_CALC
ret = [msg.split("\000"), cond]
else
ret = [[msg], DEFAULT_SINGLE_CALC]
end
ret
end
# Clear cached mofiles.
def clear
@mofiles = {}
end
# Set output_charset.
# * charset: output charset.
def output_charset=(charset)
@output_charset = charset
clear
end
private
# Load a mo-file from the file.
# lang is the subclass of Locale::Tag::Simple.
def load_mo(lang)
lang = lang.to_posix unless lang.kind_of? Locale::Tag::Posix
lang_key = lang.to_s
mofile = @mofiles[lang_key]
if mofile
if mofile == :empty
return :empty
elsif ! self.class.cached?
mofile.update!
end
return mofile
end
path = @locale_path.current_path(lang)
if path
charset = @output_charset || lang.charset || Locale.charset || "UTF-8"
@mofiles[lang_key] = MOFile.open(path, charset)
else
@mofiles[lang_key] = :empty
end
end
end
end
|