module GetText class ParseError < StandardError end # Contains data related to the expression or sentence that # is to be translated (translation target). # Implements a sort of state machine to assist the parser. class TranslationTarget attr_accessor :type, :msgid, :occurrences # obligatory attributes attr_accessor :plural, :msgctxt, :extracted_comment # optional attributes def initialize(new_type) @type = new_type @occurrences = Array.new @param_number = 0 end # Supports parsing by setting attributes by and by. def set_current_attribute(str) case @param_number when 0 set_string_value :msgid, str when 1 case type when :plural set_string_value :plural, str when :msgctxt, :msgctxt_plural set_string_value :msgctxt, str else raise ParseError, 'no more string parameters expected' end when 2 if :msgctxt_plural set_string_value plural, str else raise ParseError, 'no more string parameters expected' end end end def advance_to_next_attribute @param_number += 1 end # Support for extracted comments. Explanation s. # http://www.gnu.org/software/gettext/manual/gettext.html#Names def add_extracted_comment(new_comment) @extracted_comment = @extracted_comment.to_s + new_comment 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 matches?(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 if other.nil? raise ParseError, "Translation targets do not match: \n" \ " self: #{self.inspect}\n other: '#{other.inspect}'" unless matches?(other) if other.plural && !self.plural res = other res.occurrences.concat self.occurrences else res = self res.occurrences.concat other.occurrences end res 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_string_value(param, value) send "#{param}=", (send(param) || '') + value.gsub(/\n/, '\n') end end end