grosser-get_pomo 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
data/vendor/iconv.rb ADDED
@@ -0,0 +1,107 @@
1
+ =begin
2
+ iconv.rb - Pseudo Iconv class. Supports Iconv.iconv, Iconv.conv.
3
+
4
+ For Matz Ruby:
5
+ If you don't have iconv but glib2, this library uses glib2 iconv functions.
6
+
7
+ For JRuby:
8
+ Use Java String class to convert strings.
9
+
10
+ Copyright (C) 2004-2007 Masao Mutoh
11
+
12
+ You may redistribute it and/or modify it under the same
13
+ license terms as Ruby.
14
+
15
+ $Id: iconv.rb,v 1.6 2007/11/08 14:21:22 mutoh Exp $
16
+ =end
17
+
18
+ #Modifications
19
+ #wrapped inside FastGettext namespace to reduce conflic
20
+
21
+ begin
22
+ require 'iconv'
23
+ rescue LoadError
24
+ # Provides Iconv.iconv which normally is provided through Ruby/GLib(1) functions.
25
+ # This library is required for 'gettext'.
26
+ # If you require 'gettext/iconv', it tries to call Ruby/GLib function
27
+ # when it doesn't find original Iconv class(iconv.so) it adds a pseudo class.
28
+ #
29
+ # One-click Ruby Installer for Win32 hadn’t had iconv and there hadn’t been a way to install iconv.so itself for Win32.
30
+ # And JRuby hadn’t had Iconv.
31
+ # I’ve not checked them currently, but if they’ve supported iconv now, we don’t need this anymore...
32
+ #
33
+ # (1) Ruby/GLib is a module which is provided from Ruby-GNOME2 Project.
34
+ # You can get binaries for Win32(One-Click Ruby Installer).
35
+ # <URL: http://ruby-gnome2.sourceforge.jp/>
36
+ module GetPomo
37
+ class Iconv2
38
+ module Failure; end
39
+ class InvalidEncoding < ArgumentError; include Failure; end
40
+ class IllegalSequence < ArgumentError; include Failure; end
41
+ class InvalidCharacter < ArgumentError; include Failure; end
42
+
43
+ if RUBY_PLATFORM =~ /java/
44
+ def self.conv(to, from, str)
45
+ raise InvalidCharacter, "the 3rd argument is nil" unless str
46
+ begin
47
+ str = java.lang.String.new(str.unpack("C*").to_java(:byte), from)
48
+ str.getBytes(to).to_ary.pack("C*")
49
+ rescue java.io.UnsupportedEncodingException
50
+ raise InvalidEncoding
51
+ end
52
+ end
53
+ else
54
+ begin
55
+ require 'glib2'
56
+
57
+ def self.check_glib_version?(major, minor, micro) # :nodoc:
58
+ (GLib::BINDING_VERSION[0] > major ||
59
+ (GLib::BINDING_VERSION[0] == major &&
60
+ GLib::BINDING_VERSION[1] > minor) ||
61
+ (GLib::BINDING_VERSION[0] == major &&
62
+ GLib::BINDING_VERSION[1] == minor &&
63
+ GLib::BINDING_VERSION[2] >= micro))
64
+ end
65
+
66
+ if check_glib_version?(0, 11, 0)
67
+ # This is a function equivalent of Iconv.iconv.
68
+ # * to: encoding name for destination
69
+ # * from: encoding name for source
70
+ # * str: strings to be converted
71
+ # * Returns: Returns an Array of converted strings.
72
+ def self.conv(to, from, str)
73
+ begin
74
+ GLib.convert(str, to, from)
75
+ rescue GLib::ConvertError => e
76
+ case e.code
77
+ when GLib::ConvertError::NO_CONVERSION
78
+ raise InvalidEncoding.new(str)
79
+ when GLib::ConvertError::ILLEGAL_SEQUENCE
80
+ raise IllegalSequence.new(str)
81
+ else
82
+ raise InvalidCharacter.new(str)
83
+ end
84
+ end
85
+ end
86
+ else
87
+ def self.conv(to, from, str) # :nodoc:
88
+ begin
89
+ GLib.convert(str, to, from)
90
+ rescue
91
+ raise IllegalSequence.new(str)
92
+ end
93
+ end
94
+ end
95
+ rescue LoadError
96
+ def self.conv(to, from, str) # :nodoc:
97
+ warn "Iconv was not found." if $DEBUG
98
+ str
99
+ end
100
+ end
101
+ end
102
+ def self.iconv(to, from, str)
103
+ conv(to, from, str).split(//)
104
+ end
105
+ end
106
+ end
107
+ end
data/vendor/mofile.rb ADDED
@@ -0,0 +1,296 @@
1
+ =begin
2
+ mofile.rb - A simple class for operating GNU MO file.
3
+
4
+ Copyright (C) 2003-2008 Masao Mutoh
5
+ Copyright (C) 2002 Masahiro Sakai, Masao Mutoh
6
+ Copyright (C) 2001 Masahiro Sakai
7
+
8
+ Masahiro Sakai <s01397ms at sfc.keio.ac.jp>
9
+ Masao Mutoh <mutoh at highway.ne.jp>
10
+
11
+ You can redistribute this file and/or modify it under the same term
12
+ of Ruby. License of Ruby is included with Ruby distribution in
13
+ the file "README".
14
+
15
+ $Id: mo.rb,v 1.10 2008/06/17 16:40:52 mutoh Exp $
16
+ =end
17
+
18
+ require File.join(File.dirname(__FILE__),'iconv')
19
+ require 'stringio'
20
+
21
+ #Modifications:
22
+ # use Iconv or FastGettext::Icvon
23
+
24
+ module GetPomo
25
+ module GetText
26
+ class MOFile < Hash
27
+ class InvalidFormat < RuntimeError; end;
28
+
29
+ attr_reader :filename
30
+
31
+ Header = Struct.new(:magic,
32
+ :revision,
33
+ :nstrings,
34
+ :orig_table_offset,
35
+ :translated_table_offset,
36
+ :hash_table_size,
37
+ :hash_table_offset)
38
+
39
+ # The following are only used in .mo files
40
+ # with minor revision >= 1.
41
+ class HeaderRev1 < Header
42
+ attr_accessor :n_sysdep_segments,
43
+ :sysdep_segments_offset,
44
+ :n_sysdep_strings,
45
+ :orig_sysdep_tab_offset,
46
+ :trans_sysdep_tab_offset
47
+ end
48
+
49
+ MAGIC_BIG_ENDIAN = "\x95\x04\x12\xde"
50
+ MAGIC_LITTLE_ENDIAN = "\xde\x12\x04\x95"
51
+
52
+ def self.open(arg = nil, output_charset = nil)
53
+ result = self.new(output_charset)
54
+ result.load(arg)
55
+ end
56
+
57
+ def initialize(output_charset = nil)
58
+ @filename = nil
59
+ @last_modified = nil
60
+ @little_endian = true
61
+ @output_charset = output_charset
62
+ super()
63
+ end
64
+
65
+ def update!
66
+ if FileTest.exist?(@filename)
67
+ st = File.stat(@filename)
68
+ load(@filename) unless (@last_modified == [st.ctime, st.mtime])
69
+ else
70
+ warn "#{@filename} was lost." if $DEBUG
71
+ clear
72
+ end
73
+ self
74
+ end
75
+
76
+ def load(arg)
77
+ if arg.kind_of? String
78
+ begin
79
+ st = File.stat(arg)
80
+ @last_modified = [st.ctime, st.mtime]
81
+ rescue Exception
82
+ end
83
+ load_from_file(arg)
84
+ else
85
+ load_from_stream(arg)
86
+ end
87
+ @filename = arg
88
+ self
89
+ end
90
+
91
+ def load_from_stream(io)
92
+ magic = io.read(4)
93
+ case magic
94
+ when MAGIC_BIG_ENDIAN
95
+ @little_endian = false
96
+ when MAGIC_LITTLE_ENDIAN
97
+ @little_endian = true
98
+ else
99
+ raise InvalidFormat.new(sprintf("Unknown signature %s", magic.dump))
100
+ end
101
+
102
+ endian_type6 = @little_endian ? 'V6' : 'N6'
103
+ endian_type_astr = @little_endian ? 'V*' : 'N*'
104
+
105
+ header = HeaderRev1.new(magic, *(io.read(4 * 6).unpack(endian_type6)))
106
+
107
+ if header.revision == 1
108
+ # FIXME: It doesn't support sysdep correctly.
109
+ header.n_sysdep_segments = io.read(4).unpack(endian_type6)
110
+ header.sysdep_segments_offset = io.read(4).unpack(endian_type6)
111
+ header.n_sysdep_strings = io.read(4).unpack(endian_type6)
112
+ header.orig_sysdep_tab_offset = io.read(4).unpack(endian_type6)
113
+ header.trans_sysdep_tab_offset = io.read(4).unpack(endian_type6)
114
+ elsif header.revision > 1
115
+ raise InvalidFormat.new(sprintf("file format revision %d isn't supported", header.revision))
116
+ end
117
+ io.pos = header.orig_table_offset
118
+ orig_table_data = io.read((4 * 2) * header.nstrings).unpack(endian_type_astr)
119
+
120
+ io.pos = header.translated_table_offset
121
+ trans_table_data = io.read((4 * 2) * header.nstrings).unpack(endian_type_astr)
122
+
123
+ original_strings = Array.new(header.nstrings)
124
+ for i in 0...header.nstrings
125
+ io.pos = orig_table_data[i * 2 + 1]
126
+ original_strings[i] = io.read(orig_table_data[i * 2 + 0])
127
+ end
128
+
129
+ clear
130
+ for i in 0...header.nstrings
131
+ io.pos = trans_table_data[i * 2 + 1]
132
+ str = io.read(trans_table_data[i * 2 + 0])
133
+
134
+ if (! original_strings[i]) || original_strings[i] == ""
135
+ if str
136
+ @charset = nil
137
+ @nplurals = nil
138
+ @plural = nil
139
+ str.each_line{|line|
140
+ if /^Content-Type:/i =~ line and /charset=((?:\w|-)+)/i =~ line
141
+ @charset = $1
142
+ elsif /^Plural-Forms:\s*nplurals\s*\=\s*(\d*);\s*plural\s*\=\s*([^;]*)\n?/ =~ line
143
+ @nplurals = $1
144
+ @plural = $2
145
+ end
146
+ break if @charset and @nplurals
147
+ }
148
+ @nplurals = "1" unless @nplurals
149
+ @plural = "0" unless @plural
150
+ end
151
+ else
152
+ if @output_charset
153
+ begin
154
+ iconv = Iconv || FastGettext::Iconv
155
+ str = iconv.conv(@output_charset, @charset, str) if @charset
156
+ rescue iconv::Failure
157
+ if $DEBUG
158
+ warn "@charset = ", @charset
159
+ warn"@output_charset = ", @output_charset
160
+ warn "msgid = ", original_strings[i]
161
+ warn "msgstr = ", str
162
+ end
163
+ end
164
+ end
165
+ end
166
+ self[original_strings[i]] = str.freeze
167
+ end
168
+ self
169
+ end
170
+
171
+ # Is this number a prime number ?
172
+ # http://apidock.com/ruby/Prime
173
+ def prime?(number)
174
+ ('1' * number) !~ /^1?$|^(11+?)\1+$/
175
+ end
176
+
177
+ def next_prime(seed)
178
+ require 'mathn'
179
+ prime = Prime.new
180
+ while current = prime.succ
181
+ return current if current > seed
182
+ end
183
+ end
184
+
185
+ # From gettext-0.12.1/gettext-runtime/intl/hash-string.h
186
+ # Defines the so called `hashpjw' function by P.J. Weinberger
187
+ # [see Aho/Sethi/Ullman, COMPILERS: Principles, Techniques and Tools,
188
+ # 1986, 1987 Bell Telephone Laboratories, Inc.]
189
+ HASHWORDBITS = 32
190
+ def hash_string(str)
191
+ hval = 0
192
+ i = 0
193
+ str.each_byte do |b|
194
+ break if b == '\0'
195
+ hval <<= 4
196
+ hval += b.to_i
197
+ g = hval & (0xf << (HASHWORDBITS - 4))
198
+ if (g != 0)
199
+ hval ^= g >> (HASHWORDBITS - 8)
200
+ hval ^= g
201
+ end
202
+ end
203
+ hval
204
+ end
205
+
206
+ def save_to_stream(io)
207
+ #Save data as little endian format.
208
+ header_size = 4 * 7
209
+ table_size = 4 * 2 * size
210
+
211
+ hash_table_size = next_prime((size * 4) / 3)
212
+ hash_table_size = 3 if hash_table_size <= 2
213
+ header = Header.new(
214
+ MAGIC_LITTLE_ENDIAN, # magic
215
+ 0, # revision
216
+ size, # nstrings
217
+ header_size, # orig_table_offset
218
+ header_size + table_size, # translated_table_offset
219
+ hash_table_size, # hash_table_size
220
+ header_size + table_size * 2 # hash_table_offset
221
+ )
222
+ io.write(header.to_a.pack('a4V*'))
223
+
224
+ ary = to_a
225
+ ary.sort!{|a, b| a[0] <=> b[0]} # sort by original string
226
+
227
+ pos = header.hash_table_size * 4 + header.hash_table_offset
228
+
229
+ orig_table_data = Array.new()
230
+ ary.each{|item, _|
231
+ orig_table_data.push(item.size)
232
+ orig_table_data.push(pos)
233
+ pos += item.size + 1 # +1 is <NUL>
234
+ }
235
+ io.write(orig_table_data.pack('V*'))
236
+
237
+ trans_table_data = Array.new()
238
+ ary.each{|_, item|
239
+ trans_table_data.push(item.size)
240
+ trans_table_data.push(pos)
241
+ pos += item.size + 1 # +1 is <NUL>
242
+ }
243
+ io.write(trans_table_data.pack('V*'))
244
+
245
+ hash_tab = Array.new(hash_table_size)
246
+ j = 0
247
+ ary[0...size].each {|key, _|
248
+ hash_val = hash_string(key)
249
+ idx = hash_val % hash_table_size
250
+ if hash_tab[idx] != nil
251
+ incr = 1 + (hash_val % (hash_table_size - 2))
252
+ begin
253
+ if (idx >= hash_table_size - incr)
254
+ idx -= hash_table_size - incr
255
+ else
256
+ idx += incr
257
+ end
258
+ end until (hash_tab[idx] == nil)
259
+ end
260
+ hash_tab[idx] = j + 1
261
+ j += 1
262
+ }
263
+ hash_tab.collect!{|i| i ? i : 0}
264
+
265
+ io.write(hash_tab.pack('V*'))
266
+
267
+ ary.each{|item, _| io.write(item); io.write("\0") }
268
+ ary.each{|_, item| io.write(item); io.write("\0") }
269
+
270
+ self
271
+ end
272
+
273
+ def load_from_file(filename)
274
+ @filename = filename
275
+ begin
276
+ File.open(filename, 'rb'){|f| load_from_stream(f)}
277
+ rescue => e
278
+ e.set_backtrace("File: #{@filename}")
279
+ raise e
280
+ end
281
+ end
282
+
283
+ def save_to_file(filename)
284
+ File.open(filename, 'wb'){|f| save_to_stream(f)}
285
+ end
286
+
287
+ def set_comment(msgid_or_sym, comment)
288
+ #Do nothing
289
+ end
290
+
291
+
292
+ attr_accessor :little_endian, :path, :last_modified
293
+ attr_reader :charset, :nplurals, :plural
294
+ end
295
+ end
296
+ end
metadata ADDED
@@ -0,0 +1,75 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: grosser-get_pomo
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.6.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Michael Grosser
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2009-11-20 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description:
15
+ email: grosser.michael@gmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files:
19
+ - README.markdown
20
+ files:
21
+ - .gitignore
22
+ - README.markdown
23
+ - Rakefile
24
+ - VERSION
25
+ - get_pomo.gemspec
26
+ - lib/get_pomo.rb
27
+ - lib/get_pomo/mo_file.rb
28
+ - lib/get_pomo/po_file.rb
29
+ - lib/get_pomo/translation.rb
30
+ - prototype_treetop/po.treetop
31
+ - prototype_treetop/test.rb
32
+ - spec/files/complex.mo
33
+ - spec/files/empty.mo
34
+ - spec/files/plural.mo
35
+ - spec/files/singular.mo
36
+ - spec/files/singular_2.mo
37
+ - spec/pomo/mo_file_spec.rb
38
+ - spec/pomo/po_file_spec.rb
39
+ - spec/pomo/translation_spec.rb
40
+ - spec/pomo_spec.rb
41
+ - spec/spec_helper.rb
42
+ - vendor/README.rdoc
43
+ - vendor/iconv.rb
44
+ - vendor/mofile.rb
45
+ homepage: http://github.com/grosser/get_pomo
46
+ licenses: []
47
+ post_install_message:
48
+ rdoc_options:
49
+ - --charset=UTF-8
50
+ require_paths:
51
+ - lib
52
+ required_ruby_version: !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ! '>='
56
+ - !ruby/object:Gem::Version
57
+ version: '0'
58
+ required_rubygems_version: !ruby/object:Gem::Requirement
59
+ none: false
60
+ requirements:
61
+ - - ! '>='
62
+ - !ruby/object:Gem::Version
63
+ version: '0'
64
+ requirements: []
65
+ rubyforge_project:
66
+ rubygems_version: 1.8.24
67
+ signing_key:
68
+ specification_version: 3
69
+ summary: ! 'Ruby/Gettext: A .po and .mo file parser/generator'
70
+ test_files:
71
+ - spec/spec_helper.rb
72
+ - spec/pomo_spec.rb
73
+ - spec/pomo/translation_spec.rb
74
+ - spec/pomo/mo_file_spec.rb
75
+ - spec/pomo/po_file_spec.rb