haecksler 0.0.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7fac756e6245151603f1454fb9384c64cbe57ed0
4
+ data.tar.gz: 3429e573e1d61c725bdc051273ca7337e166eb9e
5
+ SHA512:
6
+ metadata.gz: 3a4acbbd1ae9b6ac447d0fa18675617e84392f64a2b6d0b9f24d6499fe6b5d4376d236b59de1af87094c1aab05d48203f673172525ee56d3f48952418d407e47
7
+ data.tar.gz: 8afb2a948a53866943cccb6f201d6850ae947f43d4584903af9f4c8c86b73c6aba57f64d9251a0a62033965972cddef6990e10399e88c34ea439ddef2d34a0fb
@@ -0,0 +1,22 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.1
4
+ - 2.0.0
5
+ - jruby-head
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in haecksler.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Frank Falkenberg
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,51 @@
1
+ # Haecksler
2
+
3
+ [![Code Climate](https://codeclimate.com/github/falti/haecksler.png)](https://codeclimate.com/github/falti/haecksler)
4
+ [![Build Status](https://travis-ci.org/falti/haecksler.svg?branch=master)](https://travis-ci.org/falti/haecksler)
5
+ [![Dependency Status](https://gemnasium.com/falti/haecksler.svg)](https://gemnasium.com/falti/haecksler)
6
+
7
+
8
+ TODO: Write a gem description
9
+
10
+ ## Installation
11
+
12
+ Add this line to your application's Gemfile:
13
+
14
+ gem 'haecksler'
15
+
16
+ And then execute:
17
+
18
+ $ bundle
19
+
20
+ Or install it yourself as:
21
+
22
+ $ gem install haecksler
23
+
24
+ ## Usage
25
+
26
+ ```ruby
27
+ file = File.open(File.expand_path("../complete.txt",__FILE__))
28
+
29
+ result = Haecksler.chop(file) do |h|
30
+
31
+ h.header_trap {|header| header =~/^FILE/ }
32
+ h.header "HName", 4
33
+ h.header "HExtra", 6
34
+
35
+ h.column "Id", 2, :integer
36
+ h.column "Name", 10
37
+ h.column "Date", 8, :date
38
+
39
+ h.footer_trap {|footer| footer =~/^END/ }
40
+ h.footer "FFooter", 3
41
+ h.footer "FDate", 8, :date
42
+ end
43
+ ```
44
+
45
+ ## Contributing
46
+
47
+ 1. Fork it ( https://github.com/[my-github-username]/haecksler/fork )
48
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
49
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
50
+ 4. Push to the branch (`git push origin my-new-feature`)
51
+ 5. Create a new Pull Request
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'haecksler/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "haecksler"
8
+ spec.version = Haecksler::VERSION
9
+ spec.authors = ["Frank Falkenberg"]
10
+ spec.email = ["faltibrain@gmail.com"]
11
+ spec.summary = %q{Library to parse fixed-length files}
12
+ spec.description = %q{Haecksler is the German word for a wood chipper}
13
+ spec.homepage = "https://github.com/falti/haecksler"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.5.3"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rspec", '~> 2.14'
24
+ end
@@ -0,0 +1,5 @@
1
+ require "haecksler/version"
2
+ require "haecksler/column"
3
+ require "haecksler/row"
4
+ require "haecksler/sheet"
5
+ require "haecksler/dsl"
@@ -0,0 +1,70 @@
1
+ require 'delegate'
2
+ require 'date'
3
+
4
+ module Haecksler
5
+
6
+ class TypeError
7
+ attr_reader :value, :type
8
+
9
+ def initialize(value, column)
10
+ @value = value
11
+ @type = column.type
12
+ end
13
+
14
+ def to_s
15
+ "Could not parse '#{value}' to '#{type}"
16
+ end
17
+
18
+ end
19
+
20
+ class ParsedColumn < SimpleDelegator
21
+ attr_accessor :value
22
+ end
23
+
24
+ class Column
25
+ attr_reader :name, :size, :type, :date_format
26
+
27
+ DEFAULT_OPTIONS={type: :string, date_format: nil}
28
+
29
+ def initialize(options = {type: :string})
30
+ options = DEFAULT_OPTIONS.merge(options)
31
+ @name = options[:name]
32
+ @size = options[:size]
33
+ @type = options[:type]
34
+ @date_format = options[:date_format]
35
+ end
36
+
37
+ def parse(string_value)
38
+ parsed = ParsedColumn.new(self)
39
+
40
+ parsed.value = begin
41
+ case type
42
+ when :string
43
+ String(string_value).rstrip
44
+ when :integer
45
+ Integer(string_value)
46
+ when :float
47
+ Float(string_value)
48
+ when :date
49
+ if date_format.nil?
50
+ Date.parse(string_value)
51
+ else
52
+ Date.strptime(string_value, date_format)
53
+ end
54
+ when :datetime
55
+ if date_format.nil?
56
+ DateTime.parse(string_value)
57
+ else
58
+ DateTime.strptime(string_value, date_format)
59
+ end
60
+ else
61
+ nil
62
+ end
63
+ rescue
64
+ TypeError.new(string_value, self)
65
+ end
66
+
67
+ parsed
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,62 @@
1
+ module Haecksler
2
+
3
+ def self.chop(input)
4
+ dsl = Dsl.new.chop(input)
5
+ yield dsl
6
+ dsl.parse!
7
+ end
8
+
9
+ class Dsl
10
+
11
+ def chop(input)
12
+ @input = input
13
+ @row = Row.new
14
+ @header_check = proc { false }
15
+ @header = false
16
+ @footer_check = proc { false }
17
+ @footer = false
18
+ self
19
+ end
20
+
21
+ def column(name, size, type=:string, date_format=nil)
22
+ @row << _column(name, size, type, date_format)
23
+ end
24
+
25
+ def header_trap(&proc)
26
+ @header_check = proc
27
+ end
28
+
29
+ def footer_trap(&proc)
30
+ @footer_check = proc
31
+ end
32
+
33
+ def header(name, size, type=:string, date_format=nil)
34
+ @header ||= HeaderRow.new
35
+ @header << _column(name, size, type, date_format)
36
+ end
37
+
38
+ def footer(name, size, type=:string, date_format=nil)
39
+ @footer ||= FooterRow.new
40
+ @footer << _column(name, size, type, date_format)
41
+ end
42
+
43
+ def parse!
44
+ Sheet.new(@input, {
45
+ row: @row,
46
+ header_check: @header_check,
47
+ header: @header,
48
+ footer_check: @footer_check,
49
+ footer: @footer}
50
+ )
51
+ end
52
+
53
+ private
54
+ def _column(name, size, type, date_format)
55
+ Column.new({name: name, size: size, type: type, date_format: date_format})
56
+ end
57
+
58
+
59
+
60
+ end
61
+
62
+ end
@@ -0,0 +1,62 @@
1
+ module Haecksler
2
+
3
+ class Row
4
+ attr_reader :columns
5
+
6
+ def initialize(columns = [])
7
+ @columns = columns
8
+ end
9
+
10
+ def <<(column)
11
+ @columns << column
12
+ end
13
+
14
+ def [](key)
15
+ begin
16
+ @columns.find{|c| c.name == key }.value
17
+ rescue
18
+ nil
19
+ end
20
+ end
21
+
22
+ def parse(input)
23
+
24
+ indizes = columns.map(&:size).reduce([0]) do |memo,item|
25
+ memo << (memo.last.to_i + item)
26
+ memo
27
+ end
28
+
29
+ slices = input.split(//).each_with_index.slice_before { | element | indizes.include? element[1] }
30
+
31
+ parsed_columns = slices.map {|slice| slice.map{|i| i[0]}.join("")}.zip(columns).map do |text, column|
32
+ column.parse(text)
33
+ end
34
+
35
+ @columns = parsed_columns
36
+
37
+ self
38
+
39
+ end
40
+
41
+ def header?
42
+ false
43
+ end
44
+
45
+ def footer?
46
+ false
47
+ end
48
+ end
49
+
50
+ class HeaderRow < Row
51
+ def header?
52
+ true
53
+ end
54
+ end
55
+
56
+ class FooterRow < Row
57
+ def footer?
58
+ true
59
+ end
60
+ end
61
+
62
+ end
@@ -0,0 +1,32 @@
1
+ module Haecksler
2
+ class Sheet
3
+ include Enumerable
4
+
5
+ attr_reader :row
6
+
7
+ DEFAULT_OPTIONS={ header: false, footer: false, header_check: proc{ false }, footer_check: proc{ false } }
8
+
9
+ def initialize(input, options={})
10
+ options = DEFAULT_OPTIONS.merge(options)
11
+ @header = options[:header]
12
+ @footer = options[:footer]
13
+ @row = options[:row]
14
+ @input = input
15
+ @header_check = options[:header_check]
16
+ @footer_check = options[:footer_check]
17
+ end
18
+
19
+ def each
20
+ @input.lazy.each do |input|
21
+ if @header_check.call(input)
22
+ yield @header.parse(input.chomp)
23
+ elsif @footer_check.call(input)
24
+ yield @footer.parse(input.chomp)
25
+ else
26
+ yield @row.parse(input.chomp)
27
+ end
28
+ end
29
+ end
30
+
31
+ end
32
+ end
@@ -0,0 +1,3 @@
1
+ module Haecksler
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,90 @@
1
+ require 'spec_helper'
2
+
3
+ module Haecksler
4
+ describe Column do
5
+ describe "a string column" do
6
+ subject do
7
+ Column.new(name: "First Name", size: 10, type: :string )
8
+ end
9
+ it "should require all options to be set" do
10
+ expect(subject).to be_a Column
11
+ end
12
+
13
+ it "should parse a string column" do
14
+ parsed = subject.parse("Frank")
15
+ expect(parsed).to be_a ParsedColumn
16
+ expect(parsed.name).to eq("First Name")
17
+ expect(parsed.value).to eq "Frank"
18
+ end
19
+
20
+ it "should trim trailing whitespace" do
21
+ expect(subject.parse("Frank ").value).to eq "Frank"
22
+ end
23
+
24
+ it "should keep leading whitespace" do
25
+ expect(subject.parse(" Frank ").value).to eq " Frank"
26
+ end
27
+
28
+ end
29
+
30
+ describe "Integer column" do
31
+
32
+ subject do
33
+ Column.new(name: "I1", size: 2, type: :integer)
34
+ end
35
+
36
+ it "should handle integer column" do
37
+ expect(subject.parse("2 ").value).to eq 2
38
+ expect(subject.parse(" 2").value).to eq 2
39
+ expect(subject.parse("02").value).to eq 2
40
+ end
41
+
42
+ it "should yield a TypeError for wrong type column" do
43
+ expect(subject.parse("x ").value).to be_a TypeError
44
+ end
45
+
46
+ end
47
+
48
+ describe "Float column" do
49
+ subject do
50
+ Column.new(name: "I1", size: 3, type: :float)
51
+ end
52
+ it "should handle double column" do
53
+ expect(subject.parse("2 ").value).to eq 2.0
54
+ expect(subject.parse("2.0").value).to eq 2.0
55
+ expect(subject.parse("02").value).to eq 2.0
56
+ end
57
+
58
+ it "should yield a TypeError for wrong type column" do
59
+ expect(subject.parse("x ").value).to be_a TypeError
60
+ end
61
+ end
62
+
63
+ describe "Date column" do
64
+ subject do
65
+ Column.new(name: "I1", size: 8, type: :date)
66
+ end
67
+
68
+ it "should handle date column" do
69
+ expect(subject.parse("20130304").value).to eq Date.new(2013,3,4)
70
+ end
71
+
72
+ it "should respect date format" do
73
+ c = Column.new(name:"I2", size: 10, type: :date, date_format: '%d.%m.%Y')
74
+ expect(c.parse("03.12.2008").value).to eq Date.new(2008,12,3)
75
+ end
76
+ end
77
+
78
+ describe "DateTime column" do
79
+ subject do
80
+ Column.new(name: "I1", size: 8, type: :datetime)
81
+ end
82
+
83
+ it "should handle date column" do
84
+ expect(subject.parse("20130304").value).to eq DateTime.new(2013,3,4)
85
+ end
86
+
87
+ end
88
+
89
+ end
90
+ end
@@ -0,0 +1,4 @@
1
+ FILESample
2
+ 01Fränk 20080305
3
+ 02Sam 20091205
4
+ END20140910
@@ -0,0 +1,87 @@
1
+ require "spec_helper"
2
+
3
+ module Haecksler
4
+
5
+ describe Haecksler do
6
+
7
+ before(:each) do
8
+ @data = [
9
+ "01Frank 20080305",
10
+ "02Sam 20091205"
11
+ ]
12
+ end
13
+
14
+ it "should work without header/footer" do
15
+
16
+ result = Haecksler.chop(@data) do |h|
17
+ h.column "Id", 2, :integer
18
+ h.column "Name", 10
19
+ h.column "Date", 8, :date
20
+ end
21
+
22
+ expect(result.first["Name"]).to eq "Frank"
23
+ end
24
+
25
+ it "should work with header" do
26
+
27
+ @data.unshift("HEADER01")
28
+ result = Haecksler.chop(@data) do |h|
29
+ h.header_trap {|header| header =~/^HEADER/ }
30
+ h.header "HName", 6
31
+ h.header "SomeNumber", 2, :integer
32
+ h.column "Id", 2, :integer
33
+ h.column "Name", 10
34
+ h.column "Date", 8, :date
35
+ end
36
+ header = result.first
37
+
38
+ expect(header["HName"]).to eq "HEADER"
39
+ expect(header["SomeNumber"]).to eq 1
40
+ end
41
+
42
+ it "should work with footer" do
43
+ @data << "FOOTER02"
44
+ result = Haecksler.chop(@data) do |h|
45
+ h.footer_trap {|footer| footer =~/^FOOTER/ }
46
+ h.footer "footer", 6
47
+ h.footer "SomeNumber", 2, :integer
48
+ h.column "Id", 2, :integer
49
+ h.column "Name", 10
50
+ h.column "Date", 8, :date
51
+ end
52
+
53
+ footer = result.to_a.last
54
+ expect(footer["footer"]).to eq "FOOTER"
55
+ expect(footer["SomeNumber"]).to eq 2
56
+ end
57
+
58
+ it "should work on full sample" do
59
+ file = File.open(File.expand_path("../complete.txt",__FILE__))
60
+
61
+ result = Haecksler.chop(file) do |h|
62
+
63
+ h.header_trap {|header| header =~/^FILE/ }
64
+ h.header "HName", 4
65
+ h.header "HExtra", 6
66
+
67
+ h.column "Id", 2, :integer
68
+ h.column "Name", 10
69
+ h.column "Date", 8, :date
70
+
71
+ h.footer_trap {|footer| footer =~/^END/ }
72
+ h.footer "FFooter", 3
73
+ h.footer "FDate", 8, :date
74
+ end.to_a
75
+
76
+
77
+ expect(result[0]).to be_a HeaderRow
78
+ expect(result[1]).to be_a Row
79
+ expect(result[2]).to be_a Row
80
+ expect(result[3]).to be_a FooterRow
81
+
82
+
83
+ end
84
+
85
+
86
+ end
87
+ end
@@ -0,0 +1,72 @@
1
+ require 'spec_helper'
2
+
3
+ module Haecksler
4
+ describe Row do
5
+ it "should initialize with empty columns" do
6
+ expect(subject.columns).to have(0).things
7
+ end
8
+
9
+ it "should not be header or footer" do
10
+ expect(subject).not_to be_header
11
+ expect(subject).not_to be_footer
12
+ end
13
+
14
+ it "should receive more columns" do
15
+ subject << Column.new(name: "Name", size: 10)
16
+ expect(subject.columns).to have(1).thing
17
+ subject << Column.new(name: "Id", size: 2)
18
+ end
19
+
20
+ it "should parse a row" do
21
+ subject << Column.new(name: "Name", size: 10)
22
+ subject << Column.new(name: "Id", size: 2)
23
+
24
+ parsed_result = subject.parse("Frank AB")
25
+
26
+ expect(parsed_result.columns).to have(2).things
27
+
28
+ expect(parsed_result.columns.first.value).to eq "Frank"
29
+ expect(parsed_result.columns.last.value).to eq "AB"
30
+ end
31
+
32
+ it "should parse a row with UTF" do
33
+ subject << Column.new(name: "Name", size: 10)
34
+ subject << Column.new(name: "Id", size: 2)
35
+
36
+ parsed_result = subject.parse("Fränk €B")
37
+
38
+ expect(parsed_result.columns).to have(2).things
39
+
40
+ expect(parsed_result.columns.first.value).to eq "Fränk"
41
+ expect(parsed_result.columns.last.value).to eq "€B"
42
+
43
+ end
44
+
45
+ it "should have Hash like access" do
46
+ subject << Column.new(name: "Name", size: 3)
47
+ parsed_result = subject.parse("ABC")
48
+ expect(parsed_result["Name"]).to eq("ABC")
49
+ end
50
+
51
+ it "should return nil for unknown key" do
52
+ subject << Column.new(name: "Name", size: 3)
53
+ parsed_result = subject.parse("ABC")
54
+ expect(parsed_result["Unknown"]).to be_nil
55
+ end
56
+
57
+ end
58
+
59
+ describe HeaderRow do
60
+ it "should behave as header" do
61
+ expect(subject).to be_header
62
+ expect(subject).not_to be_footer
63
+ end
64
+ end
65
+
66
+ describe FooterRow do
67
+ it "should behave as footer" do
68
+ expect(subject).not_to be_header
69
+ expect(subject).to be_footer
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,51 @@
1
+ require 'spec_helper'
2
+
3
+ module Haecksler
4
+ describe Sheet do
5
+ before(:each) do
6
+ @data = [
7
+ "01Frank 20080305",
8
+ "02Sam 20091205"
9
+ ]
10
+ @row = Row.new
11
+ @row << Column.new(name: "Id", size: 2, type: :integer)
12
+ @row << Column.new(name: "Name", size: 10)
13
+ @row << Column.new(name: "Date", size: 8, type: :date)
14
+ end
15
+
16
+ it "should parse some array" do
17
+ expect(Sheet.new(@data, row: @row)).to have(2).things
18
+ end
19
+
20
+ it "should parse with header" do
21
+ @data = ["HEADER1"] + @data
22
+ header_row = Row.new
23
+ header_row << Column.new(name: "f1", size: 6)
24
+ header_row << Column.new(name: "f2", size: 1, type: :integer)
25
+
26
+ s = Sheet.new(@data, row: @row, header: header_row, header_check: proc{|line| line =~ /^HEADER/ })
27
+
28
+ expect(s).to be_an Enumerable
29
+ expect(s).to have(3).things
30
+ end
31
+
32
+ describe "with a File" do
33
+
34
+ it "should process file without header" do
35
+
36
+ File.open(File.expand_path("../simple.txt",__FILE__)) do |f|
37
+ s = Sheet.new(f, row: @row)
38
+ expect(s).to be_an Enumerable
39
+ first = s.first
40
+ expect(first).not_to be_nil
41
+ expect(first["Name"]).to eq "Frank"
42
+ f.rewind
43
+ expect(s).to have(2).things
44
+
45
+
46
+ end
47
+ end
48
+
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,2 @@
1
+ 01Frank 20080305
2
+ 02Sam 20091205
@@ -0,0 +1,19 @@
1
+ require 'haecksler'
2
+
3
+ # This file was generated by the `rspec --init` command. Conventionally, all
4
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
5
+ # Require this file using `require "spec_helper"` to ensure that it is only
6
+ # loaded once.
7
+ #
8
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
9
+ RSpec.configure do |config|
10
+ config.treat_symbols_as_metadata_keys_with_true_values = true
11
+ config.run_all_when_everything_filtered = true
12
+ config.filter_run :focus
13
+
14
+ # Run specs in random order to surface order dependencies. If you find an
15
+ # order dependency and want to debug it, you can fix the order by providing
16
+ # the seed, which is printed after each run.
17
+ # --seed 1234
18
+ config.order = 'random'
19
+ end
metadata ADDED
@@ -0,0 +1,114 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: haecksler
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Frank Falkenberg
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-04-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: 1.5.3
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: 1.5.3
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '2.14'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '2.14'
55
+ description: Haecksler is the German word for a wood chipper
56
+ email:
57
+ - faltibrain@gmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - .gitignore
63
+ - .rspec
64
+ - .travis.yml
65
+ - Gemfile
66
+ - LICENSE.txt
67
+ - README.md
68
+ - Rakefile
69
+ - haecksler.gemspec
70
+ - lib/haecksler.rb
71
+ - lib/haecksler/column.rb
72
+ - lib/haecksler/dsl.rb
73
+ - lib/haecksler/row.rb
74
+ - lib/haecksler/sheet.rb
75
+ - lib/haecksler/version.rb
76
+ - spec/column_spec.rb
77
+ - spec/complete.txt
78
+ - spec/dsl_spec.rb
79
+ - spec/row_spec.rb
80
+ - spec/sheet_spec.rb
81
+ - spec/simple.txt
82
+ - spec/spec_helper.rb
83
+ homepage: https://github.com/falti/haecksler
84
+ licenses:
85
+ - MIT
86
+ metadata: {}
87
+ post_install_message:
88
+ rdoc_options: []
89
+ require_paths:
90
+ - lib
91
+ required_ruby_version: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - '>='
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ required_rubygems_version: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - '>='
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ requirements: []
102
+ rubyforge_project:
103
+ rubygems_version: 2.1.11
104
+ signing_key:
105
+ specification_version: 4
106
+ summary: Library to parse fixed-length files
107
+ test_files:
108
+ - spec/column_spec.rb
109
+ - spec/complete.txt
110
+ - spec/dsl_spec.rb
111
+ - spec/row_spec.rb
112
+ - spec/sheet_spec.rb
113
+ - spec/simple.txt
114
+ - spec/spec_helper.rb