grosser-fast_gettext 0.2.4 → 0.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.markdown CHANGED
@@ -1,6 +1,6 @@
1
1
  FastGettext
2
2
  ===========
3
- GetText but fast + simple + threadsave!
3
+ GetText but 4 times faster, simple, clean namespace (7 vs 34) and threadsave!
4
4
 
5
5
  Setup
6
6
  =====
@@ -16,7 +16,7 @@ Choose text domain, and locale for translation
16
16
  FastGettext.locale = 'de'
17
17
 
18
18
  Start translating
19
- include FastGettext
19
+ include FastGettext::Translation
20
20
  _('Car') == 'Auto'
21
21
  _('not-found') == 'not-found'
22
22
  s_('Namespace|no-found') == 'not-found'
@@ -24,24 +24,34 @@ Start translating
24
24
 
25
25
  Speed
26
26
  =====
27
- FastGettext
28
- small:
29
- 1.000000 0.130000 1.130000 ( 1.132578)
30
- mapped: 8620K writeable/private: 5588K shared: 28K
27
+ 50_000 translations:
28
+ Ideal: (primitive Hash lookup)
29
+ small translation file:
30
+ 1.100000 0.180000 1.280000 ( 1.287230)
31
+ mapped: 5832K writeable/private: 3016K shared: 28K
32
+
33
+ large translation file:
34
+ 1.150000 0.150000 1.300000 ( 1.296114)
35
+ mapped: 5832K writeable/private: 3016K shared: 28K
36
+
37
+ FastGettext:
38
+ small translation file:
39
+ 3.980000 0.430000 4.410000 ( 4.407260)
40
+ mapped: 5852K writeable/private: 3036K shared: 28K
31
41
 
32
- large:
33
- 1.060000 0.100000 1.160000 ( 1.163962)
34
- mapped: 8620K writeable/private: 5588K shared: 28K
42
+ large translation file:
43
+ 4.070000 0.450000 4.520000 ( 4.515585)
44
+ mapped: 5972K writeable/private: 3156K shared: 28K
35
45
 
46
+ GetText:
47
+ small translation file:
48
+ 16.280000 1.340000 17.620000 ( 17.630391)
49
+ mapped: 8976K writeable/private: 5944K shared: 28K
36
50
 
37
- GetText
38
- small:
39
- 3.220000 0.260000 3.480000 ( 3.478093)
40
- mapped: 9036K writeable/private: 6004K shared: 28K
51
+ large translation file:
52
+ 16.590000 1.430000 18.020000 ( 18.042926)
53
+ mapped: 9024K writeable/private: 5992K shared: 28K
41
54
 
42
- large:
43
- 3.280000 0.230000 3.510000 ( 3.511891)
44
- mapped: 9156K writeable/private: 6124K shared: 28K
45
55
 
46
56
 
47
57
  Thread Safety and Rails
@@ -59,7 +69,7 @@ then e.g. controllers, so set them inside your application_controller.
59
69
 
60
70
  #application_controller.rb
61
71
  class ApplicationController ...
62
- include FastGettext
72
+ include FastGettext::Translation
63
73
  before_filter :set_locale
64
74
  def set_locale
65
75
  FastGettext.available_locales = ['de','en',...]
@@ -69,7 +79,7 @@ then e.g. controllers, so set them inside your application_controller.
69
79
 
70
80
  #application_helper.rb
71
81
  module ApplicationHelper
72
- include FastGettext
82
+ include FastGettext::Translation
73
83
  ...
74
84
 
