You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

gloc.rb 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. # Copyright (c) 2005-2006 David Barri
  2. require 'yaml'
  3. require 'gloc-internal'
  4. require 'gloc-helpers'
  5. module GLoc
  6. UTF_8= 'utf-8'
  7. SHIFT_JIS= 'sjis'
  8. EUC_JP= 'euc-jp'
  9. # This module will be included in both instances and classes of GLoc includees.
  10. # It is also included as class methods in the GLoc module itself.
  11. module InstanceMethods
  12. include Helpers
  13. # Returns a localized string.
  14. def l(symbol, *arguments)
  15. return GLoc._l(symbol,current_language,*arguments)
  16. end
  17. # Returns a localized string in a specified language.
  18. # This does not effect <tt>current_language</tt>.
  19. def ll(lang, symbol, *arguments)
  20. return GLoc._l(symbol,lang.to_sym,*arguments)
  21. end
  22. # Returns a localized string if the argument is a Symbol, else just returns the argument.
  23. def ltry(possible_key)
  24. possible_key.is_a?(Symbol) ? l(possible_key) : possible_key
  25. end
  26. # Uses the default GLoc rule to return a localized string.
  27. # See lwr_() for more info.
  28. def lwr(symbol, *arguments)
  29. lwr_(:default, symbol, *arguments)
  30. end
  31. # Uses a <em>rule</em> to return a localized string.
  32. # A rule is a function that uses specified arguments to return a localization key prefix.
  33. # The prefix is appended to the localization key originally specified, to create a new key which
  34. # is then used to lookup a localized string.
  35. def lwr_(rule, symbol, *arguments)
  36. GLoc._l("#{symbol}#{GLoc::_l_rule(rule,current_language).call(*arguments)}",current_language,*arguments)
  37. end
  38. # Returns <tt>true</tt> if a localized string with the specified key exists.
  39. def l_has_string?(symbol)
  40. return GLoc._l_has_string?(symbol,current_language)
  41. end
  42. # Sets the current language for this instance/class.
  43. # Setting the language of a class effects all instances unless the instance has its own language defined.
  44. def set_language(language)
  45. @gloc_language= language.nil? ? nil : language.to_sym
  46. end
  47. # Sets the current language if the language passed is a valid language.
  48. # If the language was valid, this method returns <tt>true</tt> else it will return <tt>false</tt>.
  49. # Note that <tt>nil</tt> is not a valid language.
  50. # See set_language(language) for more info.
  51. def set_language_if_valid(language)
  52. if GLoc.valid_language?(language)
  53. set_language(language)
  54. true
  55. else
  56. false
  57. end
  58. end
  59. end
  60. #---------------------------------------------------------------------------
  61. # Instance
  62. include ::GLoc::InstanceMethods
  63. # Returns the instance-level current language, or if not set, returns the class-level current language.
  64. def current_language
  65. @gloc_language || self.class.current_language
  66. end
  67. #---------------------------------------------------------------------------
  68. # Class
  69. # All classes/modules that include GLoc will also gain these class methods.
  70. # Notice that the GLoc::InstanceMethods module is also included.
  71. module ClassMethods
  72. include ::GLoc::InstanceMethods
  73. # Returns the current language, or if not set, returns the GLoc current language.
  74. def current_language
  75. @gloc_language || GLoc.current_language
  76. end
  77. end
  78. def self.included(target) #:nodoc:
  79. super
  80. class << target
  81. include ::GLoc::ClassMethods
  82. end
  83. end
  84. #---------------------------------------------------------------------------
  85. # GLoc module
  86. class << self
  87. include ::GLoc::InstanceMethods
  88. # Returns the default language
  89. def current_language
  90. GLoc::CONFIG[:default_language]
  91. end
  92. # Adds a collection of localized strings to the in-memory string store.
  93. def add_localized_strings(lang, symbol_hash, override=true, strings_charset=nil)
  94. _verbose_msg {"Adding #{symbol_hash.size} #{lang} strings."}
  95. _add_localized_strings(lang, symbol_hash, override, strings_charset)
  96. _verbose_msg :stats
  97. end
  98. # Creates a backup of the internal state of GLoc (ie. strings, langs, rules, config)
  99. # and optionally clears everything.
  100. def backup_state(clear=false)
  101. s= _get_internal_state_vars.map{|o| o.clone}
  102. _get_internal_state_vars.each{|o| o.clear} if clear
  103. s
  104. end
  105. # Removes all localized strings from memory, either of a certain language (or languages),
  106. # or entirely.
  107. def clear_strings(*languages)
  108. if languages.empty?
  109. _verbose_msg {"Clearing all strings"}
  110. LOCALIZED_STRINGS.clear
  111. LOWERCASE_LANGUAGES.clear
  112. else
  113. languages.each {|l|
  114. _verbose_msg {"Clearing :#{l} strings"}
  115. l= l.to_sym
  116. LOCALIZED_STRINGS.delete l
  117. LOWERCASE_LANGUAGES.each_pair {|k,v| LOWERCASE_LANGUAGES.delete k if v == l}
  118. }
  119. end
  120. end
  121. alias :_clear_strings :clear_strings
  122. # Removes all localized strings from memory, except for those of certain specified languages.
  123. def clear_strings_except(*languages)
  124. clear= (LOCALIZED_STRINGS.keys - languages)
  125. _clear_strings(*clear) unless clear.empty?
  126. end
  127. # Returns the charset used to store localized strings in memory.
  128. def get_charset(lang)
  129. CONFIG[:internal_charset_per_lang][lang] || CONFIG[:internal_charset]
  130. end
  131. # Returns a GLoc configuration value.
  132. def get_config(key)
  133. CONFIG[key]
  134. end
  135. # Loads the localized strings that are included in the GLoc library.
  136. def load_gloc_default_localized_strings(override=false)
  137. GLoc.load_localized_strings "#{File.dirname(__FILE__)}/../lang", override
  138. end
  139. # Loads localized strings from all yml files in the specifed directory.
  140. def load_localized_strings(dir=nil, override=true)
  141. _charset_required
  142. _get_lang_file_list(dir).each {|filename|
  143. # Load file
  144. raw_hash = YAML::load(File.read(filename))
  145. raw_hash={} unless raw_hash.kind_of?(Hash)
  146. filename =~ /([^\/\\]+)\.ya?ml$/
  147. lang = $1.to_sym
  148. file_charset = raw_hash['file_charset'] || UTF_8
  149. # Convert string keys to symbols
  150. dest_charset= get_charset(lang)
  151. _verbose_msg {"Reading file #{filename} [charset: #{file_charset} --> #{dest_charset}]"}
  152. symbol_hash = {}
  153. Iconv.open(dest_charset, file_charset) do |i|
  154. raw_hash.each {|key, value|
  155. symbol_hash[key.to_sym] = i.iconv(value)
  156. }
  157. end
  158. # Add strings to repos
  159. _add_localized_strings(lang, symbol_hash, override)
  160. }
  161. _verbose_msg :stats
  162. end
  163. # Restores a backup of GLoc's internal state that was made with backup_state.
  164. def restore_state(state)
  165. _get_internal_state_vars.each do |o|
  166. o.clear
  167. o.send o.respond_to?(:merge!) ? :merge! : :concat, state.shift
  168. end
  169. end
  170. # Sets the charset used to internally store localized strings.
  171. # You can set the charset to use for a specific language or languages,
  172. # or if none are specified the charset for ALL localized strings will be set.
  173. def set_charset(new_charset, *langs)
  174. CONFIG[:internal_charset_per_lang] ||= {}
  175. # Convert symbol shortcuts
  176. if new_charset.is_a?(Symbol)
  177. new_charset= case new_charset
  178. when :utf8, :utf_8 then UTF_8
  179. when :sjis, :shift_jis, :shiftjis then SHIFT_JIS
  180. when :eucjp, :euc_jp then EUC_JP
  181. else new_charset.to_s
  182. end
  183. end
  184. # Convert existing strings
  185. (langs.empty? ? LOCALIZED_STRINGS.keys : langs).each do |lang|
  186. cur_charset= get_charset(lang)
  187. if cur_charset && new_charset != cur_charset
  188. _verbose_msg {"Converting :#{lang} strings from #{cur_charset} to #{new_charset}"}
  189. Iconv.open(new_charset, cur_charset) do |i|
  190. bundle= LOCALIZED_STRINGS[lang]
  191. bundle.each_pair {|k,v| bundle[k]= i.iconv(v)}
  192. end
  193. end
  194. end
  195. # Set new charset value
  196. if langs.empty?
  197. _verbose_msg {"Setting GLoc charset for all languages to #{new_charset}"}
  198. CONFIG[:internal_charset]= new_charset
  199. CONFIG[:internal_charset_per_lang].clear
  200. else
  201. langs.each do |lang|
  202. _verbose_msg {"Setting GLoc charset for :#{lang} strings to #{new_charset}"}
  203. CONFIG[:internal_charset_per_lang][lang]= new_charset
  204. end
  205. end
  206. end
  207. # Sets GLoc configuration values.
  208. def set_config(hash)
  209. CONFIG.merge! hash
  210. end
  211. # Sets the $KCODE global variable according to a specified charset, or else the
  212. # current default charset for the default language.
  213. def set_kcode(charset=nil)
  214. _charset_required
  215. charset ||= get_charset(current_language)
  216. $KCODE= case charset
  217. when UTF_8 then 'u'
  218. when SHIFT_JIS then 's'
  219. when EUC_JP then 'e'
  220. else 'n'
  221. end
  222. _verbose_msg {"$KCODE set to #{$KCODE}"}
  223. end
  224. # Tries to find a valid language that is similar to the argument passed.
  225. # Eg. :en, :en_au, :EN_US are all similar languages.
  226. # Returns <tt>nil</tt> if no similar languages are found.
  227. def similar_language(lang)
  228. return nil if lang.nil?
  229. return lang.to_sym if valid_language?(lang)
  230. # Check lowercase without dashes
  231. lang= lang.to_s.downcase.gsub('-','_')
  232. return LOWERCASE_LANGUAGES[lang] if LOWERCASE_LANGUAGES.has_key?(lang)
  233. # Check without dialect
  234. if lang.to_s =~ /^([a-z]+?)[^a-z].*/
  235. lang= $1
  236. return LOWERCASE_LANGUAGES[lang] if LOWERCASE_LANGUAGES.has_key?(lang)
  237. end
  238. # Check other dialects
  239. lang= "#{lang}_"
  240. LOWERCASE_LANGUAGES.keys.each {|k| return LOWERCASE_LANGUAGES[k] if k.starts_with?(lang)}
  241. # Nothing found
  242. nil
  243. end
  244. # Returns an array of (currently) valid languages (ie. languages for which localized data exists).
  245. def valid_languages
  246. LOCALIZED_STRINGS.keys
  247. end
  248. # Returns <tt>true</tt> if there are any localized strings for a specified language.
  249. # Note that although <tt>set_langauge nil</tt> is perfectly valid, <tt>nil</tt> is not a valid language.
  250. def valid_language?(language)
  251. LOCALIZED_STRINGS.has_key? language.to_sym rescue false
  252. end
  253. end
  254. end