grosser-pomo 0.4.1
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 +43 -0
 - data/VERSION.yml +4 -0
 - data/lib/pomo.rb +3 -0
 - data/lib/pomo/po_file.rb +117 -0
 - data/lib/pomo/translation.rb +44 -0
 - data/spec/pomo/po_file_spec.rb +110 -0
 - data/spec/pomo/translation_spec.rb +119 -0
 - data/spec/spec_helper.rb +10 -0
 - metadata +63 -0
 
    
        data/README.markdown
    ADDED
    
    | 
         @@ -0,0 +1,43 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            A simple and extendable .mo and .po file parser/generator.  
         
     | 
| 
      
 2 
     | 
    
         
            +
            --mo file parser and writer are missing atm--
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            Advanteges over [original po-parser](http://github.com/mutoh/gettext/blob/abf96713327cc4c5d35f0a772f3b75ff4819450c/lib/gettext/poparser.rb):
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
             - simple architecture + easy to extend/modify
         
     | 
| 
      
 7 
     | 
    
         
            +
             - emtpy msgstr translations are read
         
     | 
| 
      
 8 
     | 
    
         
            +
             - comments are included
         
     | 
| 
      
 9 
     | 
    
         
            +
             - fuzzy can be set/unset
         
     | 
| 
      
 10 
     | 
    
         
            +
             - multiple translations can be combined in a new po file(with comments and fuzzy and ...)
         
     | 
| 
      
 11 
     | 
    
         
            +
             - po files can be written from any kind of input
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            Setup
         
     | 
| 
      
 14 
     | 
    
         
            +
            =====
         
     | 
| 
      
 15 
     | 
    
         
            +
                sudo gem install grosser-pomo -s http://gems.github.com/
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
            ###Static interface
         
     | 
| 
      
 18 
     | 
    
         
            +
                #parse po files
         
     | 
| 
      
 19 
     | 
    
         
            +
                translations = Pomo::PoFile.parse(File.read('xxx.po')) + Pomo::PoFile.parse(File.read('yyy.po'))
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                #and use the data...
         
     | 
| 
      
 22 
     | 
    
         
            +
                msgids = translations.reject{|t|t.plural? or t.fuzzy?}.map(&:msgid)
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                #or write a new po file (unique by msgid)...
         
     | 
| 
      
 25 
     | 
    
         
            +
                File.open('xxx.po','w){|f|f.print(Pomo::PoFile.to_text(translations))}
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
            ###Instance interface
         
     | 
| 
      
 28 
     | 
    
         
            +
                p = PoMo::PoFile.new
         
     | 
| 
      
 29 
     | 
    
         
            +
                p.add_translations_from_text(File.read('...'))
         
     | 
| 
      
 30 
     | 
    
         
            +
                ...
         
     | 
| 
      
 31 
     | 
    
         
            +
                p.translations
         
     | 
| 
      
 32 
     | 
    
         
            +
                p.to_text
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
            TODO
         
     | 
| 
      
 35 
     | 
    
         
            +
            ====
         
     | 
| 
      
 36 
     | 
    
         
            +
             - extracting of version/pluralisation_rule/plurals/translator... (from msgid "")
         
     | 
| 
      
 37 
     | 
    
         
            +
             - mo writing/reading (this is the hardest part imo...)
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
            Author
         
     | 
| 
      
 40 
     | 
    
         
            +
            ======
         
     | 
| 
      
 41 
     | 
    
         
            +
            [Michael Grosser](http://pragmatig.wordpress.com)  
         
     | 
| 
      
 42 
     | 
    
         
            +
            grosser.michael@gmail.com  
         
     | 
| 
      
 43 
     | 
    
         
            +
            Hereby placed under public domain, do what you want, just do not hold me accountable...  
         
     | 
    
        data/VERSION.yml
    ADDED
    
    
    
        data/lib/pomo.rb
    ADDED
    
    
    
        data/lib/pomo/po_file.rb
    ADDED
    
    | 
         @@ -0,0 +1,117 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'pomo/translation'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Pomo
         
     | 
| 
      
 4 
     | 
    
         
            +
              class PoFile
         
     | 
| 
      
 5 
     | 
    
         
            +
                def self.parse(text)
         
     | 
| 
      
 6 
     | 
    
         
            +
                  PoFile.new.add_translations_from_text(text)
         
     | 
| 
      
 7 
     | 
    
         
            +
                end
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                def self.to_text(translations)
         
     | 
| 
      
 10 
     | 
    
         
            +
                  p = PoFile.new(:translations=>translations)
         
     | 
| 
      
 11 
     | 
    
         
            +
                  p.to_text
         
     | 
| 
      
 12 
     | 
    
         
            +
                end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                def self.unique_translations(translations)
         
     | 
| 
      
 15 
     | 
    
         
            +
                  last_seen_at_index = {}
         
     | 
| 
      
 16 
     | 
    
         
            +
                  translations.each_with_index {|translation,index|last_seen_at_index[translation.msgid]=index}
         
     | 
| 
      
 17 
     | 
    
         
            +
                  last_seen_at_index.values.sort.map{|index| translations[index]}
         
     | 
| 
      
 18 
     | 
    
         
            +
                end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                attr_reader :translations
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                def initialize(options = {})
         
     | 
| 
      
 23 
     | 
    
         
            +
                  @translations = options[:translations] || []
         
     | 
| 
      
 24 
     | 
    
         
            +
                end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                #the text is split into lines and then converted into logical translations
         
     | 
| 
      
 27 
     | 
    
         
            +
                #each translation consists of comments(that come before a translation)
         
     | 
| 
      
 28 
     | 
    
         
            +
                #and a msgid / msgstr
         
     | 
| 
      
 29 
     | 
    
         
            +
                def add_translations_from_text(text)
         
     | 
| 
      
 30 
     | 
    
         
            +
                  start_new_translation
         
     | 
| 
      
 31 
     | 
    
         
            +
                  text.split(/$/).each_with_index do |line,index|
         
     | 
| 
      
 32 
     | 
    
         
            +
                    @line_number = index + 1
         
     | 
| 
      
 33 
     | 
    
         
            +
                    next if line.empty?
         
     | 
| 
      
 34 
     | 
    
         
            +
                    if method_call? line
         
     | 
| 
      
 35 
     | 
    
         
            +
                      parse_method_call line
         
     | 
| 
      
 36 
     | 
    
         
            +
                    elsif comment? line
         
     | 
| 
      
 37 
     | 
    
         
            +
                      add_comment line
         
     | 
| 
      
 38 
     | 
    
         
            +
                    else
         
     | 
| 
      
 39 
     | 
    
         
            +
                      add_string line
         
     | 
| 
      
 40 
     | 
    
         
            +
                    end
         
     | 
| 
      
 41 
     | 
    
         
            +
                  end
         
     | 
| 
      
 42 
     | 
    
         
            +
                  start_new_translation #instance_variable has to be overwritten or errors can occur on next add
         
     | 
| 
      
 43 
     | 
    
         
            +
                  translations
         
     | 
| 
      
 44 
     | 
    
         
            +
                end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                def to_text
         
     | 
| 
      
 47 
     | 
    
         
            +
                  self.class.unique_translations(translations).map {|translation|
         
     | 
| 
      
 48 
     | 
    
         
            +
                    comment = translation.comment.to_s.split(/\n|\r\n/).map{|line|"##{line}\n"}*''
         
     | 
| 
      
 49 
     | 
    
         
            +
                    msgid_and_msgstr = if translation.plural?
         
     | 
| 
      
 50 
     | 
    
         
            +
                      msgids =
         
     | 
| 
      
 51 
     | 
    
         
            +
                      %Q(msgid "#{translation.msgid[0]}"\n)+
         
     | 
| 
      
 52 
     | 
    
         
            +
                      %Q(msgid_plural "#{translation.msgid[1]}"\n)
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                      msgstrs = []
         
     | 
| 
      
 55 
     | 
    
         
            +
                      translation.msgstr.each_with_index do |msgstr,index|
         
     | 
| 
      
 56 
     | 
    
         
            +
                        msgstrs << %Q(msgstr[#{index}] "#{msgstr}")
         
     | 
| 
      
 57 
     | 
    
         
            +
                      end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                      msgids + (msgstrs*"\n")
         
     | 
| 
      
 60 
     | 
    
         
            +
                    else
         
     | 
| 
      
 61 
     | 
    
         
            +
                      %Q(msgid "#{translation.msgid}"\n)+
         
     | 
| 
      
 62 
     | 
    
         
            +
                      %Q(msgstr "#{translation.msgstr}")
         
     | 
| 
      
 63 
     | 
    
         
            +
                    end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                    comment + msgid_and_msgstr
         
     | 
| 
      
 66 
     | 
    
         
            +
                  } * "\n\n"
         
     | 
| 
      
 67 
     | 
    
         
            +
                end
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
                private
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
                #e.g. # fuzzy
         
     | 
| 
      
 72 
     | 
    
         
            +
                def comment?(line)
         
     | 
| 
      
 73 
     | 
    
         
            +
                  line =~ /^\s*#/
         
     | 
| 
      
 74 
     | 
    
         
            +
                end
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
                def add_comment(line)
         
     | 
| 
      
 77 
     | 
    
         
            +
                  start_new_translation if translation_complete?
         
     | 
| 
      
 78 
     | 
    
         
            +
                  @current_translation.add_text(line.strip.sub('#','')+"\n",:to=>:comment)
         
     | 
| 
      
 79 
     | 
    
         
            +
                end
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
                #msgid "hello"
         
     | 
| 
      
 82 
     | 
    
         
            +
                def method_call?(line)
         
     | 
| 
      
 83 
     | 
    
         
            +
                  line =~ /^\s*[a-z]/
         
     | 
| 
      
 84 
     | 
    
         
            +
                end
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
                #msgid "hello" -> method call msgid + add string "hello"
         
     | 
| 
      
 87 
     | 
    
         
            +
                def parse_method_call(line)
         
     | 
| 
      
 88 
     | 
    
         
            +
                  method, string = line.match(/^\s*([a-z0-9_\[\]]+)(.*)/)[1..2]
         
     | 
| 
      
 89 
     | 
    
         
            +
                  raise "no method found" unless method
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
                  start_new_translation if method == 'msgid' and translation_complete?
         
     | 
| 
      
 92 
     | 
    
         
            +
                  @last_method = method.to_sym
         
     | 
| 
      
 93 
     | 
    
         
            +
                  add_string(string)
         
     | 
| 
      
 94 
     | 
    
         
            +
                end
         
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
      
 96 
     | 
    
         
            +
                #"hello" -> hello
         
     | 
| 
      
 97 
     | 
    
         
            +
                def add_string(string)
         
     | 
| 
      
 98 
     | 
    
         
            +
                  return if string.strip.empty?
         
     | 
| 
      
 99 
     | 
    
         
            +
                  raise "not string format: #{string.inspect} on line #{@line_number}" unless string.strip =~ /^['"](.*)['"]$/
         
     | 
| 
      
 100 
     | 
    
         
            +
                  @current_translation.add_text($1,:to=>@last_method)
         
     | 
| 
      
 101 
     | 
    
         
            +
                end
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
      
 103 
     | 
    
         
            +
                def translation_complete?
         
     | 
| 
      
 104 
     | 
    
         
            +
                  return false unless @current_translation
         
     | 
| 
      
 105 
     | 
    
         
            +
                  @current_translation.complete?
         
     | 
| 
      
 106 
     | 
    
         
            +
                end
         
     | 
| 
      
 107 
     | 
    
         
            +
              
         
     | 
| 
      
 108 
     | 
    
         
            +
                def store_translation
         
     | 
| 
      
 109 
     | 
    
         
            +
                  @translations += [@current_translation] if @current_translation.complete?
         
     | 
| 
      
 110 
     | 
    
         
            +
                end
         
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
      
 112 
     | 
    
         
            +
                def start_new_translation
         
     | 
| 
      
 113 
     | 
    
         
            +
                  store_translation if translation_complete?
         
     | 
| 
      
 114 
     | 
    
         
            +
                  @current_translation = Translation.new
         
     | 
| 
      
 115 
     | 
    
         
            +
                end
         
     | 
| 
      
 116 
     | 
    
         
            +
              end
         
     | 
| 
      
 117 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,44 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Pomo
         
     | 
| 
      
 2 
     | 
    
         
            +
              class Translation
         
     | 
| 
      
 3 
     | 
    
         
            +
                FUZZY_REGEX = /^\s*fuzzy\s*$/
         
     | 
| 
      
 4 
     | 
    
         
            +
                attr_accessor :msgid, :msgstr, :comment
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
                def add_text(text,options)
         
     | 
| 
      
 7 
     | 
    
         
            +
                  to = options[:to]
         
     | 
| 
      
 8 
     | 
    
         
            +
                  if to.to_sym == :msgid_plural
         
     | 
| 
      
 9 
     | 
    
         
            +
                    self.msgid = [msgid] unless msgid.is_a? Array
         
     | 
| 
      
 10 
     | 
    
         
            +
                    msgid[1] = msgid[1].to_s + text
         
     | 
| 
      
 11 
     | 
    
         
            +
                  elsif to.to_s =~ /^msgstr\[(\d)\]$/
         
     | 
| 
      
 12 
     | 
    
         
            +
                    self.msgstr ||= []
         
     | 
| 
      
 13 
     | 
    
         
            +
                    msgstr[$1.to_i] = msgstr[$1.to_i].to_s + text
         
     | 
| 
      
 14 
     | 
    
         
            +
                  else
         
     | 
| 
      
 15 
     | 
    
         
            +
                    #simple form
         
     | 
| 
      
 16 
     | 
    
         
            +
                    send("#{to}=",send(to).to_s+text)
         
     | 
| 
      
 17 
     | 
    
         
            +
                  end
         
     | 
| 
      
 18 
     | 
    
         
            +
                end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                def to_hash
         
     | 
| 
      
 21 
     | 
    
         
            +
                  {:msgid=>msgid,:msgstr=>msgstr,:comment=>comment}.reject{|k,value|value.nil?}
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                def complete?
         
     | 
| 
      
 25 
     | 
    
         
            +
                  not msgid.to_s.strip.empty? and not msgstr.nil?
         
     | 
| 
      
 26 
     | 
    
         
            +
                end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                def fuzzy?
         
     | 
| 
      
 29 
     | 
    
         
            +
                  comment =~ FUZZY_REGEX
         
     | 
| 
      
 30 
     | 
    
         
            +
                end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                def fuzzy=(value)
         
     | 
| 
      
 33 
     | 
    
         
            +
                  if value and not fuzzy?
         
     | 
| 
      
 34 
     | 
    
         
            +
                    add_text "\nfuzzy", :to=>:comment
         
     | 
| 
      
 35 
     | 
    
         
            +
                  else
         
     | 
| 
      
 36 
     | 
    
         
            +
                    self.comment = comment.to_s.split(/$/).reject{|line|line=~FUZZY_REGEX}.join("\n")
         
     | 
| 
      
 37 
     | 
    
         
            +
                  end
         
     | 
| 
      
 38 
     | 
    
         
            +
                end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                def plural?
         
     | 
| 
      
 41 
     | 
    
         
            +
                  msgid.is_a? Array or msgstr.is_a? Array
         
     | 
| 
      
 42 
     | 
    
         
            +
                end
         
     | 
| 
      
 43 
     | 
    
         
            +
              end
         
     | 
| 
      
 44 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,110 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require File.expand_path("../spec_helper", File.dirname(__FILE__))
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            include Pomo
         
     | 
| 
      
 4 
     | 
    
         
            +
            describe Pomo::PoFile do
         
     | 
| 
      
 5 
     | 
    
         
            +
              it "parses nothing" do
         
     | 
| 
      
 6 
     | 
    
         
            +
                PoFile.parse("").should be_empty
         
     | 
| 
      
 7 
     | 
    
         
            +
              end
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
              it "parses a simple msgid and msgstr" do
         
     | 
| 
      
 10 
     | 
    
         
            +
                t = PoFile.parse(%Q(msgid "xxx"\nmsgstr "yyy"))
         
     | 
| 
      
 11 
     | 
    
         
            +
                t[0].to_hash.should == {:msgid=>'xxx',:msgstr=>'yyy'}
         
     | 
| 
      
 12 
     | 
    
         
            +
              end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
              it "parses a simple msgid and msg with additional whitespace" do
         
     | 
| 
      
 15 
     | 
    
         
            +
                t = PoFile.parse(%Q(  msgid    "xxx"   \n   msgstr    "yyy"   ))
         
     | 
| 
      
 16 
     | 
    
         
            +
                t[0].to_hash.should == {:msgid=>'xxx',:msgstr=>'yyy'}
         
     | 
| 
      
 17 
     | 
    
         
            +
              end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
              it "parses a multiline msgid/msgstr" do
         
     | 
| 
      
 20 
     | 
    
         
            +
                t = PoFile.parse(%Q(msgid "xxx"\n"aaa"\n\n\nmsgstr ""\n"bbb"))
         
     | 
| 
      
 21 
     | 
    
         
            +
                t[0].to_hash.should == {:msgid=>'xxxaaa',:msgstr=>'bbb'}
         
     | 
| 
      
 22 
     | 
    
         
            +
              end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
              it "parses simple comments" do
         
     | 
| 
      
 25 
     | 
    
         
            +
                t = PoFile.parse(%Q(#test\nmsgid "xxx"\nmsgstr "yyy"))
         
     | 
| 
      
 26 
     | 
    
         
            +
                t[0].to_hash.should == {:msgid=>'xxx',:msgstr=>'yyy',:comment=>"test\n"}
         
     | 
| 
      
 27 
     | 
    
         
            +
              end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
              it "parses comments above msgstr" do
         
     | 
| 
      
 30 
     | 
    
         
            +
                t = PoFile.parse(%Q(#test\nmsgid "xxx"\n#another\nmsgstr "yyy"))
         
     | 
| 
      
 31 
     | 
    
         
            +
                t[0].to_hash.should == {:msgid=>'xxx',:msgstr=>'yyy',:comment=>"test\nanother\n"}
         
     | 
| 
      
 32 
     | 
    
         
            +
              end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
              describe "instance interface" do
         
     | 
| 
      
 35 
     | 
    
         
            +
                it "adds two different translations" do
         
     | 
| 
      
 36 
     | 
    
         
            +
                  p = PoFile.new
         
     | 
| 
      
 37 
     | 
    
         
            +
                  p.add_translations_from_text(%Q(msgid "xxx"\nmsgstr "yyy"))
         
     | 
| 
      
 38 
     | 
    
         
            +
                  p.add_translations_from_text(%Q(msgid "aaa"\nmsgstr "yyy"))
         
     | 
| 
      
 39 
     | 
    
         
            +
                  p.translations[1].to_hash.should == {:msgid=>'aaa',:msgstr=>'yyy'}
         
     | 
| 
      
 40 
     | 
    
         
            +
                end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                it "can be initialized with translations" do
         
     | 
| 
      
 43 
     | 
    
         
            +
                  p = PoFile.new(:translations=>['xxx'])
         
     | 
| 
      
 44 
     | 
    
         
            +
                  p.translations[0].should == 'xxx'
         
     | 
| 
      
 45 
     | 
    
         
            +
                end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                it "can be converted to text" do
         
     | 
| 
      
 48 
     | 
    
         
            +
                  text = %Q(msgid "xxx"\nmsgstr "aaa")
         
     | 
| 
      
 49 
     | 
    
         
            +
                  p = PoFile.new
         
     | 
| 
      
 50 
     | 
    
         
            +
                  p.add_translations_from_text(text)
         
     | 
| 
      
 51 
     | 
    
         
            +
                  p.to_text.should == text
         
     | 
| 
      
 52 
     | 
    
         
            +
                end
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                it "keeps uniqueness when converting to_text" do
         
     | 
| 
      
 55 
     | 
    
         
            +
                  text = %Q(msgid "xxx"\nmsgstr "aaa")
         
     | 
| 
      
 56 
     | 
    
         
            +
                  p = PoFile.new
         
     | 
| 
      
 57 
     | 
    
         
            +
                  p.add_translations_from_text(%Q(msgid "xxx"\nmsgstr "yyy"))
         
     | 
| 
      
 58 
     | 
    
         
            +
                  p.add_translations_from_text(text)
         
     | 
| 
      
 59 
     | 
    
         
            +
                  p.to_text.should == text
         
     | 
| 
      
 60 
     | 
    
         
            +
                end
         
     | 
| 
      
 61 
     | 
    
         
            +
              end
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
              it "adds plural translations" do
         
     | 
| 
      
 64 
     | 
    
         
            +
                t = PoFile.parse(%Q(msgid "singular"\nmsgid_plural "plural"\nmsgstr[0] "one"\nmsgstr[1] "many"))
         
     | 
| 
      
 65 
     | 
    
         
            +
                t[0].to_hash.should == {:msgid=>['singular','plural'],:msgstr=>['one','many']}
         
     | 
| 
      
 66 
     | 
    
         
            +
              end
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
              it "does not fail on empty string" do
         
     | 
| 
      
 69 
     | 
    
         
            +
                PoFile.parse(%Q(\n\n\n\n\n))
         
     | 
| 
      
 70 
     | 
    
         
            +
              end
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
              it "shows line number for invalid strings" do
         
     | 
| 
      
 73 
     | 
    
         
            +
                begin
         
     | 
| 
      
 74 
     | 
    
         
            +
                  PoFile.parse(%Q(\n\n\n\n\nmsgstr "))
         
     | 
| 
      
 75 
     | 
    
         
            +
                  flunk
         
     | 
| 
      
 76 
     | 
    
         
            +
                rescue Exception => e
         
     | 
| 
      
 77 
     | 
    
         
            +
                  e.to_s.should =~ /line 5/
         
     | 
| 
      
 78 
     | 
    
         
            +
                end
         
     | 
| 
      
 79 
     | 
    
         
            +
              end
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
              describe :to_text do
         
     | 
| 
      
 82 
     | 
    
         
            +
                it "is empty when not translations where added" do
         
     | 
| 
      
 83 
     | 
    
         
            +
                  PoFile.to_text([]).should == ""
         
     | 
| 
      
 84 
     | 
    
         
            +
                end
         
     | 
| 
      
 85 
     | 
    
         
            +
                
         
     | 
| 
      
 86 
     | 
    
         
            +
                it "preserves simple syntax" do
         
     | 
| 
      
 87 
     | 
    
         
            +
                  text = %Q(msgid "x"\nmsgstr "y")
         
     | 
| 
      
 88 
     | 
    
         
            +
                  PoFile.to_text(PoFile.parse(text)).should == text
         
     | 
| 
      
 89 
     | 
    
         
            +
                end
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
                it "adds comments" do
         
     | 
| 
      
 92 
     | 
    
         
            +
                  t = Pomo::Translation.new
         
     | 
| 
      
 93 
     | 
    
         
            +
                  t.msgid = 'a'
         
     | 
| 
      
 94 
     | 
    
         
            +
                  t.msgstr = 'b'
         
     | 
| 
      
 95 
     | 
    
         
            +
                  t.add_text("c\n",:to=>:comment)
         
     | 
| 
      
 96 
     | 
    
         
            +
                  t.add_text("d\n",:to=>:comment)
         
     | 
| 
      
 97 
     | 
    
         
            +
                  PoFile.to_text([t]).should == %Q(#c\n#d\nmsgid "a"\nmsgstr "b")
         
     | 
| 
      
 98 
     | 
    
         
            +
                end
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
                it "uses plural notation" do
         
     | 
| 
      
 101 
     | 
    
         
            +
                  text = %Q(#awesome\nmsgid "one"\nmsgid_plural "many"\nmsgstr[0] "1"\nmsgstr[1] "n")
         
     | 
| 
      
 102 
     | 
    
         
            +
                  PoFile.to_text(PoFile.parse(text)).should == text
         
     | 
| 
      
 103 
     | 
    
         
            +
                end
         
     | 
| 
      
 104 
     | 
    
         
            +
             
     | 
| 
      
 105 
     | 
    
         
            +
                it "only uses the latest of identicals msgids" do
         
     | 
| 
      
 106 
     | 
    
         
            +
                  text = %Q(msgid "one"\nmsgstr "1"\nmsgid "one"\nmsgstr "001")
         
     | 
| 
      
 107 
     | 
    
         
            +
                  PoFile.to_text(PoFile.parse(text)).should ==  %Q(msgid "one"\nmsgstr "001")
         
     | 
| 
      
 108 
     | 
    
         
            +
                end
         
     | 
| 
      
 109 
     | 
    
         
            +
              end
         
     | 
| 
      
 110 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,119 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require File.expand_path("../spec_helper", File.dirname(__FILE__))
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'pomo/translation'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            describe Pomo::Translation do
         
     | 
| 
      
 6 
     | 
    
         
            +
              describe :complete? do
         
     | 
| 
      
 7 
     | 
    
         
            +
                it{should_not be_complete}
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                it "is complete if it has a msgid and a msgstr" do
         
     | 
| 
      
 10 
     | 
    
         
            +
                  subject.msgid="x"
         
     | 
| 
      
 11 
     | 
    
         
            +
                  subject.msgstr = "y"
         
     | 
| 
      
 12 
     | 
    
         
            +
                  should be_complete
         
     | 
| 
      
 13 
     | 
    
         
            +
                end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                it "is not complete if it has an complete msgid" do
         
     | 
| 
      
 16 
     | 
    
         
            +
                  subject.msgid=""
         
     | 
| 
      
 17 
     | 
    
         
            +
                  should_not be_complete
         
     | 
| 
      
 18 
     | 
    
         
            +
                end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                it "is not complete if it has a nil msgstr" do
         
     | 
| 
      
 21 
     | 
    
         
            +
                  subject.msgid="x"
         
     | 
| 
      
 22 
     | 
    
         
            +
                  should_not be_complete
         
     | 
| 
      
 23 
     | 
    
         
            +
                end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                it "is complete if it has an complete msgstr" do
         
     | 
| 
      
 26 
     | 
    
         
            +
                  subject.msgid = "x"
         
     | 
| 
      
 27 
     | 
    
         
            +
                  subject.msgstr = ""
         
     | 
| 
      
 28 
     | 
    
         
            +
                  should be_complete
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
              end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
              describe :add_text do
         
     | 
| 
      
 33 
     | 
    
         
            +
                it "adds a simple msgid" do
         
     | 
| 
      
 34 
     | 
    
         
            +
                  subject.add_text("x",:to=>:msgid)
         
     | 
| 
      
 35 
     | 
    
         
            +
                  subject.msgid.should == "x"
         
     | 
| 
      
 36 
     | 
    
         
            +
                end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                it "converts msgid to plural when msgid_plural is added" do
         
     | 
| 
      
 39 
     | 
    
         
            +
                  subject.add_text("x",:to=>:msgid)
         
     | 
| 
      
 40 
     | 
    
         
            +
                  subject.add_text("y",:to=>:msgid_plural)
         
     | 
| 
      
 41 
     | 
    
         
            +
                  subject.msgid.should == ["x",'y']
         
     | 
| 
      
 42 
     | 
    
         
            +
                end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                it "can add additional text to msgid plurals" do
         
     | 
| 
      
 45 
     | 
    
         
            +
                  subject.add_text("y",:to=>:msgid_plural)
         
     | 
| 
      
 46 
     | 
    
         
            +
                  subject.add_text("a",:to=>:msgid_plural)
         
     | 
| 
      
 47 
     | 
    
         
            +
                  subject.msgid.should == [nil,'ya']
         
     | 
| 
      
 48 
     | 
    
         
            +
                end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                it "can add plural msggstr" do
         
     | 
| 
      
 51 
     | 
    
         
            +
                  subject.add_text("x",:to=>'msgstr[0]')
         
     | 
| 
      
 52 
     | 
    
         
            +
                  subject.msgstr.should == ['x']
         
     | 
| 
      
 53 
     | 
    
         
            +
                end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                it "can add multiple plural msggstr" do
         
     | 
| 
      
 56 
     | 
    
         
            +
                  subject.add_text("x",:to=>'msgstr[0]')
         
     | 
| 
      
 57 
     | 
    
         
            +
                  subject.add_text("a",:to=>'msgstr[1]')
         
     | 
| 
      
 58 
     | 
    
         
            +
                  subject.add_text("y",:to=>'msgstr[1]')
         
     | 
| 
      
 59 
     | 
    
         
            +
                  subject.msgstr.should == ['x','ay']
         
     | 
| 
      
 60 
     | 
    
         
            +
                end
         
     | 
| 
      
 61 
     | 
    
         
            +
              end
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
              describe :plural? do
         
     | 
| 
      
 64 
     | 
    
         
            +
                it{should_not be_plural}
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
                it "is plural if msgid is plural" do
         
     | 
| 
      
 67 
     | 
    
         
            +
                  subject.add_text("x",:to=>:msgid_plural)
         
     | 
| 
      
 68 
     | 
    
         
            +
                  should be_plural
         
     | 
| 
      
 69 
     | 
    
         
            +
                end
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
                it "is plural if msgstr is plural" do
         
     | 
| 
      
 72 
     | 
    
         
            +
                  subject.add_text("x",:to=>"msgstr[0]")
         
     | 
| 
      
 73 
     | 
    
         
            +
                  should be_plural
         
     | 
| 
      
 74 
     | 
    
         
            +
                end
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
                it "is not plural if simple strings where added" do
         
     | 
| 
      
 77 
     | 
    
         
            +
                  subject.msgid = "a"
         
     | 
| 
      
 78 
     | 
    
         
            +
                  subject.msgstr = "a"
         
     | 
| 
      
 79 
     | 
    
         
            +
                  should_not be_plural
         
     | 
| 
      
 80 
     | 
    
         
            +
                end
         
     | 
| 
      
 81 
     | 
    
         
            +
              end
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
              describe :fuzzy? do
         
     | 
| 
      
 84 
     | 
    
         
            +
                it{should_not be_fuzzy}
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
                it "is fuzzy if a fuzzy comment was added" do
         
     | 
| 
      
 87 
     | 
    
         
            +
                  subject.add_text("fuzzy",:to=>:comment)
         
     | 
| 
      
 88 
     | 
    
         
            +
                  should be_fuzzy
         
     | 
| 
      
 89 
     | 
    
         
            +
                end
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
                it "can be made fuzzy by using fuzzy=" do
         
     | 
| 
      
 92 
     | 
    
         
            +
                  subject.fuzzy = true
         
     | 
| 
      
 93 
     | 
    
         
            +
                  should be_fuzzy
         
     | 
| 
      
 94 
     | 
    
         
            +
                end
         
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
      
 96 
     | 
    
         
            +
                it "can be made unfuzzy by using fuzzy=" do
         
     | 
| 
      
 97 
     | 
    
         
            +
                  subject.fuzzy = false
         
     | 
| 
      
 98 
     | 
    
         
            +
                  should_not be_fuzzy
         
     | 
| 
      
 99 
     | 
    
         
            +
                end
         
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
      
 101 
     | 
    
         
            +
                it "changes comment when made fuzzy through fuzzy=" do
         
     | 
| 
      
 102 
     | 
    
         
            +
                  subject.comment = "hello"
         
     | 
| 
      
 103 
     | 
    
         
            +
                  subject.fuzzy = true
         
     | 
| 
      
 104 
     | 
    
         
            +
                  subject.comment.should == "hello\nfuzzy"
         
     | 
| 
      
 105 
     | 
    
         
            +
                end
         
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
      
 107 
     | 
    
         
            +
                it "changes empty comment when made fuzzy through fuzzy=" do
         
     | 
| 
      
 108 
     | 
    
         
            +
                  subject.fuzzy = true
         
     | 
| 
      
 109 
     | 
    
         
            +
                  subject.comment.should == "\nfuzzy"
         
     | 
| 
      
 110 
     | 
    
         
            +
                end
         
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
      
 112 
     | 
    
         
            +
                it "preserves comments when making fuzzy/unfuzzy" do
         
     | 
| 
      
 113 
     | 
    
         
            +
                  subject.comment = "hello"
         
     | 
| 
      
 114 
     | 
    
         
            +
                  subject.fuzzy = true
         
     | 
| 
      
 115 
     | 
    
         
            +
                  subject.fuzzy = false
         
     | 
| 
      
 116 
     | 
    
         
            +
                  subject.comment.should == "hello"
         
     | 
| 
      
 117 
     | 
    
         
            +
                end
         
     | 
| 
      
 118 
     | 
    
         
            +
              end
         
     | 
| 
      
 119 
     | 
    
         
            +
            end
         
     | 
    
        data/spec/spec_helper.rb
    ADDED
    
    
    
        metadata
    ADDED
    
    | 
         @@ -0,0 +1,63 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            --- !ruby/object:Gem::Specification 
         
     | 
| 
      
 2 
     | 
    
         
            +
            name: grosser-pomo
         
     | 
| 
      
 3 
     | 
    
         
            +
            version: !ruby/object:Gem::Version 
         
     | 
| 
      
 4 
     | 
    
         
            +
              version: 0.4.1
         
     | 
| 
      
 5 
     | 
    
         
            +
            platform: ruby
         
     | 
| 
      
 6 
     | 
    
         
            +
            authors: 
         
     | 
| 
      
 7 
     | 
    
         
            +
            - Michael Grosser
         
     | 
| 
      
 8 
     | 
    
         
            +
            autorequire: 
         
     | 
| 
      
 9 
     | 
    
         
            +
            bindir: bin
         
     | 
| 
      
 10 
     | 
    
         
            +
            cert_chain: []
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            date: 2009-03-31 00:00:00 -07:00
         
     | 
| 
      
 13 
     | 
    
         
            +
            default_executable: 
         
     | 
| 
      
 14 
     | 
    
         
            +
            dependencies: []
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
            description: 
         
     | 
| 
      
 17 
     | 
    
         
            +
            email: grosser.michael@gmail.com
         
     | 
| 
      
 18 
     | 
    
         
            +
            executables: []
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
            extensions: []
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
            extra_rdoc_files: []
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
            files: 
         
     | 
| 
      
 25 
     | 
    
         
            +
            - VERSION.yml
         
     | 
| 
      
 26 
     | 
    
         
            +
            - README.markdown
         
     | 
| 
      
 27 
     | 
    
         
            +
            - lib/pomo
         
     | 
| 
      
 28 
     | 
    
         
            +
            - lib/pomo/po_file.rb
         
     | 
| 
      
 29 
     | 
    
         
            +
            - lib/pomo/translation.rb
         
     | 
| 
      
 30 
     | 
    
         
            +
            - lib/pomo.rb
         
     | 
| 
      
 31 
     | 
    
         
            +
            - spec/pomo
         
     | 
| 
      
 32 
     | 
    
         
            +
            - spec/pomo/po_file_spec.rb
         
     | 
| 
      
 33 
     | 
    
         
            +
            - spec/pomo/translation_spec.rb
         
     | 
| 
      
 34 
     | 
    
         
            +
            - spec/spec_helper.rb
         
     | 
| 
      
 35 
     | 
    
         
            +
            has_rdoc: true
         
     | 
| 
      
 36 
     | 
    
         
            +
            homepage: http://github.com/grosser/pomo
         
     | 
| 
      
 37 
     | 
    
         
            +
            post_install_message: 
         
     | 
| 
      
 38 
     | 
    
         
            +
            rdoc_options: 
         
     | 
| 
      
 39 
     | 
    
         
            +
            - --inline-source
         
     | 
| 
      
 40 
     | 
    
         
            +
            - --charset=UTF-8
         
     | 
| 
      
 41 
     | 
    
         
            +
            require_paths: 
         
     | 
| 
      
 42 
     | 
    
         
            +
            - lib
         
     | 
| 
      
 43 
     | 
    
         
            +
            required_ruby_version: !ruby/object:Gem::Requirement 
         
     | 
| 
      
 44 
     | 
    
         
            +
              requirements: 
         
     | 
| 
      
 45 
     | 
    
         
            +
              - - ">="
         
     | 
| 
      
 46 
     | 
    
         
            +
                - !ruby/object:Gem::Version 
         
     | 
| 
      
 47 
     | 
    
         
            +
                  version: "0"
         
     | 
| 
      
 48 
     | 
    
         
            +
              version: 
         
     | 
| 
      
 49 
     | 
    
         
            +
            required_rubygems_version: !ruby/object:Gem::Requirement 
         
     | 
| 
      
 50 
     | 
    
         
            +
              requirements: 
         
     | 
| 
      
 51 
     | 
    
         
            +
              - - ">="
         
     | 
| 
      
 52 
     | 
    
         
            +
                - !ruby/object:Gem::Version 
         
     | 
| 
      
 53 
     | 
    
         
            +
                  version: "0"
         
     | 
| 
      
 54 
     | 
    
         
            +
              version: 
         
     | 
| 
      
 55 
     | 
    
         
            +
            requirements: []
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
            rubyforge_project: 
         
     | 
| 
      
 58 
     | 
    
         
            +
            rubygems_version: 1.2.0
         
     | 
| 
      
 59 
     | 
    
         
            +
            signing_key: 
         
     | 
| 
      
 60 
     | 
    
         
            +
            specification_version: 2
         
     | 
| 
      
 61 
     | 
    
         
            +
            summary: "Ruby/Gettext: A .po and .mo file parser/generator"
         
     | 
| 
      
 62 
     | 
    
         
            +
            test_files: []
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     |