fixed_width-multibyte 0.2.2 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,149 +1,158 @@
1
- DESCRIPTION:
2
- ============
3
-
4
- A simple, clean DSL for describing, writing, and parsing fixed-width text files.
5
-
6
- FEATURES:
7
- =========
8
-
9
- * Easy DSL syntax
10
- * Can parse and format fixed width files
11
- * Templated sections for reuse
12
-
13
- SYNOPSIS:
14
- =========
15
-
16
- ##Creating a definition (Quick 'n Dirty)
17
-
18
- Hopefully this will cover 90% of use cases.
19
-
20
- # Create a FixedWidth::Defintion to describe a file format
21
- FixedWidth.define :simple do |d|
22
- # This is a template section that can be reused in other sections
23
- d.template :boundary do |t|
24
- t.column :record_type, 4
25
- t.column :company_id, 12
26
- end
27
-
28
- # Create a section named :header
29
- d.header(:align => :left) do |header|
30
- # The trap tells FixedWidth which lines should fall into this section
31
- header.trap { |line| line[0,4] == 'HEAD' }
32
- # Use the boundary template for the columns
33
- header.template :boundary
34
- end
35
-
36
- d.body do |body|
37
- body.trap { |line| line[0,4] =~ /[^(HEAD|FOOT)]/ }
38
- body.column :id, 10, :parser => :to_i
39
- body.column :first, 10, :align => :left, :group => :name
40
- body.column :last, 10, :align => :left, :group => :name
41
- body.spacer 3
42
- body.column :city, 20 , :group => :address
43
- body.column :state, 2 , :group => :address
44
- body.column :country, 3, :group => :address
45
- end
46
-
47
- d.footer do |footer|
48
- footer.trap { |line| line[0,4] == 'FOOT' }
49
- footer.template :boundary
50
- footer.column :record_count, 10, :parser => :to_i
51
- end
52
- end
53
-
54
- This definition would output a parsed file something like this:
55
-
56
- {
57
- :body => [
58
- { :id => 12,
59
- :name => { :first => "Ryan", :last => "Wood" },
60
- :address => { :city => "Foo", :state => 'SC', :country => "USA" }
61
- },
62
- { :id => 13,
63
- :name => { :first => "Jo", :last => "Schmo" },
64
- :address => { :city => "Bar", :state => "CA", :country => "USA" }
65
- }
66
- ],
67
- :header => [{ :record_type => 'HEAD', :company_id => 'ABC' }],
68
- :footer => [{ :record_type => 'FOOT', :company_id => 'ABC', :record_count => 2 }]
69
- }
70
-
71
- ##Sections
72
- ###Declaring a section
73
-
74
- Sections can have any name, however duplicates are not allowed. (A `DuplicateSectionNameError` will be thrown.) We use the standard `method_missing` trick. So if you see any unusual behavior, that's probably the first spot to look.
75
-
76
- FixedWidth.define :simple do |d|
77
- d.a_section_name do |s|
78
- ...
79
- end
80
- d.another_section_name do |s|
81
- ...
82
- end
83
- end
84
-
85
- ### Section options:
86
-
87
- * `:singular` (default `false`) indicates that the section will only have a single record, and that it should not be returned nested in an array.
88
-
89
- * `:optional` (default `false`) indicates that the section is optional. (An otherwise-specified section will raise a `RequiredSectionNotFoundError` if the trap block doesn't match the row after the last one of the previous section.)
90
-
91
- ##Columns
92
- ###Declaring a column
93
-
94
- Columns can have any name, except for `:spacer` which is reserved. Also, duplicate column names within groupings are not allowed, and a column cannot share the same name as a group. (A `DuplicateColumnNameError` will be thrown for a duplicate column name within a grouping. A `DuplicateGroupNameError` will be thrown if you try to declare a column with the same name as an existing group or vice versa.) Again, basic `method_missing` trickery here, so be warned. You can declare columns either with the `method_missing` thing or by calling `Section#column`.
95
-
96
- FixedWidth.define :simple do |d|
97
- d.a_section_name do |s|
98
- s.a_column_name 12
99
- s.column :another_column_name, 14
100
- end
101
- end
102
-
103
- ###Column Options:
104
-
105
- * `:align` can be set to `:left` or `:right`, to indicate which side the values should be/are justified to. By default, all columns are aligned `:right`.
106
-
107
- * `:group` can be set to a `Symbol` indicating the name of the nested hash which the value should be parsed to when reading/the name of the nested hash the value should be extracted from when writing.
108
-
109
- * `:parser` and `:formatter` options are symbols (to be proc-ified) or procs. By default, parsing and formatting assume that we're expecting/writing right-aligned strings, padded with spaces.
110
-
111
- * `:nil_blank` set to true will cause whitespace-only fields to be parsed to nil, regardless of `:parser`.
112
-
113
- * `:padding` can be set to a single character that will be used to pad formatted values, when writing fixed-width files.
114
-
115
- * `:truncate` can be set to true to truncate any value that exceeds the `length` property of a column. If unset or set to `false`, a `FixedWidth::FormattedStringExceedsLengthError` exception will be thrown.
116
-
117
- ##Writing out fixed-width records
118
-
119
- Then either feed it a nested struct with data values to create the file in the defined format:
120
-
121
- test_data = {
122
- :body => [
123
- { :id => 12,
124
- :name => { :first => "Ryan", :last => "Wood" },
125
- :address => { :city => "Foo", :state => 'SC', :country => "USA" }
126
- },
127
- { :id => 13,
128
- :name => { :first => "Jo", :last => "Schmo" },
129
- :address => { :city => "Bar", :state => "CA", :country => "USA" }
130
- }
131
- ],
132
- :header => [{ :record_type => 'HEAD', :company_id => 'ABC' }],
133
- :footer => [{ :record_type => 'FOOT', :company_id => 'ABC', :record_count => 2 }]
134
- }
135
-
136
- # Generates the file as a string
137
- puts FixedWidth.generate(:simple, test_data)
138
-
139
- # Writes the file
140
- FixedWidth.write(file_instance, :simple, test_data)
141
-
142
- Or parse files already in that format into a nested hash:
143
-
144
- parsed_data = FixedWidth.parse(file_instance, :test).inspect
145
-
146
- INSTALL:
147
- ========
148
-
1
+ SPECIAL NOTE
2
+ ============
3
+
4
+ Gem name: fixed_width-multibyte (as opposed to fixed_width)
5
+
6
+ Forked from https://github.com/timonk/fixed_width to provide multibyte support. Uses ActiveSupport::Multibyte::Chars instead of String#unpack. Tested in Ruby 1.8.7 and 1.9.2.
7
+
8
+ Per https://github.com/timonk/fixed_width/pull/1, this fork will not be reintegrated into the fixed_width because it adds the ActiveSupport dependency.
9
+
10
+ DESCRIPTION:
11
+ ============
12
+
13
+ A simple, clean DSL for describing, writing, and parsing fixed-width text files.
14
+
15
+ FEATURES:
16
+ =========
17
+
18
+ * Easy DSL syntax
19
+ * Can parse and format fixed width files
20
+ * Templated sections for reuse
21
+
22
+ SYNOPSIS:
23
+ =========
24
+
25
+ ##Creating a definition (Quick 'n Dirty)
26
+
27
+ Hopefully this will cover 90% of use cases.
28
+
29
+ # Create a FixedWidth::Defintion to describe a file format
30
+ FixedWidth.define :simple do |d|
31
+ # This is a template section that can be reused in other sections
32
+ d.template :boundary do |t|
33
+ t.column :record_type, 4
34
+ t.column :company_id, 12
35
+ end
36
+
37
+ # Create a section named :header
38
+ d.header(:align => :left) do |header|
39
+ # The trap tells FixedWidth which lines should fall into this section
40
+ header.trap { |line| line[0,4] == 'HEAD' }
41
+ # Use the boundary template for the columns
42
+ header.template :boundary
43
+ end
44
+
45
+ d.body do |body|
46
+ body.trap { |line| line[0,4] =~ /[^(HEAD|FOOT)]/ }
47
+ body.column :id, 10, :parser => :to_i
48
+ body.column :first, 10, :align => :left, :group => :name
49
+ body.column :last, 10, :align => :left, :group => :name
50
+ body.spacer 3
51
+ body.column :city, 20 , :group => :address
52
+ body.column :state, 2 , :group => :address
53
+ body.column :country, 3, :group => :address
54
+ end
55
+
56
+ d.footer do |footer|
57
+ footer.trap { |line| line[0,4] == 'FOOT' }
58
+ footer.template :boundary
59
+ footer.column :record_count, 10, :parser => :to_i
60
+ end
61
+ end
62
+
63
+ This definition would output a parsed file something like this:
64
+
65
+ {
66
+ :body => [
67
+ { :id => 12,
68
+ :name => { :first => "Ryan", :last => "Wood" },
69
+ :address => { :city => "Foo", :state => 'SC', :country => "USA" }
70
+ },
71
+ { :id => 13,
72
+ :name => { :first => "Jo", :last => "Schmo" },
73
+ :address => { :city => "Bar", :state => "CA", :country => "USA" }
74
+ }
75
+ ],
76
+ :header => [{ :record_type => 'HEAD', :company_id => 'ABC' }],
77
+ :footer => [{ :record_type => 'FOOT', :company_id => 'ABC', :record_count => 2 }]
78
+ }
79
+
80
+ ##Sections
81
+ ###Declaring a section
82
+
83
+ Sections can have any name, however duplicates are not allowed. (A `DuplicateSectionNameError` will be thrown.) We use the standard `method_missing` trick. So if you see any unusual behavior, that's probably the first spot to look.
84
+
85
+ FixedWidth.define :simple do |d|
86
+ d.a_section_name do |s|
87
+ ...
88
+ end
89
+ d.another_section_name do |s|
90
+ ...
91
+ end
92
+ end
93
+
94
+ ### Section options:
95
+
96
+ * `:singular` (default `false`) indicates that the section will only have a single record, and that it should not be returned nested in an array.
97
+
98
+ * `:optional` (default `false`) indicates that the section is optional. (An otherwise-specified section will raise a `RequiredSectionNotFoundError` if the trap block doesn't match the row after the last one of the previous section.)
99
+
100
+ ##Columns
101
+ ###Declaring a column
102
+
103
+ Columns can have any name, except for `:spacer` which is reserved. Also, duplicate column names within groupings are not allowed, and a column cannot share the same name as a group. (A `DuplicateColumnNameError` will be thrown for a duplicate column name within a grouping. A `DuplicateGroupNameError` will be thrown if you try to declare a column with the same name as an existing group or vice versa.) Again, basic `method_missing` trickery here, so be warned. You can declare columns either with the `method_missing` thing or by calling `Section#column`.
104
+
105
+ FixedWidth.define :simple do |d|
106
+ d.a_section_name do |s|
107
+ s.a_column_name 12
108
+ s.column :another_column_name, 14
109
+ end
110
+ end
111
+
112
+ ###Column Options:
113
+
114
+ * `:align` can be set to `:left` or `:right`, to indicate which side the values should be/are justified to. By default, all columns are aligned `:right`.
115
+
116
+ * `:group` can be set to a `Symbol` indicating the name of the nested hash which the value should be parsed to when reading/the name of the nested hash the value should be extracted from when writing.
117
+
118
+ * `:parser` and `:formatter` options are symbols (to be proc-ified) or procs. By default, parsing and formatting assume that we're expecting/writing right-aligned strings, padded with spaces.
119
+
120
+ * `:nil_blank` set to true will cause whitespace-only fields to be parsed to nil, regardless of `:parser`.
121
+
122
+ * `:padding` can be set to a single character that will be used to pad formatted values, when writing fixed-width files.
123
+
124
+ * `:truncate` can be set to true to truncate any value that exceeds the `length` property of a column. If unset or set to `false`, a `FixedWidth::FormattedStringExceedsLengthError` exception will be thrown.
125
+
126
+ ##Writing out fixed-width records
127
+
128
+ Then either feed it a nested struct with data values to create the file in the defined format:
129
+
130
+ test_data = {
131
+ :body => [
132
+ { :id => 12,
133
+ :name => { :first => "Ryan", :last => "Wood" },
134
+ :address => { :city => "Foo", :state => 'SC', :country => "USA" }
135
+ },
136
+ { :id => 13,
137
+ :name => { :first => "Jo", :last => "Schmo" },
138
+ :address => { :city => "Bar", :state => "CA", :country => "USA" }
139
+ }
140
+ ],
141
+ :header => [{ :record_type => 'HEAD', :company_id => 'ABC' }],
142
+ :footer => [{ :record_type => 'FOOT', :company_id => 'ABC', :record_count => 2 }]
143
+ }
144
+
145
+ # Generates the file as a string
146
+ puts FixedWidth.generate(:simple, test_data)
147
+
148
+ # Writes the file
149
+ FixedWidth.write(file_instance, :simple, test_data)
150
+
151
+ Or parse files already in that format into a nested hash:
152
+
153
+ parsed_data = FixedWidth.parse(file_instance, :test).inspect
154
+
155
+ INSTALL:
156
+ ========
157
+
149
158
  sudo gem install fixed_width
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.2
1
+ 0.2.3
@@ -4,21 +4,14 @@
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
- s.name = %q{fixed_width-multibyte}
8
- s.version = "0.2.2"
7
+ s.name = "fixed_width-multibyte"
8
+ s.version = "0.2.3"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Timon Karnezos"]
12
- s.date = %q{2011-05-21}
13
- s.description = %q{A gem that provides a DSL for parsing and writing files of fixed-width records.
14
-
15
- Multibyte support added while Timon is on vacation.
16
-
17
- Shamelessly forked from ryanwood/slither [http://github.com/ryanwood/slither].
18
-
19
- Renamed the gem to be a little clearer as to its purpose. Hate that 'nokogiri' nonsense.
20
- }
21
- s.email = %q{timon.karnezos@gmail.com}
12
+ s.date = "2012-01-27"
13
+ s.description = "A gem that provides a DSL for parsing and writing files of fixed-width records.\n\nMultibyte support added while Timon is on vacation.\n\nShamelessly forked from ryanwood/slither [http://github.com/ryanwood/slither].\n\nRenamed the gem to be a little clearer as to its purpose. Hate that 'nokogiri' nonsense.\n"
14
+ s.email = "timon.karnezos@gmail.com"
22
15
  s.extra_rdoc_files = [
23
16
  "README.markdown",
24
17
  "TODO"
@@ -32,7 +25,7 @@ Renamed the gem to be a little clearer as to its purpose. Hate that 'nokogiri' n
32
25
  "VERSION",
33
26
  "examples/readme_example.rb",
34
27
  "fixed_width-multibyte.gemspec",
35
- "fixed_width.gemspec",
28
+ "lib/fixed_width-multibyte.rb",
36
29
  "lib/fixed_width.rb",
37
30
  "lib/fixed_width/column.rb",
38
31
  "lib/fixed_width/core_ext/symbol.rb",
@@ -49,10 +42,10 @@ Renamed the gem to be a little clearer as to its purpose. Hate that 'nokogiri' n
49
42
  "spec/section_spec.rb",
50
43
  "spec/spec_helper.rb"
51
44
  ]
52
- s.homepage = %q{http://github.com/timonk/fixed_width}
45
+ s.homepage = "http://github.com/timonk/fixed_width"
53
46
  s.require_paths = ["lib"]
54
- s.rubygems_version = %q{1.6.2}
55
- s.summary = %q{A gem that provides a DSL for parsing and writing files of fixed-width records.}
47
+ s.rubygems_version = "1.8.10"
48
+ s.summary = "A gem that provides a DSL for parsing and writing files of fixed-width records."
56
49
 
57
50
  if s.respond_to? :specification_version then
58
51
  s.specification_version = 3
@@ -0,0 +1 @@
1
+ require File.expand_path('../fixed_width', __FILE__)
@@ -1,4 +1,3 @@
1
- $: << File.dirname(__FILE__)
2
1
  require 'ostruct'
3
2
 
4
3
  require 'active_support'
metadata CHANGED
@@ -1,47 +1,48 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: fixed_width-multibyte
3
- version: !ruby/object:Gem::Version
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.3
4
5
  prerelease:
5
- version: 0.2.2
6
6
  platform: ruby
7
- authors:
7
+ authors:
8
8
  - Timon Karnezos
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
-
13
- date: 2011-05-21 00:00:00 -05:00
14
- default_executable:
15
- dependencies:
16
- - !ruby/object:Gem::Dependency
12
+ date: 2012-01-27 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
17
15
  name: activesupport
18
- prerelease: false
19
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: &2177839880 !ruby/object:Gem::Requirement
20
17
  none: false
21
- requirements:
22
- - - ">="
23
- - !ruby/object:Gem::Version
24
- version: "0"
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
25
22
  type: :runtime
26
- version_requirements: *id001
27
- description: |
28
- A gem that provides a DSL for parsing and writing files of fixed-width records.
29
-
23
+ prerelease: false
24
+ version_requirements: *2177839880
25
+ description: ! 'A gem that provides a DSL for parsing and writing files of fixed-width
26
+ records.
27
+
28
+
30
29
  Multibyte support added while Timon is on vacation.
31
-
30
+
31
+
32
32
  Shamelessly forked from ryanwood/slither [http://github.com/ryanwood/slither].
33
-
34
- Renamed the gem to be a little clearer as to its purpose. Hate that 'nokogiri' nonsense.
35
33
 
34
+
35
+ Renamed the gem to be a little clearer as to its purpose. Hate that ''nokogiri''
36
+ nonsense.
37
+
38
+ '
36
39
  email: timon.karnezos@gmail.com
37
40
  executables: []
38
-
39
41
  extensions: []
40
-
41
- extra_rdoc_files:
42
+ extra_rdoc_files:
42
43
  - README.markdown
43
44
  - TODO
44
- files:
45
+ files:
45
46
  - COPYING
46
47
  - HISTORY
47
48
  - README.markdown
@@ -50,7 +51,7 @@ files:
50
51
  - VERSION
51
52
  - examples/readme_example.rb
52
53
  - fixed_width-multibyte.gemspec
53
- - fixed_width.gemspec
54
+ - lib/fixed_width-multibyte.rb
54
55
  - lib/fixed_width.rb
55
56
  - lib/fixed_width/column.rb
56
57
  - lib/fixed_width/core_ext/symbol.rb
@@ -66,33 +67,29 @@ files:
66
67
  - spec/parser_spec.rb
67
68
  - spec/section_spec.rb
68
69
  - spec/spec_helper.rb
69
- has_rdoc: true
70
70
  homepage: http://github.com/timonk/fixed_width
71
71
  licenses: []
72
-
73
72
  post_install_message:
74
73
  rdoc_options: []
75
-
76
- require_paths:
74
+ require_paths:
77
75
  - lib
78
- required_ruby_version: !ruby/object:Gem::Requirement
76
+ required_ruby_version: !ruby/object:Gem::Requirement
79
77
  none: false
80
- requirements:
81
- - - ">="
82
- - !ruby/object:Gem::Version
83
- version: "0"
84
- required_rubygems_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ! '>='
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ required_rubygems_version: !ruby/object:Gem::Requirement
85
83
  none: false
86
- requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- version: "0"
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
90
88
  requirements: []
91
-
92
89
  rubyforge_project:
93
- rubygems_version: 1.6.2
90
+ rubygems_version: 1.8.10
94
91
  signing_key:
95
92
  specification_version: 3
96
93
  summary: A gem that provides a DSL for parsing and writing files of fixed-width records.
97
94
  test_files: []
98
-
95
+ has_rdoc:
@@ -1,76 +0,0 @@
1
- # Generated by jeweler
2
- # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
- # -*- encoding: utf-8 -*-
5
-
6
- Gem::Specification.new do |s|
7
- s.name = %q{fixed_width}
8
- s.version = "0.2.1"
9
-
10
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = ["Timon Karnezos"]
12
- s.date = %q{2010-05-31}
13
- s.description = %q{A gem that provides a DSL for parsing and writing files of fixed-width records.
14
-
15
- Shamelessly forked from ryanwood/slither [http://github.com/ryanwood/slither].
16
-
17
- Renamed the gem to be a little clearer as to its purpose. Hate that 'nokogiri' nonsense.
18
- }
19
- s.email = %q{timon.karnezos@gmail.com}
20
- s.extra_rdoc_files = [
21
- "README.markdown",
22
- "TODO"
23
- ]
24
- s.files = [
25
- ".gitignore",
26
- "COPYING",
27
- "HISTORY",
28
- "README.markdown",
29
- "Rakefile",
30
- "TODO",
31
- "VERSION",
32
- "examples/readme_example.rb",
33
- "fixed_width.gemspec",
34
- "lib/fixed_width.rb",
35
- "lib/fixed_width/column.rb",
36
- "lib/fixed_width/core_ext/symbol.rb",
37
- "lib/fixed_width/definition.rb",
38
- "lib/fixed_width/fixed_width.rb",
39
- "lib/fixed_width/generator.rb",
40
- "lib/fixed_width/parser.rb",
41
- "lib/fixed_width/section.rb",
42
- "spec/column_spec.rb",
43
- "spec/definition_spec.rb",
44
- "spec/fixed_width_spec.rb",
45
- "spec/generator_spec.rb",
46
- "spec/parser_spec.rb",
47
- "spec/section_spec.rb",
48
- "spec/spec_helper.rb"
49
- ]
50
- s.homepage = %q{http://github.com/timonk/fixed_width}
51
- s.rdoc_options = ["--charset=UTF-8"]
52
- s.require_paths = ["lib"]
53
- s.rubygems_version = %q{1.3.6}
54
- s.summary = %q{A gem that provides a DSL for parsing and writing files of fixed-width records.}
55
- s.test_files = [
56
- "spec/column_spec.rb",
57
- "spec/definition_spec.rb",
58
- "spec/fixed_width_spec.rb",
59
- "spec/generator_spec.rb",
60
- "spec/parser_spec.rb",
61
- "spec/section_spec.rb",
62
- "spec/spec_helper.rb",
63
- "examples/readme_example.rb"
64
- ]
65
-
66
- if s.respond_to? :specification_version then
67
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
68
- s.specification_version = 3
69
-
70
- if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
71
- else
72
- end
73
- else
74
- end
75
- end
76
-