aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/gems/gettext-2.1.0/lib/gettext/tools
diff options
context:
space:
mode:
authorRobin Houston <robin@lenny.robin>2011-06-09 12:54:05 +0100
committerRobin Houston <robin@lenny.robin>2011-06-09 12:54:05 +0100
commit4d077dc48fb0589dbf401a131d524b23ab0d2258 (patch)
tree680b12febc448827ee937039d38e97020b4c5df9 /vendor/gems/gettext-2.1.0/lib/gettext/tools
parentcb67f4d0ef9feae96a90ea5bba63c939268b1224 (diff)
Bundle the locale and gettext gems
Diffstat (limited to 'vendor/gems/gettext-2.1.0/lib/gettext/tools')
-rw-r--r--vendor/gems/gettext-2.1.0/lib/gettext/tools/parser/erb.rb52
-rw-r--r--vendor/gems/gettext-2.1.0/lib/gettext/tools/parser/glade.rb98
-rw-r--r--vendor/gems/gettext-2.1.0/lib/gettext/tools/parser/ruby.rb226
-rw-r--r--vendor/gems/gettext-2.1.0/lib/gettext/tools/pomessage.rb197
-rw-r--r--vendor/gems/gettext-2.1.0/lib/gettext/tools/poparser.rb356
-rw-r--r--vendor/gems/gettext-2.1.0/lib/gettext/tools/rgettext.rb226
-rw-r--r--vendor/gems/gettext-2.1.0/lib/gettext/tools/rmsgfmt.rb84
-rw-r--r--vendor/gems/gettext-2.1.0/lib/gettext/tools/rmsgmerge.rb498
8 files changed, 1737 insertions, 0 deletions
diff --git a/vendor/gems/gettext-2.1.0/lib/gettext/tools/parser/erb.rb b/vendor/gems/gettext-2.1.0/lib/gettext/tools/parser/erb.rb
new file mode 100644
index 000000000..0aee9d461
--- /dev/null
+++ b/vendor/gems/gettext-2.1.0/lib/gettext/tools/parser/erb.rb
@@ -0,0 +1,52 @@
+=begin
+ parser/erb.rb - parser for ERB
+
+ Copyright (C) 2005-2009 Masao Mutoh
+
+ You may redistribute it and/or modify it under the same
+ license terms as Ruby or LGPL.
+=end
+
+require 'erb'
+require 'gettext/tools/parser/ruby'
+
+module GetText
+ module ErbParser
+ extend self
+
+ @config = {
+ :extnames => ['.rhtml', '.erb']
+ }
+
+ # Sets some preferences to parse ERB files.
+ # * config: a Hash of the config. It can takes some values below:
+ # * :extnames: An Array of target files extension. Default is [".rhtml"].
+ def init(config)
+ config.each{|k, v|
+ @config[k] = v
+ }
+ end
+
+ def parse(file, targets = []) # :nodoc:
+ src = ERB.new(IO.readlines(file).join).src
+ # Remove magic comment prepended by erb in Ruby 1.9.
+ src.sub!(/\A#.*?coding[:=].*?\n/, '') if src.respond_to?(:encode)
+ erb = src.split(/$/)
+ RubyParser.parse_lines(file, erb, targets)
+ end
+
+ def target?(file) # :nodoc:
+ @config[:extnames].each do |v|
+ return true if File.extname(file) == v
+ end
+ false
+ end
+ end
+end
+
+if __FILE__ == $0
+ # ex) ruby glade.rhtml foo.rhtml bar.rhtml
+ ARGV.each do |file|
+ p GetText::ErbParser.parse(file)
+ end
+end
diff --git a/vendor/gems/gettext-2.1.0/lib/gettext/tools/parser/glade.rb b/vendor/gems/gettext-2.1.0/lib/gettext/tools/parser/glade.rb
new file mode 100644
index 000000000..ab77beede
--- /dev/null
+++ b/vendor/gems/gettext-2.1.0/lib/gettext/tools/parser/glade.rb
@@ -0,0 +1,98 @@
+=begin
+ parser/glade.rb - parser for Glade-2
+
+ Copyright (C) 2004,2005 Masao Mutoh
+
+ You may redistribute it and/or modify it under the same
+ license terms as Ruby or LGPL.
+=end
+
+require 'cgi'
+require 'gettext'
+
+module GetText
+ module GladeParser
+ extend GetText
+ extend self
+
+ bindtextdomain("rgettext")
+
+ TARGET1 = /<property.*translatable="yes">(.*)/
+ TARGET2 = /(.*)<\/property>/
+
+ def parse(file, targets = []) # :nodoc:
+ lines = IO.readlines(file)
+ parse_lines(file, lines, targets)
+ end
+
+ #from ary of lines.
+ def parse_lines(file, lines, targets) # :nodoc:
+ cnt = 0
+ target = false
+ line_no = 0
+ val = nil
+
+ loop do
+ line = lines.shift
+ break unless line
+
+ cnt += 1
+ if TARGET1 =~ line
+ line_no = cnt
+ val = $1 + "\n"
+ target = true
+ if TARGET2 =~ $1
+ val = $1
+ add_target(val, file, line_no, targets)
+ val = nil
+ target = false
+ end
+ elsif target
+ if TARGET2 =~ line
+ val << $1
+ add_target(val, file, line_no, targets)
+ val = nil
+ target = false
+ else
+ val << line
+ end
+ end
+ end
+ targets
+ end
+
+ XML_RE = /<\?xml/
+ GLADE_RE = /glade-2.0.dtd/
+
+ def target?(file) # :nodoc:
+ data = IO.readlines(file)
+ if XML_RE =~ data[0] and GLADE_RE =~ data[1]
+ true
+ else
+ if File.extname(file) == '.glade'
+ raise _("`%{file}' is not glade-2.0 format.") % {:file => file}
+ end
+ false
+ end
+ end
+
+ def add_target(val, file, line_no, targets) # :nodoc:
+ return unless val.size > 0
+ assoc_data = targets.assoc(val)
+ val = CGI.unescapeHTML(val)
+ if assoc_data
+ targets[targets.index(assoc_data)] = assoc_data << "#{file}:#{line_no}"
+ else
+ targets << [val.gsub(/\n/, '\n'), "#{file}:#{line_no}"]
+ end
+ targets
+ end
+ end
+end
+
+if __FILE__ == $0
+ # ex) ruby glade.rb foo.glade bar.glade
+ ARGV.each do |file|
+ p GetText::GladeParser.parse(file)
+ end
+end
diff --git a/vendor/gems/gettext-2.1.0/lib/gettext/tools/parser/ruby.rb b/vendor/gems/gettext-2.1.0/lib/gettext/tools/parser/ruby.rb
new file mode 100644
index 000000000..9d16401ce
--- /dev/null
+++ b/vendor/gems/gettext-2.1.0/lib/gettext/tools/parser/ruby.rb
@@ -0,0 +1,226 @@
+#!/usr/bin/ruby
+=begin
+ parser/ruby.rb - parser for ruby script
+
+ Copyright (C) 2003-2009 Masao Mutoh
+ Copyright (C) 2005 speakillof
+ Copyright (C) 2001,2002 Yasushi Shoji, Masao Mutoh
+
+ You may redistribute it and/or modify it under the same
+ license terms as Ruby or LGPL.
+
+=end
+
+require 'irb/ruby-lex.rb'
+require 'stringio'
+require 'gettext/tools/pomessage'
+
+module GetText
+ class RubyLexX < RubyLex # :nodoc: all
+ # Parser#parse resemlbes RubyLex#lex
+ def parse
+ until ( (tk = token).kind_of?(RubyToken::TkEND_OF_SCRIPT) && !@continue or tk.nil? )
+ s = get_readed
+ if RubyToken::TkSTRING === tk
+ def tk.value
+ @value
+ end
+
+ def tk.value=(s)
+ @value = s
+ end
+
+ if @here_header
+ s = s.sub(/\A.*?\n/, '').sub(/^.*\n\Z/, '')
+ else
+ begin
+ s = eval(s)
+ rescue Exception
+ # Do nothing.
+ end
+ end
+
+ tk.value = s
+ end
+
+ if $DEBUG
+ if tk.is_a? TkSTRING
+ $stderr.puts("#{tk}: #{tk.value}")
+ elsif tk.is_a? TkIDENTIFIER
+ $stderr.puts("#{tk}: #{tk.name}")
+ else
+ $stderr.puts(tk)
+ end
+ end
+
+ yield tk
+ end
+ return nil
+ end
+
+ # Original parser does not keep the content of the comments,
+ # so monkey patching this with new token type and extended
+ # identify_comment implementation
+ RubyToken.def_token :TkCOMMENT_WITH_CONTENT, TkVal
+
+ def identify_comment
+ @ltype = "#"
+ get_readed # skip the hash sign itself
+
+ while ch = getc
+ if ch == "\n"
+ @ltype = nil
+ ungetc
+ break
+ end
+ end
+ return Token(TkCOMMENT_WITH_CONTENT, get_readed)
+ end
+
+ end
+
+ # Extends PoMessage for RubyParser.
+ # Implements a sort of state machine to assist the parser.
+ module PoMessageForRubyParser
+ # Supports parsing by setting attributes by and by.
+ def set_current_attribute(str)
+ param = @param_type[@param_number]
+ raise ParseError, 'no more string parameters expected' unless param
+ set_value(param, str)
+ end
+
+ def init_param
+ @param_number = 0
+ self
+ end
+
+ def advance_to_next_attribute
+ @param_number += 1
+ end
+ end
+ class PoMessage
+ include PoMessageForRubyParser
+ alias :initialize_old :initialize
+ def initialize(type)
+ initialize_old(type)
+ init_param
+ end
+ end
+
+ module RubyParser
+ extend self
+
+ ID = ['gettext', '_', 'N_', 'sgettext', 's_']
+ PLURAL_ID = ['ngettext', 'n_', 'Nn_', 'ns_', 'nsgettext']
+ MSGCTXT_ID = ['pgettext', 'p_']
+ MSGCTXT_PLURAL_ID = ['npgettext', 'np_']
+
+ # (Since 2.1.0) the 2nd parameter is deprecated
+ # (and ignored here).
+ # And You don't need to keep the pomessages as unique.
+
+ def parse(path, deprecated = []) # :nodoc:
+ lines = IO.readlines(path)
+ parse_lines(path, lines, deprecated)
+ end
+
+ def parse_lines(path, lines, deprecated = []) # :nodoc:
+ pomessages = deprecated
+ file = StringIO.new(lines.join + "\n")
+ rl = RubyLexX.new
+ rl.set_input(file)
+ rl.skip_space = true
+ #rl.readed_auto_clean_up = true
+
+ pomessage = nil
+ line_no = nil
+ last_comment = ''
+ reset_comment = false
+ rl.parse do |tk|
+ begin
+ case tk
+ when RubyToken::TkIDENTIFIER, RubyToken::TkCONSTANT
+ store_pomessage(pomessages, pomessage, path, line_no, last_comment)
+ if ID.include?(tk.name)
+ pomessage = PoMessage.new(:normal)
+ elsif PLURAL_ID.include?(tk.name)
+ pomessage = PoMessage.new(:plural)
+ elsif MSGCTXT_ID.include?(tk.name)
+ pomessage = PoMessage.new(:msgctxt)
+ elsif MSGCTXT_PLURAL_ID.include?(tk.name)
+ pomessage = PoMessage.new(:msgctxt_plural)
+ else
+ pomessage = nil
+ end
+ line_no = tk.line_no.to_s
+ when RubyToken::TkSTRING
+ pomessage.set_current_attribute tk.value if pomessage
+ when RubyToken::TkPLUS, RubyToken::TkNL
+ #do nothing
+ when RubyToken::TkCOMMA
+ pomessage.advance_to_next_attribute if pomessage
+ else
+ if store_pomessage(pomessages, pomessage, path, line_no, last_comment)
+ pomessage = nil
+ end
+ end
+ rescue
+ $stderr.print "\n\nError"
+ $stderr.print " parsing #{path}:#{tk.line_no}\n\t #{lines[tk.line_no - 1]}" if tk
+ $stderr.print "\n #{$!.inspect} in\n"
+ $stderr.print $!.backtrace.join("\n")
+ $stderr.print "\n"
+ exit 1
+ end
+
+ case tk
+ when RubyToken::TkCOMMENT_WITH_CONTENT
+ last_comment = "" if reset_comment
+ if last_comment.empty?
+ # new comment from programmer to translator?
+ comment1 = tk.value.lstrip
+ if comment1 =~ /^TRANSLATORS\:/
+ last_comment = $'
+ end
+ else
+ last_comment += "\n"
+ last_comment += tk.value
+ end
+ reset_comment = false
+ when RubyToken::TkNL
+ else
+ reset_comment = true
+ end
+ end
+ pomessages
+ end
+
+ def target?(file) # :nodoc:
+ true # always true, as the default parser.
+ end
+
+ private
+ def store_pomessage(pomessages, pomessage, file_name, line_no, last_comment) #:nodoc:
+ if pomessage && pomessage.msgid
+ pomessage.sources << file_name + ":" + line_no
+ pomessage.add_comment(last_comment) unless last_comment.empty?
+ pomessages << pomessage
+ true
+ else
+ false
+ end
+ end
+ end
+end
+
+if __FILE__ == $0
+ require 'pp'
+ ARGV.each do |path|
+ pp GetText::RubyParser.parse(path)
+ end
+
+ #rl = GetText::RubyLexX.new; rl.set_input(ARGF)
+ #rl.parse do |tk|
+ #p tk
+ #end
+end
diff --git a/vendor/gems/gettext-2.1.0/lib/gettext/tools/pomessage.rb b/vendor/gems/gettext-2.1.0/lib/gettext/tools/pomessage.rb
new file mode 100644
index 000000000..b5efe7221
--- /dev/null
+++ b/vendor/gems/gettext-2.1.0/lib/gettext/tools/pomessage.rb
@@ -0,0 +1,197 @@
+module GetText
+ class ParseError < StandardError
+ end
+
+ # Contains data related to the expression or sentence that
+ # is to be translated.
+ class PoMessage
+ PARAMS = {
+ :normal => [:msgid],
+ :plural => [:msgid, :msgid_plural],
+ :msgctxt => [:msgctxt, :msgid],
+ :msgctxt_plural => [:msgctxt, :msgid, :msgid_plural]
+ }
+
+ @@max_line_length = 70
+
+ # Sets the max line length.
+ def self.max_line_length=(len)
+ @@max_line_length = len
+ end
+
+ # Gets the max line length.
+ def self.max_line_length
+ @@max_line_length
+ end
+
+ # Required
+ attr_accessor :type # :normal, :plural, :msgctxt, :msgctxt_plural
+ attr_accessor :msgid
+ # Options
+ attr_accessor :msgid_plural
+ attr_accessor :msgctxt
+ attr_accessor :sources # ["file1:line1", "file2:line2", ...]
+ attr_accessor :comment
+
+ # Create the object. +type+ should be :normal, :plural, :msgctxt or :msgctxt_plural.
+ def initialize(type)
+ @type = type
+ @sources = []
+ @param_type = PARAMS[@type]
+ end
+
+ # Support for extracted comments. Explanation s.
+ # http://www.gnu.org/software/gettext/manual/gettext.html#Names
+ def add_comment(new_comment)
+ if (new_comment and ! new_comment.empty?)
+ @comment ||= ""
+ @comment += new_comment
+ end
+ to_s
+ end
+
+ # Returns a parameter representation suitable for po-files
+ # and other purposes.
+ def escaped(param_name)
+ orig = self.send param_name
+ orig.gsub(/"/, '\"').gsub(/\r/, '')
+ end
+
+ # Checks if the other translation target is mergeable with
+ # the current one. Relevant are msgid and translation context (msgctxt).
+ def ==(other)
+ other.msgid == self.msgid && other.msgctxt == self.msgctxt
+ end
+
+ # Merges two translation targets with the same msgid and returns the merged
+ # result. If one is declared as plural and the other not, then the one
+ # with the plural wins.
+ def merge(other)
+ return self unless other
+ raise ParseError, "Translation targets do not match: \n" \
+ " self: #{self.inspect}\n other: '#{other.inspect}'" unless self == other
+ if other.msgid_plural && !self.msgid_plural
+ res = other
+ unless (res.sources.include? self.sources[0])
+ res.sources += self.sources
+ res.add_comment(self.comment)
+ end
+ else
+ res = self
+ unless (res.sources.include? other.sources[0])
+ res.sources += other.sources
+ res.add_comment(other.comment)
+ end
+ end
+ res
+ end
+
+ # Output the po message for the po-file.
+ def to_po_str
+ raise "msgid is nil." unless @msgid
+ raise "sources is nil." unless @sources
+
+ str = ""
+ # extracted comments
+ if comment
+ comment.split("\n").each do |comment_line|
+ str << "\n#. #{comment_line.strip}"
+ end
+ end
+
+ # references
+ curr_pos = @@max_line_length
+ sources.each do |e|
+ if curr_pos + e.size > @@max_line_length
+ str << "\n#:"
+ curr_pos = 3
+ else
+ curr_pos += (e.size + 1)
+ end
+ str << " " << e
+ end
+
+ # msgctxt, msgid, msgstr
+ str << "\nmsgctxt \"" << msgctxt << "\"" if msgctxt?
+ str << "\nmsgid \"" << escaped(:msgid) << "\"\n"
+ if plural?
+ str << "msgid_plural \"" << escaped(:msgid_plural) << "\"\n"
+ str << "msgstr[0] \"\"\n"
+ str << "msgstr[1] \"\"\n"
+ else
+ str << "msgstr \"\"\n"
+ end
+ str
+ end
+
+ # Returns true if the type is kind of msgctxt.
+ # And if this is a kind of msgctxt and msgctxt property
+ # is nil, then raise an RuntimeException.
+ def msgctxt?
+ if [:msgctxt, :msgctxt_plural].include? @type
+ raise "This PoMessage is a kind of msgctxt but the msgctxt property is nil. msgid: #{msgid}" unless @msgctxt
+ true
+ end
+ end
+
+ # Returns true if the type is kind of plural.
+ # And if this is a kind of plural and msgid_plural property
+ # is nil, then raise an RuntimeException.
+ def plural?
+ if [:plural, :msgctxt_plural].include? @type
+ raise "This PoMessage is a kind of plural but the msgid_plural property is nil. msgid: #{msgid}" unless @msgid_plural
+ true
+ end
+ end
+
+ private
+
+ # sets or extends the value of a translation target params like msgid,
+ # msgctxt etc.
+ # param is symbol with the name of param
+ # value - new value
+ def set_value(param, value)
+ send "#{param}=", (send(param) || '') + value.gsub(/\n/, '\n')
+ end
+
+ public
+ # For backward comatibility. This doesn't support "comment".
+ # ary = [msgid1, "file1:line1", "file2:line"]
+ def self.new_from_ary(ary)
+ ary = ary.dup
+ msgid = ary.shift
+ sources = ary
+ type = :normal
+ msgctxt = nil
+ msgid_plural = nil
+
+ if msgid.include? "\004"
+ msgctxt, msgid = msgid.split(/\004/)
+ type = :msgctxt
+ end
+ if msgid.include? "\000"
+ ids = msgid.split(/\000/)
+ msgid = ids[0]
+ msgid_plural = ids[1]
+ if type == :msgctxt
+ type = :msgctxt_plural
+ else
+ type = :plural
+ end
+ end
+ ret = self.new(type)
+ ret.msgid = msgid
+ ret.sources = sources
+ ret.msgctxt = msgctxt
+ ret.msgid_plural = msgid_plural
+ ret
+ end
+
+ def [](number)
+ param = @param_type[number]
+ raise ParseError, 'no more string parameters expected' unless param
+ send param
+ end
+ end
+
+end
diff --git a/vendor/gems/gettext-2.1.0/lib/gettext/tools/poparser.rb b/vendor/gems/gettext-2.1.0/lib/gettext/tools/poparser.rb
new file mode 100644
index 000000000..827a99c2f
--- /dev/null
+++ b/vendor/gems/gettext-2.1.0/lib/gettext/tools/poparser.rb
@@ -0,0 +1,356 @@
+=begin
+ poparser.rb - Generate a .mo
+
+ Copyright (C) 2003-2009 Masao Mutoh <mutomasa at gmail.com>
+
+ You may redistribute it and/or modify it under the same
+ license terms as Ruby.
+=end
+
+#
+# DO NOT MODIFY!!!!
+# This file is automatically generated by Racc 1.4.6
+# from Racc grammer file "".
+#
+
+require 'racc/parser.rb'
+module GetText
+ class PoParser < Racc::Parser
+
+module_eval(<<'...end poparser.ry/module_eval...', 'poparser.ry', 108)
+ include GetText
+ GetText.bindtextdomain("rgettext")
+
+ def unescape(orig)
+ ret = orig.gsub(/\\n/, "\n")
+ ret.gsub!(/\\t/, "\t")
+ ret.gsub!(/\\r/, "\r")
+ ret.gsub!(/\\"/, "\"")
+ ret
+ end
+
+ def parse(str, data, ignore_fuzzy = true)
+ @comments = []
+ @data = data
+ @fuzzy = false
+ @msgctxt = ""
+ $ignore_fuzzy = ignore_fuzzy
+
+ str.strip!
+ @q = []
+ until str.empty? do
+ case str
+ when /\A\s+/
+ str = $'
+ when /\Amsgctxt/
+ @q.push [:MSGCTXT, $&]
+ str = $'
+ when /\Amsgid_plural/
+ @q.push [:MSGID_PLURAL, $&]
+ str = $'
+ when /\Amsgid/
+ @q.push [:MSGID, $&]
+ str = $'
+ when /\Amsgstr/
+ @q.push [:MSGSTR, $&]
+ str = $'
+ when /\A\[(\d+)\]/
+ @q.push [:PLURAL_NUM, $1]
+ str = $'
+ when /\A\#~(.*)/
+ $stderr.print _("Warning: obsolete msgid exists.\n")
+ $stderr.print " #{$&}\n"
+ @q.push [:COMMENT, $&]
+ str = $'
+ when /\A\#(.*)/
+ @q.push [:COMMENT, $&]
+ str = $'
+ when /\A\"(.*)\"/
+ @q.push [:STRING, $1]
+ str = $'
+ else
+ #c = str[0,1]
+ #@q.push [:STRING, c]
+ str = str[1..-1]
+ end
+ end
+ @q.push [false, '$end']
+ if $DEBUG
+ @q.each do |a,b|
+ puts "[#{a}, #{b}]"
+ end
+ end
+ @yydebug = true if $DEBUG
+ do_parse
+
+ if @comments.size > 0
+ @data.set_comment(:last, @comments.join("\n"))
+ end
+ @data
+ end
+
+ def next_token
+ @q.shift
+ end
+
+ def on_message(msgid, msgstr)
+ if msgstr.size > 0
+ @data[msgid] = msgstr
+ @data.set_comment(msgid, @comments.join("\n"))
+ end
+ @comments.clear
+ @msgctxt = ""
+ end
+
+ def on_comment(comment)
+ @fuzzy = true if (/fuzzy/ =~ comment)
+ @comments << comment
+ end
+
+ def parse_file(po_file, data, ignore_fuzzy = true)
+ args = [ po_file ]
+ # In Ruby 1.9, we must detect proper encoding of a PO file.
+ if String.instance_methods.include?(:encode)
+ encoding = detect_file_encoding(po_file)
+ args << "r:#{encoding}"
+ end
+ @po_file = po_file
+ parse(File.open(*args) {|io| io.read }, data, ignore_fuzzy)
+ end
+
+ def detect_file_encoding(po_file)
+ open(po_file, :encoding => 'ASCII-8BIT') do |input|
+ input.lines.each do |line|
+ return Encoding.find($1) if %r["Content-Type:.*\scharset=(.*)\\n"] =~ line
+ end
+ end
+ Encoding.default_external
+ end
+ private :detect_file_encoding
+...end poparser.ry/module_eval...
+##### State transition tables begin ###
+
+racc_action_table = [
+ 3, 13, 5, 7, 9, 15, 16, 17, 20, 17,
+ 13, 17, 13, 13, 11, 17, 23, 20, 13, 17 ]
+
+racc_action_check = [
+ 1, 16, 1, 1, 1, 12, 12, 12, 18, 18,
+ 7, 14, 15, 9, 3, 19, 20, 21, 23, 25 ]
+
+racc_action_pointer = [
+ nil, 0, nil, 14, nil, nil, nil, 3, nil, 6,
+ nil, nil, 0, nil, 4, 5, -6, nil, 2, 8,
+ 8, 11, nil, 11, nil, 12 ]
+
+racc_action_default = [
+ -1, -16, -2, -16, -3, -13, -4, -16, -6, -16,
+ -7, 26, -16, -15, -5, -16, -16, -14, -16, -8,
+ -16, -9, -11, -16, -10, -12 ]
+
+racc_goto_table = [
+ 12, 22, 14, 4, 24, 6, 2, 8, 18, 19,
+ 10, 21, 1, nil, nil, nil, 25 ]
+
+racc_goto_check = [
+ 5, 9, 5, 3, 9, 4, 2, 6, 5, 5,
+ 7, 8, 1, nil, nil, nil, 5 ]
+
+racc_goto_pointer = [
+ nil, 12, 5, 2, 4, -7, 6, 9, -7, -17 ]
+
+racc_goto_default = [
+ nil, nil, nil, nil, nil, nil, nil, nil, nil, nil ]
+
+racc_reduce_table = [
+ 0, 0, :racc_error,
+ 0, 10, :_reduce_none,
+ 2, 10, :_reduce_none,
+ 2, 10, :_reduce_none,
+ 2, 10, :_reduce_none,
+ 2, 12, :_reduce_5,
+ 1, 13, :_reduce_none,
+ 1, 13, :_reduce_none,
+ 4, 15, :_reduce_8,
+ 5, 16, :_reduce_9,
+ 2, 17, :_reduce_10,
+ 1, 17, :_reduce_none,
+ 3, 18, :_reduce_12,
+ 1, 11, :_reduce_13,
+ 2, 14, :_reduce_14,
+ 1, 14, :_reduce_15 ]
+
+racc_reduce_n = 16
+
+racc_shift_n = 26
+
+racc_token_table = {
+ false => 0,
+ :error => 1,
+ :COMMENT => 2,
+ :MSGID => 3,
+ :MSGCTXT => 4,
+ :MSGID_PLURAL => 5,
+ :MSGSTR => 6,
+ :STRING => 7,
+ :PLURAL_NUM => 8 }
+
+racc_nt_base = 9
+
+racc_use_result_var = true
+
+Racc_arg = [
+ racc_action_table,
+ racc_action_check,
+ racc_action_default,
+ racc_action_pointer,
+ racc_goto_table,
+ racc_goto_check,
+ racc_goto_default,
+ racc_goto_pointer,
+ racc_nt_base,
+ racc_reduce_table,
+ racc_token_table,
+ racc_shift_n,
+ racc_reduce_n,
+ racc_use_result_var ]
+
+Racc_token_to_s_table = [
+ "$end",
+ "error",
+ "COMMENT",
+ "MSGID",
+ "MSGCTXT",
+ "MSGID_PLURAL",
+ "MSGSTR",
+ "STRING",
+ "PLURAL_NUM",
+ "$start",
+ "msgfmt",
+ "comment",
+ "msgctxt",
+ "message",
+ "string_list",
+ "single_message",
+ "plural_message",
+ "msgstr_plural",
+ "msgstr_plural_line" ]
+
+Racc_debug_parser = true
+
+##### State transition tables end #####
+
+# reduce 0 omitted
+
+# reduce 1 omitted
+
+# reduce 2 omitted
+
+# reduce 3 omitted
+
+# reduce 4 omitted
+
+module_eval(<<'.,.,', 'poparser.ry', 23)
+ def _reduce_5(val, _values, result)
+ @msgctxt = unescape(val[1]) + "\004"
+
+ result
+ end
+.,.,
+
+# reduce 6 omitted
+
+# reduce 7 omitted
+
+module_eval(<<'.,.,', 'poparser.ry', 35)
+ def _reduce_8(val, _values, result)
+ if @fuzzy and $ignore_fuzzy
+ if val[1] != ""
+ $stderr.print _("Warning: fuzzy message was ignored.\n")
+ $stderr.print " #{@po_file}: msgid '#{val[1]}'\n"
+ else
+ on_message('', unescape(val[3]))
+ end
+ @fuzzy = false
+ else
+ on_message(@msgctxt + unescape(val[1]), unescape(val[3]))
+ end
+ result = ""
+
+ result
+ end
+.,.,
+
+module_eval(<<'.,.,', 'poparser.ry', 52)
+ def _reduce_9(val, _values, result)
+ if @fuzzy and $ignore_fuzzy
+ if val[1] != ""
+ $stderr.print _("Warning: fuzzy message was ignored.\n")
+ $stderr.print "msgid = '#{val[1]}\n"
+ else
+ on_message('', unescape(val[3]))
+ end
+ @fuzzy = false
+ else
+ on_message(@msgctxt + unescape(val[1]) + "\000" + unescape(val[3]), unescape(val[4]))
+ end
+ result = ""
+
+ result
+ end
+.,.,
+
+module_eval(<<'.,.,', 'poparser.ry', 70)
+ def _reduce_10(val, _values, result)
+ if val[0].size > 0
+ result = val[0] + "\000" + val[1]
+ else
+ result = ""
+ end
+
+ result
+ end
+.,.,
+
+# reduce 11 omitted
+
+module_eval(<<'.,.,', 'poparser.ry', 82)
+ def _reduce_12(val, _values, result)
+ result = val[2]
+
+ result
+ end
+.,.,
+
+module_eval(<<'.,.,', 'poparser.ry', 89)
+ def _reduce_13(val, _values, result)
+ on_comment(val[0])
+
+ result
+ end
+.,.,
+
+module_eval(<<'.,.,', 'poparser.ry', 97)
+ def _reduce_14(val, _values, result)
+ result = val.delete_if{|item| item == ""}.join
+
+ result
+ end
+.,.,
+
+module_eval(<<'.,.,', 'poparser.ry', 101)
+ def _reduce_15(val, _values, result)
+ result = val[0]
+
+ result
+ end
+.,.,
+
+def _reduce_none(val, _values, result)
+ val[0]
+end
+
+ end # class PoParser
+ end # module GetText
+
+
diff --git a/vendor/gems/gettext-2.1.0/lib/gettext/tools/rgettext.rb b/vendor/gems/gettext-2.1.0/lib/gettext/tools/rgettext.rb
new file mode 100644
index 000000000..a66ed2fe0
--- /dev/null
+++ b/vendor/gems/gettext-2.1.0/lib/gettext/tools/rgettext.rb
@@ -0,0 +1,226 @@
+#! /usr/bin/env ruby
+=begin
+ rgettext.rb - Generate a .pot file.
+
+ Copyright (C) 2003-2009 Masao Mutoh
+ Copyright (C) 2001,2002 Yasushi Shoji, Masao Mutoh
+
+ Yasushi Shoji <yashi at atmark-techno.com>
+ 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 'optparse'
+require 'gettext'
+require 'rbconfig'
+
+module GetText
+
+ module RGetText #:nodoc:
+ extend GetText
+
+ bindtextdomain("rgettext")
+
+ # constant values
+ VERSION = GetText::VERSION
+
+ @ex_parsers = []
+ [
+ ["glade.rb", "GladeParser"],
+ ["erb.rb", "ErbParser"],
+# ["ripper.rb", "RipperParser"],
+ ["ruby.rb", "RubyParser"] # Default parser.
+ ].each do |f, klass|
+ begin
+ require "gettext/tools/parser/#{f}"
+ @ex_parsers << GetText.const_get(klass)
+ rescue
+ $stderr.puts _("'%{klass}' is ignored.") % {:klass => klass}
+ $stderr.puts $! if $DEBUG
+ end
+ end
+
+ module_function
+
+ # Add an option parser
+ # the option parser module requires to have target?(file) and parser(file, ary) method.
+ #
+ # require 'gettext/tools/rgettext'
+ # module FooParser
+ # module_function
+ # def target?(file)
+ # File.extname(file) == '.foo' # *.foo file only.
+ # end
+ # def parse(file, ary)
+ # :
+ # return ary # [["msgid1", "foo.rb:200"], ["msgid2", "bar.rb:300", "baz.rb:400"], ...]
+ # end
+ # end
+ #
+ # GetText::RGetText.add_parser(FooParser)
+ def add_parser(klass)
+ @ex_parsers.insert(0, klass)
+ end
+
+ def generate_pot_header # :nodoc:
+ time = Time.now.strftime("%Y-%m-%d %H:%M")
+ off = Time.now.utc_offset
+ sign = off <= 0 ? '-' : '+'
+ time += sprintf('%s%02d%02d', sign, *(off.abs / 60).divmod(60))
+
+ <<TITLE
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\\n"
+"POT-Creation-Date: #{time}\\n"
+"PO-Revision-Date: #{time}\\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n"
+"Language-Team: LANGUAGE <LL@li.org>\\n"
+"MIME-Version: 1.0\\n"
+"Content-Type: text/plain; charset=UTF-8\\n"
+"Content-Transfer-Encoding: 8bit\\n"
+"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\\n"
+TITLE
+ end
+
+ def generate_pot(paths) # :nodoc:
+ pomessages = parse(paths)
+ str = ""
+ pomessages.each do |target|
+ str << target.to_po_str
+ end
+ str
+ end
+
+ def parse(paths) # :nodoc:
+ pomessages = []
+ paths.each do |path|
+ begin
+ @ex_parsers.each do |klass|
+ if klass.target?(path)
+ if klass.method(:parse).arity == 1
+ targets = klass.parse(path)
+ else
+ # For backward compatibility.
+ targets = klass.parse(path, [])
+ end
+
+ targets.each{|pomessage|
+ if pomessage.kind_of? Array
+ pomessage = PoMessage.new_from_ary(pomessage)
+ end
+
+ # Save the previous target.
+ existing = pomessages.find_index {|t| t == pomessage}
+ if existing
+ pomessage = pomessages[existing].merge(pomessage)
+ pomessages[existing] = pomessage
+ else
+ pomessages << pomessage
+ end
+ }
+ break
+ end
+ end
+ rescue
+ puts _("Error parsing %{path}") % {:path => path}
+ raise
+ end
+ end
+ pomessages
+ end
+
+ def check_options # :nodoc:
+ output = STDOUT
+
+ opts = OptionParser.new
+ opts.banner = _("Usage: %s input.rb [-r parser.rb] [-o output.pot]") % $0
+ opts.separator("")
+ opts.separator(_("Extract translatable strings from given input files."))
+ opts.separator("")
+ opts.separator(_("Specific options:"))
+
+ opts.on("-o", "--output=FILE", _("write output to specified file")) do |out|
+ unless FileTest.exist? out
+ output = File.new(File.expand_path(out), "w+")
+ else
+ $stderr.puts(_("File '%s' already exists.") % out)
+ exit 1
+ end
+ end
+
+ opts.on("-r", "--require=library", _("require the library before executing rgettext")) do |out|
+ require out
+ end
+
+ opts.on("-d", "--debug", _("run in debugging mode")) do
+ $DEBUG = true
+ end
+
+ opts.on_tail("--version", _("display version information and exit")) do
+ puts "#{$0} #{VERSION}"
+ puts "#{File.join(Config::CONFIG["bindir"], Config::CONFIG["RUBY_INSTALL_NAME"])} #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}]"
+ exit
+ end
+
+ opts.parse!(ARGV)
+
+ if ARGV.size == 0
+ puts opts.help
+ exit 1
+ end
+
+ [ARGV, output]
+ end
+
+ def run(paths = nil, out = STDOUT) # :nodoc:
+ if paths.is_a? String
+ paths = [paths]
+ elsif ! paths
+ paths, out = check_options
+ end
+
+ if paths.size == 0
+ raise ArgumentError, _("no input files")
+ end
+
+ if out.is_a? String
+ File.open(File.expand_path(out), "w+") do |file|
+ file.puts generate_pot_header
+ file.puts generate_pot(paths)
+ end
+ else
+ out.puts generate_pot_header
+ out.puts generate_pot(paths)
+ end
+ self
+ end
+ end
+ extend self
+ # Creates a po-file from targetfiles(ruby-script-files, .rhtml files, glade-2 XML files),
+ # then output the result to out. If no parameter is set, it behaves same as command line tools(rgettet).
+ #
+ # This function is a part of GetText.create_pofiles.
+ # Usually you don't need to call this function directly.
+ #
+ # * paths: An Array of po-file paths or nil.
+ # * out: output IO or output path.
+ # * Returns: self
+ def rgettext(paths = nil, out = STDOUT)
+ RGetText.run(paths, out)
+ self
+ end
+end
+
+if $0 == __FILE__
+ GetText.rgettext
+# GetText.rgettext($0, "tmp.txt")
+end
diff --git a/vendor/gems/gettext-2.1.0/lib/gettext/tools/rmsgfmt.rb b/vendor/gems/gettext-2.1.0/lib/gettext/tools/rmsgfmt.rb
new file mode 100644
index 000000000..2aa428c55
--- /dev/null
+++ b/vendor/gems/gettext-2.1.0/lib/gettext/tools/rmsgfmt.rb
@@ -0,0 +1,84 @@
+=begin
+ rmsgfmt.rb - Generate a .mo
+
+ Copyright (C) 2003-2009 Masao Mutoh
+
+ You may redistribute it and/or modify it under the same
+ license terms as Ruby or LGPL.
+=end
+
+require 'optparse'
+require 'fileutils'
+require 'gettext'
+require 'gettext/tools/poparser'
+require 'rbconfig'
+
+module GetText
+
+ module RMsgfmt #:nodoc:
+ extend GetText
+ extend self
+
+ bindtextdomain "rgettext"
+
+ def run(targetfile = nil, output_path = nil) # :nodoc:
+ unless targetfile
+ targetfile, output_path = check_options
+ end
+ unless targetfile
+ raise ArgumentError, _("no input files")
+ end
+ unless output_path
+ output_path = "messages.mo"
+ end
+
+ parser = PoParser.new
+ data = MOFile.new
+
+ parser.parse_file(targetfile, data)
+ data.save_to_file(output_path)
+ end
+
+ def check_options # :nodoc:
+ output = nil
+
+ opts = OptionParser.new
+ opts.banner = _("Usage: %s input.po [-o output.mo]" % $0)
+ opts.separator("")
+ opts.separator(_("Generate binary message catalog from textual translation description."))
+ opts.separator("")
+ opts.separator(_("Specific options:"))
+
+ opts.on("-o", "--output=FILE", _("write output to specified file")) do |out|
+ output = out
+ end
+
+ opts.on_tail("--version", _("display version information and exit")) do
+ puts "#{$0} #{GetText::VERSION}"
+ puts "#{File.join(Config::CONFIG["bindir"], Config::CONFIG["RUBY_INSTALL_NAME"])} #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}]"
+ exit
+ end
+ opts.parse!(ARGV)
+
+ if ARGV.size == 0
+ puts opts.help
+ exit 1
+ end
+
+ [ARGV[0], output]
+ end
+ end
+
+ # Creates a mo-file from a targetfile(po-file), then output the result to out.
+ # If no parameter is set, it behaves same as command line tools(rmsgfmt).
+ # * targetfile: An Array of po-files or nil.
+ # * output_path: output path.
+ # * Returns: the MOFile object.
+ def rmsgfmt(targetfile = nil, output_path = nil)
+ RMsgfmt.run(targetfile, output_path)
+ end
+end
+
+if $0 == __FILE__ then
+ GetText.rmsgfmt
+end
diff --git a/vendor/gems/gettext-2.1.0/lib/gettext/tools/rmsgmerge.rb b/vendor/gems/gettext-2.1.0/lib/gettext/tools/rmsgmerge.rb
new file mode 100644
index 000000000..802ba20bc
--- /dev/null
+++ b/vendor/gems/gettext-2.1.0/lib/gettext/tools/rmsgmerge.rb
@@ -0,0 +1,498 @@
+=begin
+ rmsgmerge.rb - Merge old .po to new .po
+
+ Copyright (C) 2005-2009 Masao Mutoh
+ Copyright (C) 2005,2006 speakillof
+
+ You may redistribute it and/or modify it under the same
+ license terms as Ruby or LGPL.
+=end
+
+require 'optparse'
+require 'gettext'
+require 'gettext/tools/poparser'
+require 'rbconfig'
+
+module GetText
+
+ module RMsgMerge
+
+ class PoData #:nodoc:
+
+ attr_reader :msgids
+
+ def initialize
+ @msgid2msgstr = {}
+ @msgid2comment = {}
+ @msgids = []
+ end
+
+ def set_comment(msgid_or_sym, comment)
+ @msgid2comment[msgid_or_sym] = comment
+ end
+
+ def msgstr(msgid)
+ @msgid2msgstr[msgid]
+ end
+
+ def comment(msgid)
+ @msgid2comment[msgid]
+ end
+
+ def [](msgid)
+ @msgid2msgstr[msgid]
+ end
+
+ def []=(msgid, msgstr)
+ # Retain the order
+ unless @msgid2msgstr[msgid]
+ @msgids << msgid
+ end
+
+ @msgid2msgstr[msgid] = msgstr
+ end
+
+ def each_msgid
+ arr = @msgids.delete_if{|i| Symbol === i or i == ''}
+ arr.each do |i|
+ yield i
+ end
+ end
+
+ def msgid?(msgid)
+ !(Symbol === msgid) and @msgid2msgstr[msgid] and (msgid != '')
+ end
+
+ # Is it necessary to implement this method?
+ def search_msgid_fuzzy(msgid, used_msgids)
+ nil
+ end
+
+ def nplural
+ unless @msgid2msgstr['']
+ return 0
+ else
+ if /\s*nplural\s*=\s*(\d+)/ =~ @msgid2msgstr['']
+ return $1.to_i
+ else
+ return 0
+ end
+
+ end
+ end
+
+ def generate_po
+ str = ''
+ str << generate_po_header
+
+ self.each_msgid do |id|
+ str << self.generate_po_entry(id)
+ end
+
+ str << @msgid2comment[:last]
+ str
+ end
+
+ def generate_po_header
+ str = ""
+
+ str << @msgid2comment[''].strip << "\n"
+ str << 'msgid ""' << "\n"
+ str << 'msgstr ""' << "\n"
+ msgstr = @msgid2msgstr[''].gsub(/"/, '\"').gsub(/\r/, '')
+ msgstr = msgstr.gsub(/^(.*)$/, '"\1\n"')
+ str << msgstr
+ str << "\n"
+
+ str
+ end
+
+ def generate_po_entry(msgid)
+ str = ""
+ str << @msgid2comment[msgid]
+ if str[-1] != "\n"[0]
+ str << "\n"
+ end
+
+ id = msgid.gsub(/"/, '\"').gsub(/\r/, '')
+ msgstr = @msgid2msgstr[msgid].gsub(/"/, '\"').gsub(/\r/, '')
+
+ if id.include?("\000")
+ ids = id.split(/\000/)
+ str << "msgid " << __conv(ids[0]) << "\n"
+ ids[1..-1].each do |single_id|
+ str << "msgid_plural " << __conv(single_id) << "\n"
+ end
+
+ msgstr.split("\000").each_with_index do |m, n|
+ str << "msgstr[#{n}] " << __conv(m) << "\n"
+ end
+ else
+ str << "msgid " << __conv(id) << "\n"
+ str << "msgstr " << __conv(msgstr) << "\n"
+ end
+
+ str << "\n"
+ str
+ end
+
+ def __conv(str)
+ s = ''
+
+ if str.count("\n") > 1
+ s << '""' << "\n"
+ s << str.gsub(/^(.*)$/, '"\1\n"')
+ else
+ s << '"' << str.sub("\n", "\\n") << '"'
+ end
+
+ s.rstrip
+ end
+
+ end
+
+ class Merger #:nodoc:
+
+ # From GNU gettext source.
+ #
+ # Merge the reference with the definition: take the #. and
+ # #: comments from the reference, take the # comments from
+ # the definition, take the msgstr from the definition. Add
+ # this merged entry to the output message list.
+ DOT_COMMENT_RE = /\A#\./
+ SEMICOLON_COMMENT_RE = /\A#\:/
+ FUZZY_RE = /\A#\,/
+ NOT_SPECIAL_COMMENT_RE = /\A#([^:.,]|\z)/
+
+ CRLF_RE = /\r?\n/
+ POT_DATE_EXTRACT_RE = /POT-Creation-Date:\s*(.*)?\s*$/
+ POT_DATE_RE = /POT-Creation-Date:.*?$/
+
+ def merge(definition, reference)
+ # deep copy
+ result = Marshal.load( Marshal.dump(reference) )
+
+ used = []
+ merge_header(result, definition)
+
+ result.each_msgid do |msgid|
+ if definition.msgid?(msgid)
+ used << msgid
+ merge_message(msgid, result, msgid, definition)
+ elsif other_msgid = definition.search_msgid_fuzzy(msgid, used)
+ used << other_msgid
+ merge_fuzzy_message(msgid, result, other_msgid, definition)
+ elsif msgid.index("\000") and ( reference.msgstr(msgid).gsub("\000", '') == '' )
+ # plural
+ result[msgid] = "\000" * definition.nplural
+ else
+ change_reference_comment(msgid, result)
+ end
+ end
+
+ ###################################################################
+ # msgids which are not used in reference are handled as obsolete. #
+ ###################################################################
+ last_comment = result.comment(:last) || ''
+ definition.each_msgid do |msgid|
+ unless used.include?(msgid)
+ last_comment << "\n"
+ last_comment << definition.generate_po_entry(msgid).strip.gsub(/^/, '#. ')
+ last_comment << "\n"
+ end
+ end
+ result.set_comment(:last, last_comment)
+
+ result
+ end
+
+ def merge_message(msgid, target, def_msgid, definition)
+ merge_comment(msgid, target, def_msgid, definition)
+
+ ############################################
+ # check mismatch of msgid and msgid_plural #
+ ############################################
+ def_msgstr = definition[def_msgid]
+ if msgid.index("\000")
+ if def_msgstr.index("\000")
+ # OK
+ target[msgid] = def_msgstr
+ else
+ # NG
+ s = ''
+ definition.nplural.times {
+ s << def_msgstr
+ s << "\000"
+ }
+ target[msgid] = s
+ end
+ else
+ if def_msgstr.index("\000")
+ # NG
+ target[msgid] = def_msgstr.split("\000")[0]
+ else
+ # OK
+ target[msgid] = def_msgstr
+ end
+ end
+ end
+
+ # for the future
+ def merge_fuzzy_message(msgid, target, def_msgid, definition)
+ merge_message(msgid, target, def_msgid, definition)
+ end
+
+ def merge_comment(msgid, target, def_msgid, definition)
+ ref_comment = target.comment(msgid)
+ def_comment = definition.comment(def_msgid)
+
+ normal_comment = []
+ dot_comment = []
+ semi_comment = []
+ is_fuzzy = false
+
+ def_comment.split(CRLF_RE).each do |l|
+ if NOT_SPECIAL_COMMENT_RE =~ l
+ normal_comment << l
+ end
+ end
+
+ ref_comment.split(CRLF_RE).each do |l|
+ if DOT_COMMENT_RE =~ l
+ dot_comment << l
+ elsif SEMICOLON_COMMENT_RE =~ l
+ semi_comment << l
+ elsif FUZZY_RE =~ l
+ is_fuzzy = true
+ end
+ end
+
+ str = format_comment(normal_comment, dot_comment, semi_comment, is_fuzzy)
+ target.set_comment(msgid, str)
+ end
+
+ def change_reference_comment(msgid, podata)
+ normal_comment = []
+ dot_comment = []
+ semi_comment = []
+ is_fuzzy = false
+
+ podata.comment(msgid).split(CRLF_RE).each do |l|
+ if DOT_COMMENT_RE =~ l
+ dot_comment << l
+ elsif SEMICOLON_COMMENT_RE =~ l
+ semi_comment << l
+ elsif FUZZY_RE =~ l
+ is_fuzzy = true
+ else
+ normal_comment << l
+ end
+ end
+
+ str = format_comment(normal_comment, dot_comment, semi_comment, is_fuzzy)
+ podata.set_comment(msgid, str)
+ end
+
+ def format_comment(normal_comment, dot_comment, semi_comment, is_fuzzy)
+ str = ''
+
+ str << normal_comment.join("\n").gsub(/^#(\s*)/){|sss|
+ if $1 == ""
+ "# "
+ else
+ sss
+ end
+ }
+ if normal_comment.size > 0
+ str << "\n"
+ end
+
+ str << dot_comment.join("\n").gsub(/^#.(\s*)/){|sss|
+ if $1 == ""
+ "#. "
+ else
+ sss
+ end
+ }
+ if dot_comment.size > 0
+ str << "\n"
+ end
+
+ str << semi_comment.join("\n").gsub(/^#:\s*/, "#: ")
+ if semi_comment.size > 0
+ str << "\n"
+ end
+
+ if is_fuzzy
+ str << "#, fuzzy\n"
+ end
+
+ str
+ end
+
+ def merge_header(target, definition)
+ merge_comment('', target, '', definition)
+
+ msg = target.msgstr('')
+ def_msg = definition.msgstr('')
+ if POT_DATE_EXTRACT_RE =~ msg
+ time = $1
+ def_msg = def_msg.sub(POT_DATE_RE, "POT-Creation-Date: #{time}")
+ end
+
+ target[''] = def_msg
+ end
+
+ end
+
+ end
+
+end
+
+module GetText::RMsgMerge #:nodoc:
+
+ class Config #:nodoc:
+
+ attr_accessor :defpo, :refpot, :output, :fuzzy, :update
+
+ # update mode options
+ attr_accessor :backup, :suffix
+
+=begin
+The result is written back to def.po.
+ --backup=CONTROL make a backup of def.po
+ --suffix=SUFFIX override the usual backup suffix
+The version control method may be selected via the --backup option or through
+the VERSION_CONTROL environment variable. Here are the values:
+ none, off never make backups (even if --backup is given)
+ numbered, t make numbered backups
+ existing, nil numbered if numbered backups exist, simple otherwise
+ simple, never always make simple backups
+The backup suffix is `~', unless set with --suffix or the SIMPLE_BACKUP_SUFFIX
+environment variable.
+=end
+
+ def initialize
+ @output = STDOUT
+ @fuzzy = nil
+ @update = nil
+ @backup = ENV["VERSION_CONTROL"]
+ @suffix= ENV["SIMPLE_BACKUP_SUFFIX"] || "~"
+ @input_dirs = ["."]
+ end
+
+ end
+
+end
+
+module GetText
+
+ module RMsgMerge
+ extend GetText
+ extend self
+
+ bindtextdomain("rgettext")
+
+ # constant values
+ VERSION = GetText::VERSION
+ DATE = %w($Date: 2007/07/21 15:03:05 $)[1]
+
+ def check_options(config)
+ opts = OptionParser.new
+ opts.banner = _("Usage: %s def.po ref.pot [-o output.pot]") % $0
+ #opts.summary_width = 80
+ opts.separator("")
+ opts.separator(_("Merges two Uniforum style .po files together. The def.po file is an existing PO file with translations. The ref.pot file is the last created PO file with up-to-date source references. ref.pot is generally created by rgettext."))
+ opts.separator("")
+ opts.separator(_("Specific options:"))
+
+ opts.on("-o", "--output=FILE", _("write output to specified file")) do |out|
+ unless FileTest.exist? out
+ config.output = out
+ else
+ #$stderr.puts(_("File '%s' has already existed.") % out)
+ #exit 1
+ end
+ end
+
+ #opts.on("-F", "--fuzzy-matching")
+
+ opts.on_tail("--version", _("display version information and exit")) do
+ puts "#{$0} #{VERSION} (#{DATE})"
+ puts "#{File.join(::Config::CONFIG["bindir"], ::Config::CONFIG["RUBY_INSTALL_NAME"])} #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}]"
+ exit
+ end
+
+ opts.parse!(ARGV)
+
+ if ARGV.size != 2
+ puts opts.help
+ exit 1
+ end
+
+ config.defpo = ARGV[0]
+ config.refpot = ARGV[1]
+ end
+
+ def run(reference = nil, definition = nil, out = STDOUT)
+ config = GetText::RMsgMerge::Config.new
+ config.refpot = reference
+ config.defpo = definition
+ config.output = out
+
+ check_options(config)
+
+ if config.defpo.nil?
+ raise ArgumentError, _("definition po is not given.")
+ elsif config.refpot.nil?
+ raise ArgumentError, _("reference pot is not given.")
+ end
+
+ parser = PoParser.new
+ defpo = parser.parse_file(config.defpo, PoData.new, false)
+ refpot = parser.parse_file(config.refstrrefstr, PoData.new, false)
+
+ m = Merger.new
+ result = m.merge(defpo, refpot)
+ p result if $DEBUG
+ print result.generate_po if $DEBUG
+
+ begin
+ if out.is_a? String
+ File.open(File.expand_path(out), "w+") do |file|
+ file.write(result.generate_po)
+ end
+ else
+ out.puts(result.generate_po)
+ end
+ ensure
+ out.close
+ end
+ end
+
+ end
+
+end
+
+
+
+module GetText
+
+ # Experimental
+ def rmsgmerge(reference = nil, definition = nil, out = STDOUT)
+ RMsgMerge.run(reference, definition, out)
+ end
+
+end
+
+
+
+if $0 == __FILE__ then
+ require 'pp'
+
+ #parser = GetText::RMsgMerge::PoParser.new;
+ #parser = GetText::PoParser.new;
+ #pp parser.parse(ARGF.read)
+
+ GetText.rmsgmerge
+end