75
85
  Try the [gettext_i18n_rails plugin](http://github.com/grosser/gettext_i18n_rails), it simplifies the setup.
data/VERSION.yml CHANGED
@@ -1,4 +1,4 @@
1
1
  ---
2
2
  :minor: 2
3
- :patch: 4
3
+ :patch: 5
4
4
  :major: 0
data/lib/fast_gettext.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'fast_gettext/mo_file'
2
2
  require 'fast_gettext/storage'
3
+ require 'fast_gettext/translation'
3
4
  require File.join(File.dirname(__FILE__),'..','vendor','string')
4
5
 
5
6
  module FastGettext
@@ -13,39 +14,18 @@ module FastGettext
13
14
  LOCALE_REX = /^[a-z]{2}$|^[a-z]{2}_[A-Z]{2}$/
14
15
  NAMESPACE_SEPERATOR = '|'
15
16
 
16
- def _(translate)
17
- current_mo[translate] || translate
18
- end
19
-
20
- #translate pluralized
21
- def n_(singular,plural,count)
22
- if translation = current_mo.plural(singular,plural,count)
23
- translation
24
- else
25
- count > 1 ? plural : singular
26
- end
27
- end
28
-
29
- #translate, but discard namespace if nothing was found
30
- # Car|Tire -> Tire if no translation could be found
31
- def s_(translate,seperator=nil)
32
- if translation = current_mo[translate]
33
- translation
34
- else
35
- translate.split(seperator||NAMESPACE_SEPERATOR).last
17
+ # users should not include FastGettext, since this would conterminate their namespace
18
+ # rather use
19
+ # FastGettext.locale = ..
20
+ # FastGettext.text_domain = ..
21
+ # and
22
+ # include FastGettext::Translation
23
+ FastGettext::Translation.public_instance_methods.each do |method|
24
+ define_method method do |*args|
25
+ Translation.send(method,*args)
36
26
  end
37
27
  end
38
28
 
39
- #tell gettext: this string need translation (will be found during parsing)
40
- def N_(translate)
41
- translate
42
- end
43
-
44
- #tell gettext: this string need translation (will be found during parsing)
45
- def Nn_(singular,plural)
46
- [singular,plural]
47
- end
48
-
49
29
  def add_text_domain(name,options)
50
30
  self.text_domains ||= {}
51
31
  domain = self.text_domains[name] = {:path=>options.delete(:path),:mo_files=>{}}
@@ -60,12 +40,4 @@ module FastGettext
60
40
  end
61
41
  domain
62
42
  end
63
-
64
- private
65
-
66
- #TODO geht nicht <-> {}.plural
67
- def current_mo
68
- mo = text_domains[text_domain][:mo_files][locale] rescue nil
69
- mo || {}
70
- end
71
43
  end
@@ -1,6 +1,6 @@
1
1
  module FastGettext
2
2
  module Storage
3
- [:text_domain,:available_locales].each do |method|
3
+ [:current_translations,:available_locales].each do |method|
4
4
  define_method method do
5
5
  thread_store(method)
6
6
  end
@@ -9,21 +9,39 @@ module FastGettext
9
9
  end
10
10
  end
11
11
 
12
+ #global, since re-parsing whole folders takes too much time...
12
13
  @@text_domains={}
13
14
  def text_domains
14
15
  @@text_domains
15
16
  end
16
17
 
18
+ def text_domain
19
+ thread_store(:text_domain)
20
+ end
21
+
22
+ def text_domain=(new_text_domain)
23
+ write_thread_store(:text_domain,new_text_domain)
24
+ update_current_translations
25
+ end
26
+
17
27
  def locale
18
28
  thread_store(:locale) || (available_locales||[]).first || 'en'
19
29
  end
20
30
 
21
- def locale=(value)
22
- write_thread_store(:locale,value) if not available_locales or available_locales.include?(value)
31
+ def locale=(new_locale)
32
+ new_locale = new_locale.to_s
33
+ if not available_locales or available_locales.include?(new_locale)
34
+ write_thread_store(:locale,new_locale)
35
+ update_current_translations
36
+ end
23
37
  end
24
38
 
25
39
  private
26
40
 
41
+ def update_current_translations
42
+ self.current_translations = text_domains[text_domain][:mo_files][locale] || {} if text_domains[text_domain]
43
+ end
44
+
27
45
  def thread_store(key)
28
46
  Thread.current["FastGettext.#{key}"]
29
47
  end
@@ -0,0 +1,38 @@
1
+ module FastGettext
2
+ module Translation
3
+ extend self
4
+
5
+ def _(translate)
6
+ FastGettext.current_translations[translate] || translate
7
+ end
8
+
9
+ #translate pluralized
10
+ def n_(singular,plural,count)
11
+ if translation = FastGettext.current_translations.plural(singular,plural,count)
12
+ translation
13
+ else
14
+ count > 1 ? plural : singular
15
+ end
16
+ end
17
+
18
+ #translate, but discard namespace if nothing was found
19
+ # Car|Tire -> Tire if no translation could be found
20
+ def s_(translate,seperator=nil)
21
+ if translation = FastGettext.current_translations[translate]
22
+ translation
23
+ else
24
+ translate.split(seperator||NAMESPACE_SEPERATOR).last
25
+ end
26
+ end
27
+
28
+ #tell gettext: this string need translation (will be found during parsing)
29
+ def N_(translate)
30
+ translate
31
+ end
32
+
33
+ #tell gettext: this string need translation (will be found during parsing)
34
+ def Nn_(singular,plural)
35
+ [singular,plural]
36
+ end
37
+ end
38
+ end
@@ -15,7 +15,7 @@ describe Storage do
15
15
  send(method) == 'de'
16
16
  end
17
17
 
18
- [:locale, :available_locales, :text_domain].each do |method|
18
+ [:locale, :available_locales, :text_domain, :current_translations].each do |method|
19
19
  it "stores #{method} thread-save" do
20
20
  thread_save(method).should == true
21
21
  end
@@ -0,0 +1,55 @@
1
+ current_folder = File.dirname(__FILE__)
2
+ require File.join(current_folder,'..','spec_helper')
3
+
4
+ FastGettext.add_text_domain('test',:path=>File.join(File.dirname(__FILE__),'..','locale'))
5
+ FastGettext.text_domain = 'test'
6
+ FastGettext.available_locales = ['en','de']
7
+ FastGettext.locale = 'de'
8
+
9
+ include FastGettext::Translation
10
+
11
+ describe FastGettext::Translation do
12
+ describe :_ do
13
+ it "translates simple text" do
14
+ _('car').should == 'Auto'
15
+ end
16
+ it "returns msgid if not translation was found" do
17
+ _('NOT|FOUND').should == 'NOT|FOUND'
18
+ end
19
+ end
20
+
21
+ describe :n_ do
22
+ it "translates pluralized" do
23
+ n_('Axis','Axis',1).should == 'Achse'
24
+ n_('Axis','Axis',2).should == 'Achsen'
25
+ end
26
+ it "returns the appropriate msgid if no translation was found" do
27
+ n_('NOTFOUND','NOTFOUNDs',1).should == 'NOTFOUND'
28
+ n_('NOTFOUND','NOTFOUNDs',2).should == 'NOTFOUNDs'
29
+ end
30
+ end
31
+
32
+ describe :s_ do
33
+ it "translates simple text" do
34
+ _('car').should == 'Auto'
35
+ end
36
+ it "returns cleaned msgid if a translation was not found" do
37
+ s_("XXX|not found").should == "not found"
38
+ end
39
+ it "can use a custom seperator" do
40
+ s_("XXX/not found",'/').should == "not found"
41
+ end
42
+ end
43
+
44
+ describe :N_ do
45
+ it "returns the msgid" do
46
+ N_('XXXXX').should == 'XXXXX'
47
+ end
48
+ end
49
+
50
+ describe :Nn_ do
51
+ it "returns the msgids as array" do
52
+ Nn_('X','Y').should == ['X','Y']
53
+ end
54
+ end
55
+ end
@@ -1,6 +1,5 @@
1
1
  require File.expand_path("spec_helper", File.dirname(__FILE__))
2
2
 
3
- include FastGettext
4
3
  FastGettext.add_text_domain('test',:path=>File.join(File.dirname(__FILE__),'locale'))
5
4
  FastGettext.text_domain = 'test'
6
5
  FastGettext.available_locales = ['en','de']
@@ -9,47 +8,11 @@ FastGettext.locale = 'de'
9
8
  include FastGettext
10
9
 
11
10
  describe FastGettext do
12
- describe :_ do
13
- it "translates simple text" do
14
- _('car').should == 'Auto'
15
- end
16
- it "returns msgid if not translation was found" do
17
- _('NOT|FOUND').should == 'NOT|FOUND'
18
- end
19
- end
20
-
21
- describe :n_ do
22
- it "translates pluralized" do
23
- n_('Axis','Axis',1).should == 'Achse'
24
- n_('Axis','Axis',2).should == 'Achsen'
25
- end
26
- it "returns the appropriate msgid if no translation was found" do
27
- n_('NOTFOUND','NOTFOUNDs',1).should == 'NOTFOUND'
28
- n_('NOTFOUND','NOTFOUNDs',2).should == 'NOTFOUNDs'
29
- end
30
- end
31
-
32
- describe :s_ do
33
- it "translates simple text" do
34
- _('car').should == 'Auto'
35
- end
36
- it "returns cleaned msgid if a translation was not found" do
37
- s_("XXX|not found").should == "not found"
38
- end
39
- it "can use a custom seperator" do
40
- s_("XXX/not found",'/').should == "not found"
41
- end
42
- end
43
-
44
- describe :N_ do
45
- it "returns the msgid" do
46
- N_('XXXXX').should == 'XXXXX'
47
- end
48
- end
49
-
50
- describe :Nn_ do
51
- it "returns the msgids as array" do
52
- Nn_('X','Y').should == ['X','Y']
53
- end
11
+ it "provides access to FastGettext::Translations methods" do
12
+ _('car').should == 'Auto'
13
+ s_("XXX|not found").should == "not found"
14
+ n_('Axis','Axis',1).should == 'Achse'
15
+ N_('XXXXX').should == 'XXXXX'
16
+ Nn_('X','Y').should == ['X','Y']
54
17
  end
55
18
  end
@@ -0,0 +1,2 @@
1
+ #simulate file not found
2
+ raise LoadError
@@ -0,0 +1,27 @@
1
+ current_folder = File.dirname(__FILE__)
2
+ $LOAD_PATH.unshift File.expand_path("../../lib", current_folder)
3
+
4
+ describe 'Iconv' do
5
+ it "also works when Iconv was not found locally" do
6
+ #prepare load path
7
+ $LOAD_PATH.unshift File.join(current_folder,'fake_load_path')
8
+ test = 1
9
+ begin
10
+ require 'iconv'
11
+ rescue LoadError
12
+ test = 2
13
+ end
14
+ test.should == 2
15
+
16
+ #load fast_gettext
17
+ require 'fast_gettext'
18
+
19
+ FastGettext.add_text_domain('test',:path=>File.join(File.dirname(__FILE__),'..','locale'))
20
+ FastGettext.text_domain = 'test'
21
+ FastGettext.available_locales = ['en','de']
22
+ FastGettext.locale = 'de'
23
+
24
+ #translate
25
+ FastGettext._('car').should == 'Auto'
26
+ end
27
+ end
data/vendor/iconv.rb CHANGED
@@ -15,8 +15,11 @@
15
15
  $Id: iconv.rb,v 1.6 2007/11/08 14:21:22 mutoh Exp $
16
16
  =end
17
17
 
18
+ #Modifications
19
+ #wrapped inside FastGettext namespace to reduce conflic
20
+
18
21
  begin
19
- require 'iconv.so'
22
+ require 'iconv'
20
23
  rescue LoadError
21
24
  # Pseudo Iconv class
22
25
  #
@@ -27,73 +30,75 @@ rescue LoadError
27
30
  # (1) Ruby/GLib is a module which is provided from Ruby-GNOME2 Project.
28
31
  # You can get binaries for Win32(One-Click Ruby Installer).
29
32
  # <URL: http://ruby-gnome2.sourceforge.jp/>
30
- class Iconv
31
- module Failure; end
32
- class InvalidEncoding < ArgumentError; include Failure; end
33
- class IllegalSequence < ArgumentError; include Failure; end
34
- class InvalidCharacter < ArgumentError; include Failure; end
33
+ module FastGettext
34
+ class Iconv2
35
+ module Failure; end
36
+ class InvalidEncoding < ArgumentError; include Failure; end
37
+ class IllegalSequence < ArgumentError; include Failure; end
38
+ class InvalidCharacter < ArgumentError; include Failure; end
35
39
 
36
- if RUBY_PLATFORM =~ /java/
37
- def self.conv(to, from, str)
38
- raise InvalidCharacter, "the 3rd argument is nil" unless str
39
- begin
40
- str = java.lang.String.new(str.unpack("C*").to_java(:byte), from)
41
- str.getBytes(to).to_ary.pack("C*")
42
- rescue java.io.UnsupportedEncodingException
43
- raise InvalidEncoding
44
- end
45
- end
46
- else
47
- begin
48
- require 'glib2'
49
-
50
- def self.check_glib_version?(major, minor, micro) # :nodoc:
51
- (GLib::BINDING_VERSION[0] > major ||
52
- (GLib::BINDING_VERSION[0] == major &&
53
- GLib::BINDING_VERSION[1] > minor) ||
54
- (GLib::BINDING_VERSION[0] == major &&
55
- GLib::BINDING_VERSION[1] == minor &&
56
- GLib::BINDING_VERSION[2] >= micro))
40
+ if RUBY_PLATFORM =~ /java/
41
+ def self.conv(to, from, str)
42
+ raise InvalidCharacter, "the 3rd argument is nil" unless str
43
+ begin
44
+ str = java.lang.String.new(str.unpack("C*").to_java(:byte), from)
45
+ str.getBytes(to).to_ary.pack("C*")
46
+ rescue java.io.UnsupportedEncodingException
47
+ raise InvalidEncoding
48
+ end
57
49
  end
58
-
59
- if check_glib_version?(0, 11, 0)
60
- # This is a function equivalent of Iconv.iconv.
61
- # * to: encoding name for destination
62
- # * from: encoding name for source
63
- # * str: strings to be converted
64
- # * Returns: Returns an Array of converted strings.
65
- def self.conv(to, from, str)
66
- begin
67
- GLib.convert(str, to, from)
68
- rescue GLib::ConvertError => e
69
- case e.code
70
- when GLib::ConvertError::NO_CONVERSION
71
- raise InvalidEncoding.new(str)
72
- when GLib::ConvertError::ILLEGAL_SEQUENCE
50
+ else
51
+ begin
52
+ require 'glib2'
53
+
54
+ def self.check_glib_version?(major, minor, micro) # :nodoc:
55
+ (GLib::BINDING_VERSION[0] > major ||
56
+ (GLib::BINDING_VERSION[0] == major &&
57
+ GLib::BINDING_VERSION[1] > minor) ||
58
+ (GLib::BINDING_VERSION[0] == major &&
59
+ GLib::BINDING_VERSION[1] == minor &&
60
+ GLib::BINDING_VERSION[2] >= micro))
61
+ end
62
+
63
+ if check_glib_version?(0, 11, 0)
64
+ # This is a function equivalent of Iconv.iconv.
65
+ # * to: encoding name for destination
66
+ # * from: encoding name for source
67
+ # * str: strings to be converted
68
+ # * Returns: Returns an Array of converted strings.
69
+ def self.conv(to, from, str)
70
+ begin
71
+ GLib.convert(str, to, from)
72
+ rescue GLib::ConvertError => e
73
+ case e.code
74
+ when GLib::ConvertError::NO_CONVERSION
75
+ raise InvalidEncoding.new(str)
76
+ when GLib::ConvertError::ILLEGAL_SEQUENCE
77
+ raise IllegalSequence.new(str)
78
+ else
79
+ raise InvalidCharacter.new(str)
80
+ end
81
+ end
82
+ end
83
+ else
84
+ def self.conv(to, from, str) # :nodoc:
85
+ begin
86
+ GLib.convert(str, to, from)
87
+ rescue
73
88
  raise IllegalSequence.new(str)
74
- else
75
- raise InvalidCharacter.new(str)
76
89
  end
77
90
  end
78
91
  end
79
- else
92
+ rescue LoadError
80
93
  def self.conv(to, from, str) # :nodoc:
81
- begin
82
- GLib.convert(str, to, from)
83
- rescue
84
- raise IllegalSequence.new(str)
85
- end
94
+ warn "Iconv was not found." if $DEBUG
95
+ str
86
96
  end
87
97
  end
88
- rescue LoadError
89
- def self.conv(to, from, str) # :nodoc:
90
- warn "Iconv was not found." if $DEBUG
91
- str
92
- end
93
98
  end
94
- end
95
- def self.iconv(to, from, str)
96
- conv(to, from, str).split(//)
99
+ def self.iconv(to, from, str)
100
+ conv(to, from, str).split(//)
101
+ end
97
102
  end
98
103
  end
99
104
  end
data/vendor/mofile.rb CHANGED
@@ -18,6 +18,9 @@
18
18
  require 'iconv'
19
19
  require 'stringio'
20
20
 
21
+ #Modifications:
22
+ # use Iconv or FastGettext::Icvon
23
+
21
24
  module FastGettext
22
25
  module GetText
23
26
  class MOFile < Hash
@@ -148,8 +151,9 @@ module FastGettext
148
151
  else
149
152
  if @output_charset
150
153
  begin
151
- str = Iconv.conv(@output_charset, @charset, str) if @charset
152
- rescue Iconv::Failure
154
+ iconv = Iconv || FastGettext::Iconv
155
+ str = iconv.conv(@output_charset, @charset, str) if @charset
156
+ rescue iconv::Failure
153
157
  if $DEBUG
154
158
  warn "@charset = ", @charset
155
159
  warn"@output_charset = ", @output_charset
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: grosser-fast_gettext
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Grosser
@@ -28,6 +28,7 @@ files:
28
28
  - vendor/README.rdoc
29
29
  - lib/fast_gettext.rb
30
30
  - lib/fast_gettext
31
+ - lib/fast_gettext/translation.rb
31
32
  - lib/fast_gettext/storage.rb
32
33
  - lib/fast_gettext/mo_file.rb
33
34
  - spec/fast_gettext_spec.rb
@@ -40,9 +41,13 @@ files:
40
41
  - spec/locale/de/LC_MESSAGES
41
42
  - spec/locale/de/LC_MESSAGES/test.mo
42
43
  - spec/fast_gettext
44
+ - spec/fast_gettext/translation_spec.rb
43
45
  - spec/fast_gettext/storage_spec.rb
44
46
  - spec/fast_gettext/mo_file_spec.rb
45
47
  - spec/vendor
48
+ - spec/vendor/iconv_spec.rb
49
+ - spec/vendor/fake_load_path
50
+ - spec/vendor/fake_load_path/iconv.rb
46
51
  - spec/vendor/string_spec.rb
47
52
  - VERSION.yml
48
53
  - README.markdown