apfel 0.0.2
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/Gemfile +2 -0
- data/Gemfile.lock +34 -0
- data/README.md +56 -0
- data/Rakefile +17 -0
- data/apfel.gemspec +26 -0
- data/lib/apfel/dot_strings_parser.rb +54 -0
- data/lib/apfel/kv_pair.rb +29 -0
- data/lib/apfel/line.rb +72 -0
- data/lib/apfel/parsed_dot_strings.rb +65 -0
- data/lib/apfel/reader.rb +18 -0
- data/lib/apfel/version.rb +3 -0
- data/lib/apfel.rb +16 -0
- data/spec/apfel_spec.rb +58 -0
- data/spec/parsed_dot_strings_spec.rb +116 -0
- data/spec/reader_spec.rb +27 -0
- data/spec/spec_helper.rb +23 -0
- metadata +119 -0
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
apfel (0.0.2)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: https://rubygems.org/
|
8
|
+
specs:
|
9
|
+
coderay (1.0.8)
|
10
|
+
diff-lcs (1.1.3)
|
11
|
+
method_source (0.8.1)
|
12
|
+
pry (0.9.10)
|
13
|
+
coderay (~> 1.0.5)
|
14
|
+
method_source (~> 0.8)
|
15
|
+
slop (~> 3.3.1)
|
16
|
+
rake (0.9.2.2)
|
17
|
+
rspec (2.12.0)
|
18
|
+
rspec-core (~> 2.12.0)
|
19
|
+
rspec-expectations (~> 2.12.0)
|
20
|
+
rspec-mocks (~> 2.12.0)
|
21
|
+
rspec-core (2.12.0)
|
22
|
+
rspec-expectations (2.12.0)
|
23
|
+
diff-lcs (~> 1.1.3)
|
24
|
+
rspec-mocks (2.12.0)
|
25
|
+
slop (3.3.3)
|
26
|
+
|
27
|
+
PLATFORMS
|
28
|
+
ruby
|
29
|
+
|
30
|
+
DEPENDENCIES
|
31
|
+
apfel!
|
32
|
+
pry
|
33
|
+
rake
|
34
|
+
rspec
|
data/README.md
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
# Apfel
|
2
|
+
|
3
|
+
## Introduction
|
4
|
+
|
5
|
+
Apfel is simple parser for .strings (DotStrings) files written in Ruby. DotStrings files are used by Apple platforms for localization. Apfel reads DotStrings files, parses them for key-value pairs and comments.
|
6
|
+
|
7
|
+
Once in the form of a hash, the content of the DotStrings file can easily be
|
8
|
+
rebuilt as JSON, XML and RESX (with the help of Builder https://github.com/jimweirich/builder) and more!
|
9
|
+
|
10
|
+
## Use
|
11
|
+
|
12
|
+
To start using Apfel first require the gem
|
13
|
+
```Ruby
|
14
|
+
require 'apfel'
|
15
|
+
```
|
16
|
+
|
17
|
+
Next, pass Apfel the .strings file you want to parse:
|
18
|
+
```Ruby
|
19
|
+
parsed_file = Apfel.parse('path/to/file')
|
20
|
+
```
|
21
|
+
|
22
|
+
Once the file has been parsed, you can do many things with it:
|
23
|
+
```Ruby
|
24
|
+
# Turn it into a ruby hash (includes comments)
|
25
|
+
parsed_file.to_hash
|
26
|
+
|
27
|
+
# Turn it into json (includes comments)
|
28
|
+
parsed_file.to_json
|
29
|
+
|
30
|
+
# With either #to_hash or #to_json you can specify
|
31
|
+
# whether you want the comments included
|
32
|
+
parsed_file.to_hash(with_comments: false)
|
33
|
+
|
34
|
+
# Get all the keys as an array
|
35
|
+
parsed_file.keys
|
36
|
+
|
37
|
+
# Get all the values as an array
|
38
|
+
parsed_file.values
|
39
|
+
|
40
|
+
# Return an array of key-value hashes
|
41
|
+
parsed_file.key_values
|
42
|
+
|
43
|
+
# Return an array of key-comment hashes
|
44
|
+
parsed_file.comments
|
45
|
+
|
46
|
+
# Return an array of all the comments without their keys
|
47
|
+
parsed_file.comments(with_keys: false)
|
48
|
+
```
|
49
|
+
## Contributing
|
50
|
+
|
51
|
+
1. Fork it
|
52
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
53
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
54
|
+
4. Commit tests (they should pass when rake is run)
|
55
|
+
5. Push to the branch (`git push origin my-new-feature`)
|
56
|
+
6. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
begin
|
3
|
+
require 'bundler/setup'
|
4
|
+
rescue LoadError
|
5
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
6
|
+
end
|
7
|
+
Bundler::GemHelper.install_tasks
|
8
|
+
|
9
|
+
require 'rspec/core/rake_task'
|
10
|
+
RSpec::Core::RakeTask.new do |t|
|
11
|
+
t.rspec_opts = ["--color", '--order rand']
|
12
|
+
end
|
13
|
+
|
14
|
+
desc "Run all tests and documentation checks"
|
15
|
+
task :qa => [:spec]
|
16
|
+
|
17
|
+
task :default => :qa
|
data/apfel.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
apfel_folder = File.join(File.dirname(__FILE__), 'lib', 'apfel')
|
3
|
+
$:.unshift apfel_folder
|
4
|
+
require "version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "apfel"
|
8
|
+
s.version = Apfel::VERSION
|
9
|
+
s.platform = Gem::Platform::RUBY
|
10
|
+
s.authors = ["Ryan Levick"]
|
11
|
+
s.email = ["ryan.levick@gmail.com"]
|
12
|
+
s.homepage = "https://github.com/rlevick/apfel"
|
13
|
+
s.summary = %q{Simple parser for DotStrings Files}
|
14
|
+
s.description = %q{Parse valid .strings files for easy conversion to other formats}
|
15
|
+
|
16
|
+
s.add_development_dependency "rspec"
|
17
|
+
s.add_development_dependency "rake"
|
18
|
+
s.add_development_dependency "pry"
|
19
|
+
|
20
|
+
s.rubyforge_project = "apfel"
|
21
|
+
|
22
|
+
s.files = `git ls-files`.split("\n")
|
23
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
24
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
25
|
+
s.require_paths = ["lib"]
|
26
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Apfel
|
2
|
+
require 'line'
|
3
|
+
require 'kv_pair'
|
4
|
+
class DotStringsParser
|
5
|
+
KEY = "KEY"
|
6
|
+
COMMENT = "COMMENT"
|
7
|
+
|
8
|
+
def initialize(read_file, parsed_file = ParsedDotStrings.new)
|
9
|
+
@read_file = read_file
|
10
|
+
@parsed_file = parsed_file
|
11
|
+
end
|
12
|
+
|
13
|
+
def parse_file
|
14
|
+
state = KEY
|
15
|
+
current_comment = nil
|
16
|
+
comments_for_keys = {}
|
17
|
+
@read_file.each do |content_line|
|
18
|
+
current_line = Line.new(content_line)
|
19
|
+
next if current_line.empty_line? && current_line.in_comment == false
|
20
|
+
|
21
|
+
#State machine to parse the comments
|
22
|
+
case state
|
23
|
+
when KEY
|
24
|
+
if current_line.whole_comment?
|
25
|
+
unless current_line.whole_comment.strip == 'No comment provided by engineer.'
|
26
|
+
current_comment = current_line.whole_comment
|
27
|
+
end
|
28
|
+
elsif current_line.key_value_pair? && current_comment
|
29
|
+
comments_for_keys[current_line.key] = current_comment
|
30
|
+
current_comment = nil
|
31
|
+
elsif current_line.open_comment?
|
32
|
+
current_comment = current_line.open_comment + "\n"
|
33
|
+
state = COMMENT
|
34
|
+
end
|
35
|
+
when COMMENT
|
36
|
+
if current_line.close_comment?
|
37
|
+
current_comment += current_line.close_comment
|
38
|
+
state = KEY
|
39
|
+
else
|
40
|
+
current_line.in_comment = true
|
41
|
+
current_comment = current_comment + current_line.content + "\n"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
unless current_line.is_comment?
|
46
|
+
@parsed_file.kv_pairs << KVPair.new(current_line, comments_for_keys[current_line.key])
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
raise "Invalid .string file: Unterminated comment" unless state == KEY
|
51
|
+
@parsed_file
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Apfel
|
2
|
+
class KVPair
|
3
|
+
attr_reader :line, :raw_comment
|
4
|
+
|
5
|
+
def initialize(line, comment)
|
6
|
+
@line = line
|
7
|
+
@raw_comment = comment
|
8
|
+
end
|
9
|
+
|
10
|
+
def key
|
11
|
+
line.key.strip unless line.key.nil?
|
12
|
+
end
|
13
|
+
|
14
|
+
def value
|
15
|
+
line.value.strip unless line.key.nil?
|
16
|
+
end
|
17
|
+
|
18
|
+
def comment
|
19
|
+
if raw_comment.nil?
|
20
|
+
@raw_comment = ""
|
21
|
+
else
|
22
|
+
raw_comment.gsub!(/(\/\*)|(\*\/)/,"")
|
23
|
+
raw_comment.gsub!("\n", " ")
|
24
|
+
raw_comment.gsub!(/\s+/, " ")
|
25
|
+
raw_comment.strip
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/apfel/line.rb
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
module Apfel
|
2
|
+
class Line
|
3
|
+
attr_reader :content
|
4
|
+
attr_accessor :in_comment
|
5
|
+
|
6
|
+
def initialize(line)
|
7
|
+
@content = line
|
8
|
+
@in_comment = false
|
9
|
+
raise "Line does not end in ;" unless valid?
|
10
|
+
end
|
11
|
+
|
12
|
+
def empty_line?
|
13
|
+
/^\s*$/.match(content) || false
|
14
|
+
end
|
15
|
+
|
16
|
+
def whole_comment
|
17
|
+
/((^\/\*(.+)\*\/)|(^\/\/(.+)))/.match(content).to_s
|
18
|
+
end
|
19
|
+
|
20
|
+
def whole_comment?
|
21
|
+
!(whole_comment.empty?)
|
22
|
+
end
|
23
|
+
|
24
|
+
def open_comment
|
25
|
+
/^\/\*(.+)$/.match(content).to_s
|
26
|
+
end
|
27
|
+
|
28
|
+
def open_comment?
|
29
|
+
!(open_comment.empty?)
|
30
|
+
end
|
31
|
+
|
32
|
+
def close_comment
|
33
|
+
/^(.+)\*\/\s*$/.match(content).to_s
|
34
|
+
end
|
35
|
+
|
36
|
+
def close_comment?
|
37
|
+
!(close_comment.empty?)
|
38
|
+
end
|
39
|
+
|
40
|
+
def key_value_pair?
|
41
|
+
!!(/^\s*"([^"]+)"\s*=/.match(content))
|
42
|
+
end
|
43
|
+
|
44
|
+
def cleaned_content
|
45
|
+
content.gsub(/;\s*$/, "")
|
46
|
+
end
|
47
|
+
|
48
|
+
def valid?
|
49
|
+
if key_value_pair?
|
50
|
+
!!(/;[\s]*$/.match(content))
|
51
|
+
else
|
52
|
+
true
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def key
|
57
|
+
if key_value_pair?
|
58
|
+
cleaned_content.partition(/"\s*=\s*"/)[0].gsub!(/(^"|"$)/, "")
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def value
|
63
|
+
if key_value_pair?
|
64
|
+
cleaned_content.partition(/"\s*=\s*"/)[2].gsub!(/(^"|"$)/, "")
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def is_comment?
|
69
|
+
whole_comment? || open_comment? || close_comment? || in_comment
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module Apfel
|
2
|
+
require 'json'
|
3
|
+
class ParsedDotStrings
|
4
|
+
attr_accessor :kv_pairs
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@kv_pairs = []
|
8
|
+
end
|
9
|
+
|
10
|
+
def key_values
|
11
|
+
kv_pairs.map do |pair|
|
12
|
+
{pair.key => pair.value}
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def keys
|
17
|
+
kv_pairs.map do |pair|
|
18
|
+
pair.key
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def values
|
23
|
+
kv_pairs.map do |pair|
|
24
|
+
pair.value
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def comments(args={})
|
29
|
+
with_keys = args[:with_keys].nil? ? true : args[:with_keys]
|
30
|
+
cleaned_pairs = kv_pairs.map do |pair|
|
31
|
+
pair
|
32
|
+
end
|
33
|
+
with_keys ? build_comment_hash(cleaned_pairs) : cleaned_pairs.map(&:comment)
|
34
|
+
end
|
35
|
+
|
36
|
+
def to_hash(args={})
|
37
|
+
with_comments = args[:with_comments].nil? ? true : args[:with_comments]
|
38
|
+
|
39
|
+
build_hash { |hash, pair|
|
40
|
+
hash_value = with_comments ? { pair.value => pair.comment } : pair.value
|
41
|
+
hash[pair.key] = hash_value
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
def to_json(args={})
|
46
|
+
self.to_hash(with_comments: args[:with_comments]).to_json
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def build_comment_hash(kv_pairs)
|
52
|
+
build_hash { |hash, pair|
|
53
|
+
hash[pair.key] = pair.comment
|
54
|
+
}
|
55
|
+
end
|
56
|
+
|
57
|
+
def build_hash(&block)
|
58
|
+
hash = {}
|
59
|
+
kv_pairs.each do |pair|
|
60
|
+
yield hash, pair
|
61
|
+
end
|
62
|
+
hash
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
data/lib/apfel/reader.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
module Apfel
|
2
|
+
# Class for reading in files and returning an array of its content
|
3
|
+
class Reader
|
4
|
+
# Reads in a file and returns an array consisting of each line of input
|
5
|
+
# cleaned of new line characters
|
6
|
+
def self.read(file)
|
7
|
+
File.open(file, "r") do |f|
|
8
|
+
content_array=[]
|
9
|
+
content = f.read
|
10
|
+
content.each_line do |line|
|
11
|
+
line.gsub!("\n","")
|
12
|
+
content_array.push(line)
|
13
|
+
end
|
14
|
+
content_array
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/apfel.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Apfel
|
4
|
+
require 'apfel/reader'
|
5
|
+
require 'apfel/dot_strings_parser'
|
6
|
+
# Public module for parsing DotStrings files and returning a parsed dot
|
7
|
+
# strings object
|
8
|
+
def self.parse(file)
|
9
|
+
file = read(file)
|
10
|
+
DotStringsParser.new(file).parse_file
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.read(file)
|
14
|
+
Reader.read(file)
|
15
|
+
end
|
16
|
+
end
|
data/spec/apfel_spec.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'apfel'
|
3
|
+
require 'apfel/parsed_dot_strings'
|
4
|
+
|
5
|
+
describe Apfel do
|
6
|
+
describe '::parse_file' do
|
7
|
+
context 'when given a valid DotStrings file'do
|
8
|
+
|
9
|
+
let(:parsed_file) do
|
10
|
+
Apfel.parse(valid_file)
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'returns a ParsedDotStrings object' do
|
14
|
+
parsed_file.should be_a(Apfel::ParsedDotStrings)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'when given an invalid strings file' do
|
19
|
+
context 'missing a semicolon' do
|
20
|
+
|
21
|
+
let(:invalid_file_semicolon) do
|
22
|
+
create_temp_file( <<-EOS
|
23
|
+
/* This is the first comment */
|
24
|
+
"key_number_one" = "value number one"
|
25
|
+
EOS
|
26
|
+
)
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'returns an error' do
|
30
|
+
expect {
|
31
|
+
Apfel.parse(invalid_file_semicolon)
|
32
|
+
}.to raise_error
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'not closed comment' do
|
37
|
+
let(:invalid_file_comment) do
|
38
|
+
create_temp_file(<<-EOS
|
39
|
+
/* This is the first comment
|
40
|
+
"key_number_one" = "value number one";
|
41
|
+
|
42
|
+
/* This is
|
43
|
+
a
|
44
|
+
multiline comment */
|
45
|
+
end
|
46
|
+
EOS
|
47
|
+
)
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'raises an error' do
|
51
|
+
expect {
|
52
|
+
Apfel.parse(invalid_file_semicolon)
|
53
|
+
}.to raise_error
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'apfel'
|
3
|
+
require 'parsed_dot_strings'
|
4
|
+
|
5
|
+
module Apfel
|
6
|
+
describe ParsedDotStrings do
|
7
|
+
let(:parsed_file) do
|
8
|
+
Apfel.parse(valid_file)
|
9
|
+
end
|
10
|
+
|
11
|
+
describe '#keys' do
|
12
|
+
it 'returns an array of all the keys'do
|
13
|
+
parsed_file.keys.should eq(
|
14
|
+
["key_number_one",
|
15
|
+
"key_number_two",
|
16
|
+
"key_number_three"]
|
17
|
+
)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '#values' do
|
22
|
+
it 'returns an array of all the values'do
|
23
|
+
parsed_file.values.should eq(
|
24
|
+
["value number one",
|
25
|
+
"value number two",
|
26
|
+
"value number three"]
|
27
|
+
)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '#comments' do
|
32
|
+
context 'when :with_keys is passed as true' do
|
33
|
+
it 'returns a hash of the comments mapped to their correct keys' do
|
34
|
+
parsed_file.comments(with_keys: true).should eq(
|
35
|
+
{"key_number_one" => "This is the first comment",
|
36
|
+
"key_number_two" => "This is a multiline comment",
|
37
|
+
"key_number_three" => "This is comment number 3"}
|
38
|
+
)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context 'when with_keys is passed as false' do
|
43
|
+
it 'returns an array of just the comments' do
|
44
|
+
parsed_file.comments(with_keys: false).should eq(
|
45
|
+
["This is the first comment",
|
46
|
+
"This is a multiline comment",
|
47
|
+
"This is comment number 3"]
|
48
|
+
)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'defaults to returning a hash' do
|
53
|
+
parsed_file.comments.should be_a(Hash)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe '#key_values' do
|
58
|
+
it 'returns an array of hashes of key and values' do
|
59
|
+
parsed_file.key_values.should eq(
|
60
|
+
[
|
61
|
+
{"key_number_one" => "value number one"},
|
62
|
+
{"key_number_two" => "value number two"},
|
63
|
+
{"key_number_three" => "value number three"}
|
64
|
+
]
|
65
|
+
)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe '#to_hash' do
|
70
|
+
it 'returns a hash with the key = key, value = { value => comments }' do
|
71
|
+
parsed_file.to_hash.should eq(
|
72
|
+
{
|
73
|
+
"key_number_one" => { "value number one" => "This is the first comment" },
|
74
|
+
"key_number_two" => { "value number two" => "This is a multiline comment" },
|
75
|
+
"key_number_three" => { "value number three" => "This is comment number 3" }
|
76
|
+
}
|
77
|
+
)
|
78
|
+
end
|
79
|
+
|
80
|
+
context 'when :no_comments is passed as true' do
|
81
|
+
it 'returns a hash of just keys and values' do
|
82
|
+
parsed_file.to_hash(with_comments: false).should eq(
|
83
|
+
{
|
84
|
+
"key_number_one" => "value number one",
|
85
|
+
"key_number_two" => "value number two",
|
86
|
+
"key_number_three" => "value number three"
|
87
|
+
}
|
88
|
+
)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe 'to_json' do
|
94
|
+
it 'returns a valid json representation of .strings file' do
|
95
|
+
parsed_file.to_json.should eq(
|
96
|
+
{
|
97
|
+
"key_number_one" => { "value number one" => "This is the first comment" },
|
98
|
+
"key_number_two" => { "value number two" => "This is a multiline comment" },
|
99
|
+
"key_number_three" => { "value number three" => "This is comment number 3" }
|
100
|
+
}.to_json
|
101
|
+
)
|
102
|
+
end
|
103
|
+
context 'when :no_comments is passed as true' do
|
104
|
+
it 'returns a valid json representation of just keys and values' do
|
105
|
+
parsed_file.to_json(with_comments: false).should eq(
|
106
|
+
{
|
107
|
+
"key_number_one" => "value number one",
|
108
|
+
"key_number_two" => "value number two",
|
109
|
+
"key_number_three" => "value number three"
|
110
|
+
}.to_json
|
111
|
+
)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
data/spec/reader_spec.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'reader'
|
3
|
+
|
4
|
+
module Apfel
|
5
|
+
describe Reader do
|
6
|
+
describe '#read' do
|
7
|
+
let(:temp_file) do
|
8
|
+
create_temp_file(<<-EOS
|
9
|
+
This is a file with some lines.
|
10
|
+
Roses are red, violets are blue.
|
11
|
+
This text is really boring,
|
12
|
+
and so are you!
|
13
|
+
EOS
|
14
|
+
)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'reads a file a returns an array of its output' do
|
18
|
+
Reader.read(temp_file).should eq([
|
19
|
+
"This is a file with some lines.",
|
20
|
+
"Roses are red, violets are blue.",
|
21
|
+
"This text is really boring,",
|
22
|
+
"and so are you!"
|
23
|
+
])
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'tempfile'
|
2
|
+
require 'json'
|
3
|
+
def create_temp_file(string)
|
4
|
+
temp_file = Tempfile.new('temp')
|
5
|
+
temp_file << string
|
6
|
+
temp_file.flush
|
7
|
+
end
|
8
|
+
|
9
|
+
def valid_file
|
10
|
+
create_temp_file(<<-EOS
|
11
|
+
/* This is the first comment */
|
12
|
+
"key_number_one" = "value number one";
|
13
|
+
|
14
|
+
/* This is
|
15
|
+
a
|
16
|
+
|
17
|
+
multiline comment */
|
18
|
+
"key_number_two" = "value number two";
|
19
|
+
/* This is comment number 3 */
|
20
|
+
"key_number_three" = " value number three ";
|
21
|
+
EOS
|
22
|
+
)
|
23
|
+
end
|
metadata
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: apfel
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Ryan Levick
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-12-01 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rspec
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rake
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: pry
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
description: Parse valid .strings files for easy conversion to other formats
|
63
|
+
email:
|
64
|
+
- ryan.levick@gmail.com
|
65
|
+
executables: []
|
66
|
+
extensions: []
|
67
|
+
extra_rdoc_files: []
|
68
|
+
files:
|
69
|
+
- Gemfile
|
70
|
+
- Gemfile.lock
|
71
|
+
- README.md
|
72
|
+
- Rakefile
|
73
|
+
- apfel.gemspec
|
74
|
+
- lib/apfel.rb
|
75
|
+
- lib/apfel/dot_strings_parser.rb
|
76
|
+
- lib/apfel/kv_pair.rb
|
77
|
+
- lib/apfel/line.rb
|
78
|
+
- lib/apfel/parsed_dot_strings.rb
|
79
|
+
- lib/apfel/reader.rb
|
80
|
+
- lib/apfel/version.rb
|
81
|
+
- spec/apfel_spec.rb
|
82
|
+
- spec/parsed_dot_strings_spec.rb
|
83
|
+
- spec/reader_spec.rb
|
84
|
+
- spec/spec_helper.rb
|
85
|
+
homepage: https://github.com/rlevick/apfel
|
86
|
+
licenses: []
|
87
|
+
post_install_message:
|
88
|
+
rdoc_options: []
|
89
|
+
require_paths:
|
90
|
+
- lib
|
91
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
92
|
+
none: false
|
93
|
+
requirements:
|
94
|
+
- - ! '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
segments:
|
98
|
+
- 0
|
99
|
+
hash: -2408211664317922349
|
100
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
101
|
+
none: false
|
102
|
+
requirements:
|
103
|
+
- - ! '>='
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: '0'
|
106
|
+
segments:
|
107
|
+
- 0
|
108
|
+
hash: -2408211664317922349
|
109
|
+
requirements: []
|
110
|
+
rubyforge_project: apfel
|
111
|
+
rubygems_version: 1.8.24
|
112
|
+
signing_key:
|
113
|
+
specification_version: 3
|
114
|
+
summary: Simple parser for DotStrings Files
|
115
|
+
test_files:
|
116
|
+
- spec/apfel_spec.rb
|
117
|
+
- spec/parsed_dot_strings_spec.rb
|
118
|
+
- spec/reader_spec.rb
|
119
|
+
- spec/spec_helper.rb
|