PoParser 0.1.0
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.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.rspec +3 -0
- data/.travis.yml +7 -0
- data/CHANGELOG.md +4 -0
- data/Gemfile +6 -0
- data/Guardfile +9 -0
- data/LICENSE.txt +22 -0
- data/README.md +159 -0
- data/Rakefile +1 -0
- data/lib/poparser/comment.rb +28 -0
- data/lib/poparser/constants.rb +18 -0
- data/lib/poparser/entry.rb +154 -0
- data/lib/poparser/message.rb +51 -0
- data/lib/poparser/parser.rb +66 -0
- data/lib/poparser/po.rb +134 -0
- data/lib/poparser/tokenizer.rb +36 -0
- data/lib/poparser/transformer.rb +59 -0
- data/lib/poparser/version.rb +3 -0
- data/lib/poparser.rb +21 -0
- data/poparser.gemspec +31 -0
- data/spec/poparser/comment_spec.rb +16 -0
- data/spec/poparser/entry_spec.rb +85 -0
- data/spec/poparser/fixtures/multiline.po +6 -0
- data/spec/poparser/fixtures/plural.po +6 -0
- data/spec/poparser/fixtures/tokenizer.po +7 -0
- data/spec/poparser/message_spec.rb +34 -0
- data/spec/poparser/parser_spec.rb +69 -0
- data/spec/poparser/po_spec.rb +48 -0
- data/spec/poparser/poparser_spec.rb +10 -0
- data/spec/poparser/test.po +51 -0
- data/spec/poparser/tokenizer_spec.rb +14 -0
- data/spec/poparser/transformer_spec.rb +24 -0
- data/spec/poparser/version_spec.rb +8 -0
- data/spec/spec_helper.rb +22 -0
- metadata +191 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
require 'ap'
|
|
2
|
+
|
|
3
|
+
module PoParser
|
|
4
|
+
# Feed each block of PO file to Parser.
|
|
5
|
+
class Tokenizer
|
|
6
|
+
def initialize
|
|
7
|
+
@parser = Parser.new
|
|
8
|
+
@po = Po.new
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def extract_entries(path)
|
|
12
|
+
@po.path = path
|
|
13
|
+
block = ''
|
|
14
|
+
File.open(path, 'r') do |f|
|
|
15
|
+
f.each_line do |line|
|
|
16
|
+
if line.match(/^\n$/)
|
|
17
|
+
@po << parse_block(block)
|
|
18
|
+
block = ''
|
|
19
|
+
elsif f.eof?
|
|
20
|
+
block += line
|
|
21
|
+
@po << parse_block(block)
|
|
22
|
+
else
|
|
23
|
+
block += line
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
@po
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
def parse_block(block)
|
|
32
|
+
parsed_hash = @parser.parse(block)
|
|
33
|
+
Transformer.new.transform(parsed_hash)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
module PoParser
|
|
2
|
+
# Converts the array returned from {Parser} to a useable hash
|
|
3
|
+
class Transformer
|
|
4
|
+
def initialize
|
|
5
|
+
@hash = {}
|
|
6
|
+
super
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def transform(obj)
|
|
10
|
+
apply_transforms(obj).each do |hash|
|
|
11
|
+
merge(hash)
|
|
12
|
+
end
|
|
13
|
+
@hash
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
private
|
|
17
|
+
# @Note: There was a problem applying all rules together. I don't know
|
|
18
|
+
# in what order Parslet run rules, but it's not in order. I end up
|
|
19
|
+
# making to seperate transform and feed one output to the other.
|
|
20
|
+
def first_transform
|
|
21
|
+
Parslet::Transform.new do
|
|
22
|
+
rule(:msgstr_plural => subtree(:plural)) do
|
|
23
|
+
if plural.is_a? Array
|
|
24
|
+
{ "msgstr\[#{plural[0][:plural_id]}\]".to_sym => plural }
|
|
25
|
+
else
|
|
26
|
+
{ "msgstr\[#{plural[:plural_id]}\]".to_sym => plural }
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
rule(:text => simple(:txt)) { txt.to_s.chomp }
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def second_transform
|
|
35
|
+
Parslet::Transform.new do
|
|
36
|
+
rule(:plural_id => simple(:id), :text => simple(:txt)) { txt }
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def apply_transforms(hash)
|
|
41
|
+
first = first_transform.apply(hash)
|
|
42
|
+
second_transform.apply(first)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Merges two hashed together. If both hashes have common keys it
|
|
46
|
+
# will create an array of them
|
|
47
|
+
#
|
|
48
|
+
# @return [Hash]
|
|
49
|
+
def merge(newh)
|
|
50
|
+
@hash.merge!(newh) do |key, oldval, newval|
|
|
51
|
+
if oldval.is_a? Array
|
|
52
|
+
oldval << newval
|
|
53
|
+
else
|
|
54
|
+
Array.new [oldval, newval]
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
data/lib/poparser.rb
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# External Libs
|
|
2
|
+
require 'parslet'
|
|
3
|
+
|
|
4
|
+
# Local files
|
|
5
|
+
require 'poparser/constants'
|
|
6
|
+
require 'poparser/parser'
|
|
7
|
+
require 'poparser/transformer'
|
|
8
|
+
require 'poparser/tokenizer'
|
|
9
|
+
require 'poparser/comment'
|
|
10
|
+
require 'poparser/message'
|
|
11
|
+
require 'poparser/entry'
|
|
12
|
+
require 'poparser/po'
|
|
13
|
+
require 'poparser/version'
|
|
14
|
+
|
|
15
|
+
module PoParser
|
|
16
|
+
class << self
|
|
17
|
+
def parse(path)
|
|
18
|
+
Tokenizer.new.extract_entries(path)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
data/poparser.gemspec
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
+
require 'poparser/version'
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |spec|
|
|
7
|
+
spec.name = "PoParser"
|
|
8
|
+
spec.version = PoParser::VERSION
|
|
9
|
+
spec.authors = ["Arash Mousavi"]
|
|
10
|
+
spec.email = ["mousavi.arash@gmail.com"]
|
|
11
|
+
spec.summary = %q{A PO file parser, editor and generator.}
|
|
12
|
+
spec.description = %q{A PO file parser, editor and generator. PO files are translation files generated by GNU/Gettext tool.}
|
|
13
|
+
spec.homepage = "http://github.com/arashm/poparser"
|
|
14
|
+
spec.license = "MIT"
|
|
15
|
+
|
|
16
|
+
spec.files = `git ls-files`.split($/)
|
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
|
18
|
+
spec.test_files = spec.files.grep(%r{^spec/})
|
|
19
|
+
spec.require_paths = ["lib"]
|
|
20
|
+
|
|
21
|
+
# Runtime deps
|
|
22
|
+
spec.add_runtime_dependency "parslet"
|
|
23
|
+
|
|
24
|
+
# Development deps
|
|
25
|
+
spec.add_development_dependency "bundler", "~> 1.5"
|
|
26
|
+
spec.add_development_dependency "rake"
|
|
27
|
+
spec.add_development_dependency "rspec", "~> 2.14"
|
|
28
|
+
spec.add_development_dependency "guard-rspec"
|
|
29
|
+
spec.add_development_dependency "pry-debugger"
|
|
30
|
+
spec.add_development_dependency "awesome_print"
|
|
31
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require 'spec_helper'
|
|
3
|
+
|
|
4
|
+
describe PoParser::Comment do
|
|
5
|
+
it 'converts the comment to string' do
|
|
6
|
+
comment = PoParser::Comment.new(:translator_comment, "this is a line")
|
|
7
|
+
result = "# this is a line\n"
|
|
8
|
+
expect(comment.to_s(true)).to eq(result)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it 'converts array of same comment to string' do
|
|
12
|
+
comment = PoParser::Comment.new(:translator_comment, ["this is a line", "this is another line"])
|
|
13
|
+
result = "# this is a line\n# this is another line\n"
|
|
14
|
+
expect(comment.to_s(true)).to eq(result)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require 'spec_helper'
|
|
3
|
+
|
|
4
|
+
describe PoParser::Entry do
|
|
5
|
+
before(:each) do
|
|
6
|
+
@entry = PoParser::Entry.new
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
let(:labels) do
|
|
10
|
+
[:refrence, :extracted_comment, :flag, :previous_untraslated_string,
|
|
11
|
+
:translator_comment, :msgid, :msgid_plural, :msgstr, :msgctxt]
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it 'should respond to labels' do
|
|
15
|
+
labels.each do |label|
|
|
16
|
+
@entry.should respond_to label
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it 'should show a hash presentation of a entry' do
|
|
21
|
+
@entry.msgid = 'string'
|
|
22
|
+
@entry.msgstr = 'reshte'
|
|
23
|
+
expect(@entry.to_h).to eq({:msgid=>"string", :msgstr=>"reshte"})
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it 'should translate the entry' do
|
|
27
|
+
@entry.translate ('this entry is translated')
|
|
28
|
+
expect(@entry.msgstr.to_s).to eq 'this entry is translated'
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it 'checks if the entry is translated' do
|
|
32
|
+
expect(@entry.translated?).to be_false
|
|
33
|
+
@entry.translate ''
|
|
34
|
+
expect(@entry.translated?).to be_false
|
|
35
|
+
@entry.translate 'translated'
|
|
36
|
+
expect(@entry.complete?).to be_true
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
context 'Plural' do
|
|
40
|
+
it 'returns false if it\'s not plural' do
|
|
41
|
+
expect(@entry.plural?).to be_false
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it 'returns true if it\'s plural' do
|
|
45
|
+
@entry.msgid_plural = 'sth'
|
|
46
|
+
expect(@entry.plural?).to be_true
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
context 'Flags' do
|
|
51
|
+
it 'should check if a entry is fuzzy' do
|
|
52
|
+
expect(@entry.fuzzy?).to be_false
|
|
53
|
+
@entry.flag = 'fuzzy'
|
|
54
|
+
expect(@entry.fuzzy?).to be_true
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
it 'should flag a entry as fuzzy' do
|
|
58
|
+
expect(@entry.flag_as_fuzzy).to be_true
|
|
59
|
+
expect(@entry.flag).to eq('fuzzy')
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it 'should be able to set a custome flag' do
|
|
63
|
+
expect(@entry.flag_as 'python-format').to be_true
|
|
64
|
+
expect(@entry.flag).to eq('python-format')
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
context 'Convertion to string' do
|
|
69
|
+
it 'should be able to show string representaion of entries' do
|
|
70
|
+
@entry.flag = 'fuzzy'
|
|
71
|
+
@entry.msgid = 'string'
|
|
72
|
+
@entry.msgstr = 'reshte'
|
|
73
|
+
result = "#, fuzzy\nmsgid \"string\"\nmsgstr \"reshte\"\n"
|
|
74
|
+
expect(@entry.to_s).to eq result
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
it 'convert multiline entries to string' do
|
|
78
|
+
@entry.flag = 'fuzzy'
|
|
79
|
+
@entry.msgid = ['first line', 'second line']
|
|
80
|
+
@entry.msgstr = ['first line', 'second line']
|
|
81
|
+
result = "#, fuzzy\nmsgid \"\"\n\"first line\"\n\"second line\"\nmsgstr \"\"\n\"first line\"\n\"second line\"\n"
|
|
82
|
+
expect(@entry.to_s).to eq(result)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require 'spec_helper'
|
|
3
|
+
|
|
4
|
+
describe PoParser::Message do
|
|
5
|
+
it 'converts the message to string' do
|
|
6
|
+
message = PoParser::Message.new(:msgid, "this is a line")
|
|
7
|
+
result = "msgid \"this is a line\"\n"
|
|
8
|
+
expect(message.to_s(true)).to eq(result)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it 'converts array of same message to string' do
|
|
12
|
+
message = PoParser::Message.new(:msgid, ["this is a line", "this is another line"])
|
|
13
|
+
result = "msgid \"\"\n\"this is a line\"\n\"this is another line\"\n"
|
|
14
|
+
expect(message.to_s(true)).to eq(result)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it 'shows one line string for multiline entries' do
|
|
18
|
+
message = PoParser::Message.new(:msgid, ["", "this is a line ", "this is another line"])
|
|
19
|
+
result = "this is a line this is another line"
|
|
20
|
+
expect(message.str).to eq result
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it 'converts plural msgstr correctly' do
|
|
24
|
+
message = PoParser::Message.new(:"msgstr[0]", "this is a line")
|
|
25
|
+
result = "msgstr[0] \"this is a line\"\n"
|
|
26
|
+
expect(message.to_s(true)).to eq(result)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it 'converts multiline plural msgstr correctly' do
|
|
30
|
+
message = PoParser::Message.new(:"msgstr[0]", ["this is a line", "this is another line"])
|
|
31
|
+
result = "msgstr[0] \"\"\n\"this is a line\"\n\"this is another line\"\n"
|
|
32
|
+
expect(message.to_s(true)).to eq(result)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
#encoding: utf-8
|
|
2
|
+
require "spec_helper"
|
|
3
|
+
|
|
4
|
+
describe PoParser::Parser do
|
|
5
|
+
let(:po) { PoParser::Parser.new }
|
|
6
|
+
|
|
7
|
+
context(:comments) do
|
|
8
|
+
|
|
9
|
+
let(:tc) { po.translator_comment }
|
|
10
|
+
let(:rc) { po.refrence }
|
|
11
|
+
let(:ec) { po.extracted_comment }
|
|
12
|
+
let(:fc) { po.flag }
|
|
13
|
+
let(:pusc){ po.previous_untraslated_string }
|
|
14
|
+
|
|
15
|
+
it 'parses the translator comment' do
|
|
16
|
+
tc.should parse("# Persian translation for damned-lies 123123\n")
|
|
17
|
+
tc.should parse("# Copyright (C) 2012 damned-lies's COPYRIGHT HOLDER\n")
|
|
18
|
+
tc.should parse("# Arash Mousavi <mousavi.arash@gmail.com>, 2014.\n")
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it 'parses refrence comment' do
|
|
22
|
+
rc.should parse("#: database-content.py:1 database-content.py:129 settings.py:52\n")
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it 'parses extracted_comment' do
|
|
26
|
+
ec.should parse("#. database-content.py:1 database-content.py:129 settings.py:52\n")
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it 'parses flag_comment' do
|
|
30
|
+
fc.should parse("#, python-format\n")
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it 'parses previous_untraslated_string' do
|
|
34
|
+
pusc.should parse("#| msgid \"\"\n")
|
|
35
|
+
pusc.should parse("#| \"Hello,\\n\"\n")
|
|
36
|
+
pusc.should parse("#| \"The new state of %(module)s - %(branch)s - %(domain)s (%(language)s) is \"\n")
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
context 'Entries' do
|
|
42
|
+
let(:msgid) { po.msgid }
|
|
43
|
+
let(:msgstr){ po.msgstr }
|
|
44
|
+
let(:pofile){ Pathname.new('spec/poparser/fixtures/multiline.po').realpath }
|
|
45
|
+
|
|
46
|
+
it 'parses msgid' do
|
|
47
|
+
msgid.should parse "msgid \"The new state of %(module)s - %(branch)s - %(domain)s (%(language)s) is now \"\n"
|
|
48
|
+
msgid.should parse "msgid \"The new \"state\" of %(module)s - %(branch)s - %(domain)s (%(language)s) is now \"\n"
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it 'parses msgstr' do
|
|
52
|
+
msgstr.should parse "msgstr \"The new state of %(module)s - %(branch)s - %(domain)s (%(language)s) is now \"\n"
|
|
53
|
+
msgstr.should parse "msgstr \"فعالیت نامعتبر. شاید یک نفر دیگر دقیقا قبل از شما یک فعالیت دیگر ارسال کرده ۱۲۳۱۲۳۱safda \"\n"
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it 'parses multiline entries' do
|
|
57
|
+
data = pofile.read
|
|
58
|
+
result = [{:msgid=>[{:text=>""}, {:text=>"first"}, {:text=>"second"}]}, {:msgstr=>[{:text=>""}, {:text=>"aval"}, {:text=>"dovom"}]}]
|
|
59
|
+
expect(po.parse data).to eq(result)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it 'parses plural msgstr entries' do
|
|
63
|
+
str = "msgstr[0] \"\""
|
|
64
|
+
result = [{:msgstr_plural=>{:plural_id=>"0", :text=>""}}]
|
|
65
|
+
expect(po.parse(str)).to eq(result)
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require 'spec_helper'
|
|
3
|
+
|
|
4
|
+
describe PoParser::Po do
|
|
5
|
+
let (:entry) do
|
|
6
|
+
{
|
|
7
|
+
translator_comment: 'comment',
|
|
8
|
+
refrence: 'refrence comment',
|
|
9
|
+
msgid: 'untranslated',
|
|
10
|
+
msgstr: 'translated string'
|
|
11
|
+
}
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
before(:each) do
|
|
15
|
+
@po = PoParser::Po.new
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it 'should be able to add an entry to Po' do
|
|
19
|
+
# << is an alias for Po#add_entry
|
|
20
|
+
expect(@po << entry).to be_a_kind_of PoParser::Entry
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it 'should be able to add multiple entries' do
|
|
24
|
+
entries = [entry, entry.dup]
|
|
25
|
+
expect(@po << entries).to be_a_kind_of Array
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it 'returns all fuzzy entries' do
|
|
29
|
+
entry2, entry3 = entry.dup, entry.dup
|
|
30
|
+
[entry2, entry3].each { |en| en[:flag] = 'fuzzy' }
|
|
31
|
+
@po << [entry, entry2, entry3]
|
|
32
|
+
expect(@po.fuzzy.size).to eq 2
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it 'returns all untraslated strings' do
|
|
36
|
+
entry2, entry3 = entry.dup, entry.dup
|
|
37
|
+
[entry2, entry3].each { |en| en[:msgstr] = '' }
|
|
38
|
+
@po << [entry, entry2, entry3]
|
|
39
|
+
expect(@po.untranslated.size).to eq 2
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it 'shows stats' do
|
|
43
|
+
entry2, entry3 = entry.dup, entry.dup
|
|
44
|
+
[entry2, entry3].each { |en| en[:msgstr] = '' }
|
|
45
|
+
@po << [entry, entry2, entry3]
|
|
46
|
+
ap @po.stats
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Persian translation for damned-lies.
|
|
2
|
+
# Copyright (C) 2012 damned-lies's COPYRIGHT HOLDER
|
|
3
|
+
# This file is distributed under the same license as the damned-lies package.
|
|
4
|
+
# Arash Mousavi <mousavi.arash@gmail.com>, 2014.
|
|
5
|
+
#
|
|
6
|
+
msgid ""
|
|
7
|
+
msgstr ""
|
|
8
|
+
"Project-Id-Version: damned-lies master\n"
|
|
9
|
+
"Report-Msgid-Bugs-To: \n"
|
|
10
|
+
"POT-Creation-Date: 2012-05-04 12:56+0000\n"
|
|
11
|
+
"PO-Revision-Date: 2014-05-15 22:24+0330\n"
|
|
12
|
+
"Last-Translator: Arash Mousavi <mousavi.arash@gmail.com>\n"
|
|
13
|
+
"Language-Team: Persian <fa@li.org>\n"
|
|
14
|
+
"MIME-Version: 1.0\n"
|
|
15
|
+
"Content-Type: text/plain; charset=UTF-8\n"
|
|
16
|
+
"Content-Transfer-Encoding: 8bit\n"
|
|
17
|
+
"Plural-Forms: nplurals=1; plural=0;\n"
|
|
18
|
+
"X-Generator: Poedit 1.6.4\n"
|
|
19
|
+
|
|
20
|
+
#: database-content.py:1 database-content.py:129 settings.py:52
|
|
21
|
+
msgid "Afrikaans"
|
|
22
|
+
msgstr "آفریقایی"
|
|
23
|
+
|
|
24
|
+
#: templates/vertimus/vertimus_detail.html:105
|
|
25
|
+
#, python-format
|
|
26
|
+
msgid " including <a href=\"%(img_url)s\">%(stats)s image</a>"
|
|
27
|
+
msgid_plural " including <a href=\"%(img_url)s\">%(stats)s images</a>"
|
|
28
|
+
msgstr[0] ""
|
|
29
|
+
msgstr[1] ""
|
|
30
|
+
|
|
31
|
+
#: templates/vertimus/vertimus_detail.html:136 vertimus/forms.py:79
|
|
32
|
+
msgid "Invalid action. Someone probably posted another action just before you."
|
|
33
|
+
msgstr ""
|
|
34
|
+
"فعالیت نامعتبر. شاید یک نفر دیگر دقیقا قبل از شما یک فعالیت دیگر ارسال کرده "
|
|
35
|
+
"است."
|
|
36
|
+
|
|
37
|
+
#: vertimus/models.py:470
|
|
38
|
+
#, python-format
|
|
39
|
+
#| msgid ""
|
|
40
|
+
#| "Hello,\n"
|
|
41
|
+
#| "\n"
|
|
42
|
+
#| "The new state of %(module)s - %(branch)s - %(domain)s (%(language)s) is "
|
|
43
|
+
#| "now '%(new_state)s'.\n"
|
|
44
|
+
#| "%(url)s\n"
|
|
45
|
+
#| "\n"
|
|
46
|
+
msgid ""
|
|
47
|
+
"The new state of %(module)s - %(branch)s - %(domain)s (%(language)s) is now "
|
|
48
|
+
"'%(new_state)s'."
|
|
49
|
+
msgstr ""
|
|
50
|
+
"وضعیت جدید %(module)s - %(branch)s - %(domain)s (%(language)s) هماکنون "
|
|
51
|
+
"«%(new_state)s» است."
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require "spec_helper.rb"
|
|
3
|
+
|
|
4
|
+
describe PoParser::Tokenizer do
|
|
5
|
+
let(:token) { PoParser::Tokenizer.new }
|
|
6
|
+
let(:po_file){ Pathname.new('spec/poparser/fixtures/tokenizer.po').realpath }
|
|
7
|
+
let(:result) { [{:refrence=>"templates:105", :msgid=>"Afrikaans", :msgstr=>"آفریقایی"}, {:flag=>"fuzzy", :msgid=>"Afrikaans", :msgstr=>"آفریقایی" }] }
|
|
8
|
+
|
|
9
|
+
it 'should be able to extracts entries' do
|
|
10
|
+
expect(
|
|
11
|
+
token.extract_entries(po_file).to_h
|
|
12
|
+
).to eq(result)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require "spec_helper"
|
|
3
|
+
|
|
4
|
+
describe PoParser::Transformer do
|
|
5
|
+
let(:trans){ PoParser::Transformer.new }
|
|
6
|
+
|
|
7
|
+
it 'transforms the returned array from parslet to a usable hash' do
|
|
8
|
+
parslet_array = [{:translator_comment=>"Persian translation\n"}, {:translator_comment=>"Copyright\n"}, {:msgid=>"\"test\"\n"}]
|
|
9
|
+
transformed_hash = {:translator_comment=>["Persian translation\n", "Copyright\n"], :msgid=>"\"test\"\n"}
|
|
10
|
+
expect(trans.transform(parslet_array)).to eq(transformed_hash)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it 'transforms plural msgstr forms correctly' do
|
|
14
|
+
data = [{:msgstr_plural=>{:plural_id=>"0", :text=>"this is a txt"}}]
|
|
15
|
+
result = { :'msgstr[0]' => "this is a txt" }
|
|
16
|
+
expect(trans.transform(data)).to eq(result)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it 'transforms multiline plural msgstr forms correctly' do
|
|
20
|
+
data = [{:msgstr_plural=>[{:plural_id=>"0", :text=>"this is a txt"}, {:text => 'some text'}]}]
|
|
21
|
+
result = { :'msgstr[0]' => ["this is a txt", "some text"] }
|
|
22
|
+
expect(trans.transform(data)).to eq(result)
|
|
23
|
+
end
|
|
24
|
+
end
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
|
2
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
|
3
|
+
# Require this file using `require "spec_helper"` to ensure that it is only
|
|
4
|
+
# loaded once.
|
|
5
|
+
#
|
|
6
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
|
7
|
+
require 'poparser'
|
|
8
|
+
require 'parslet/rig/rspec'
|
|
9
|
+
require 'coveralls'
|
|
10
|
+
Coveralls.wear!
|
|
11
|
+
|
|
12
|
+
RSpec.configure do |config|
|
|
13
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
|
14
|
+
config.run_all_when_everything_filtered = true
|
|
15
|
+
config.filter_run :focus
|
|
16
|
+
|
|
17
|
+
# Run specs in random order to surface order dependencies. If you find an
|
|
18
|
+
# order dependency and want to debug it, you can fix the order by providing
|
|
19
|
+
# the seed, which is printed after each run.
|
|
20
|
+
# --seed 1234
|
|
21
|
+
config.order = 'random'
|
|
22
|
+
end
|