Redmine/vendor/plugins/gloc-1.1.0/lib/gloc.rb

301 lines
10 KiB
Ruby

# Copyright (c) 2005-2006 David Barri
require 'yaml'
require 'gloc-internal'
require 'gloc-helpers'
module GLoc
UTF_8= 'utf-8'
SHIFT_JIS= 'sjis'
EUC_JP= 'euc-jp'
# This module will be included in both instances and classes of GLoc includees.
# It is also included as class methods in the GLoc module itself.
module InstanceMethods
include Helpers
# Returns a localized string.
def l(symbol, *arguments)
return GLoc._l(symbol,current_language,*arguments)
end
# Returns a localized string in a specified language.
# This does not effect <tt>current_language</tt>.
def ll(lang, symbol, *arguments)
return GLoc._l(symbol,lang.to_sym,*arguments)
end
# Returns a localized string if the argument is a Symbol, else just returns the argument.
def ltry(possible_key)
possible_key.is_a?(Symbol) ? l(possible_key) : possible_key
end
# Uses the default GLoc rule to return a localized string.
# See lwr_() for more info.
def lwr(symbol, *arguments)
lwr_(:default, symbol, *arguments)
end
# Uses a <em>rule</em> to return a localized string.
# A rule is a function that uses specified arguments to return a localization key prefix.
# The prefix is appended to the localization key originally specified, to create a new key which
# is then used to lookup a localized string.
def lwr_(rule, symbol, *arguments)
GLoc._l("#{symbol}#{GLoc::_l_rule(rule,current_language).call(*arguments)}",current_language,*arguments)
end
# Returns <tt>true</tt> if a localized string with the specified key exists.
def l_has_string?(symbol)
return GLoc._l_has_string?(symbol,current_language)
end
# Sets the current language for this instance/class.
# Setting the language of a class effects all instances unless the instance has its own language defined.
def set_language(language)
GLoc.current_language = language
end
# Sets the current language if the language passed is a valid language.
# If the language was valid, this method returns <tt>true</tt> else it will return <tt>false</tt>.
# Note that <tt>nil</tt> is not a valid language.
# See set_language(language) for more info.
def set_language_if_valid(language)
if GLoc.valid_language?(language)
set_language(language)
true
else
false
end
end
end
#---------------------------------------------------------------------------
# Instance
include ::GLoc::InstanceMethods
# Returns the instance-level current language, or if not set, returns the class-level current language.
def current_language
GLoc.current_language
end
#---------------------------------------------------------------------------
# Class
# All classes/modules that include GLoc will also gain these class methods.
# Notice that the GLoc::InstanceMethods module is also included.
module ClassMethods
include ::GLoc::InstanceMethods
# Returns the current language, or if not set, returns the GLoc current language.
def current_language
GLoc.current_language
end
end
def self.included(target) #:nodoc:
super
class << target
include ::GLoc::ClassMethods
end
end
#---------------------------------------------------------------------------
# GLoc module
class << self
include ::GLoc::InstanceMethods
@@current_language = nil
# Returns the current language
def current_language
@@current_language || GLoc::CONFIG[:default_language]
end
def current_language=(lang)
@@current_language = lang.blank? ? nil : lang.to_sym
end
# Adds a collection of localized strings to the in-memory string store.
def add_localized_strings(lang, symbol_hash, override=true, strings_charset=nil)
_verbose_msg {"Adding #{symbol_hash.size} #{lang} strings."}
_add_localized_strings(lang, symbol_hash, override, strings_charset)
_verbose_msg :stats
end
# Creates a backup of the internal state of GLoc (ie. strings, langs, rules, config)
# and optionally clears everything.
def backup_state(clear=false)
s= _get_internal_state_vars.map{|o| o.clone}
_get_internal_state_vars.each{|o| o.clear} if clear
s
end
# Removes all localized strings from memory, either of a certain language (or languages),
# or entirely.
def clear_strings(*languages)
if languages.empty?
_verbose_msg {"Clearing all strings"}
LOCALIZED_STRINGS.clear
LOWERCASE_LANGUAGES.clear
else
languages.each {|l|
_verbose_msg {"Clearing :#{l} strings"}
l= l.to_sym
LOCALIZED_STRINGS.delete l
LOWERCASE_LANGUAGES.each_pair {|k,v| LOWERCASE_LANGUAGES.delete k if v == l}
}
end
end
alias :_clear_strings :clear_strings
# Removes all localized strings from memory, except for those of certain specified languages.
def clear_strings_except(*languages)
clear= (LOCALIZED_STRINGS.keys - languages)
_clear_strings(*clear) unless clear.empty?
end
# Returns the charset used to store localized strings in memory.
def get_charset(lang)
CONFIG[:internal_charset_per_lang][lang] || CONFIG[:internal_charset]
end
# Returns a GLoc configuration value.
def get_config(key)
CONFIG[key]
end
# Loads the localized strings that are included in the GLoc library.
def load_gloc_default_localized_strings(override=false)
GLoc.load_localized_strings "#{File.dirname(__FILE__)}/../lang", override
end
# Loads localized strings from all yml files in the specifed directory.
def load_localized_strings(dir=nil, override=true)
_charset_required
_get_lang_file_list(dir).each {|filename|
# Load file
raw_hash = YAML::load(File.read(filename))
raw_hash={} unless raw_hash.kind_of?(Hash)
filename =~ /([^\/\\]+)\.ya?ml$/
lang = $1.to_sym
file_charset = raw_hash['file_charset'] || UTF_8
# Convert string keys to symbols
dest_charset= get_charset(lang)
_verbose_msg {"Reading file #{filename} [charset: #{file_charset} --> #{dest_charset}]"}
symbol_hash = {}
Iconv.open(dest_charset, file_charset) do |i|
raw_hash.each {|key, value|
symbol_hash[key.to_sym] = i.iconv(value)
}
end
# Add strings to repos
_add_localized_strings(lang, symbol_hash, override)
}
_verbose_msg :stats
end
# Restores a backup of GLoc's internal state that was made with backup_state.
def restore_state(state)
_get_internal_state_vars.each do |o|
o.clear
o.send o.respond_to?(:merge!) ? :merge! : :concat, state.shift
end
end
# Sets the charset used to internally store localized strings.
# You can set the charset to use for a specific language or languages,
# or if none are specified the charset for ALL localized strings will be set.
def set_charset(new_charset, *langs)
CONFIG[:internal_charset_per_lang] ||= {}
# Convert symbol shortcuts
if new_charset.is_a?(Symbol)
new_charset= case new_charset
when :utf8, :utf_8 then UTF_8
when :sjis, :shift_jis, :shiftjis then SHIFT_JIS
when :eucjp, :euc_jp then EUC_JP
else new_charset.to_s
end
end
# Convert existing strings
(langs.empty? ? LOCALIZED_STRINGS.keys : langs).each do |lang|
cur_charset= get_charset(lang)
if cur_charset && new_charset != cur_charset
_verbose_msg {"Converting :#{lang} strings from #{cur_charset} to #{new_charset}"}
Iconv.open(new_charset, cur_charset) do |i|
bundle= LOCALIZED_STRINGS[lang]
bundle.each_pair {|k,v| bundle[k]= i.iconv(v)}
end
end
end
# Set new charset value
if langs.empty?
_verbose_msg {"Setting GLoc charset for all languages to #{new_charset}"}
CONFIG[:internal_charset]= new_charset
CONFIG[:internal_charset_per_lang].clear
else
langs.each do |lang|
_verbose_msg {"Setting GLoc charset for :#{lang} strings to #{new_charset}"}
CONFIG[:internal_charset_per_lang][lang]= new_charset
end
end
end
# Sets GLoc configuration values.
def set_config(hash)
CONFIG.merge! hash
end
# Sets the $KCODE global variable according to a specified charset, or else the
# current default charset for the default language.
def set_kcode(charset=nil)
_charset_required
charset ||= get_charset(current_language)
$KCODE= case charset
when UTF_8 then 'u'
when SHIFT_JIS then 's'
when EUC_JP then 'e'
else 'n'
end
_verbose_msg {"$KCODE set to #{$KCODE}"}
end
# Tries to find a valid language that is similar to the argument passed.
# Eg. :en, :en_au, :EN_US are all similar languages.
# Returns <tt>nil</tt> if no similar languages are found.
def similar_language(lang)
return nil if lang.nil?
return lang.to_sym if valid_language?(lang)
# Check lowercase without dashes
lang= lang.to_s.downcase.gsub('-','_')
return LOWERCASE_LANGUAGES[lang] if LOWERCASE_LANGUAGES.has_key?(lang)
# Check without dialect
if lang.to_s =~ /^([a-z]+?)[^a-z].*/
lang= $1
return LOWERCASE_LANGUAGES[lang] if LOWERCASE_LANGUAGES.has_key?(lang)
end
# Check other dialects
lang= "#{lang}_"
LOWERCASE_LANGUAGES.keys.each {|k| return LOWERCASE_LANGUAGES[k] if k.starts_with?(lang)}
# Nothing found
nil
end
# Returns an array of (currently) valid languages (ie. languages for which localized data exists).
def valid_languages
LOCALIZED_STRINGS.keys
end
# Returns <tt>true</tt> if there are any localized strings for a specified language.
# Note that although <tt>set_langauge nil</tt> is perfectly valid, <tt>nil</tt> is not a valid language.
def valid_language?(language)
LOCALIZED_STRINGS.has_key? language.to_sym rescue false
end
end
end