X12 0.0.5

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.
Files changed (50) hide show
  1. data/CHANGELOG +13 -0
  2. data/COPYING +502 -0
  3. data/README +309 -0
  4. data/Rakefile +157 -0
  5. data/TODO +6 -0
  6. data/doc/classes/X12.html +174 -0
  7. data/doc/classes/X12/Base.html +677 -0
  8. data/doc/classes/X12/Composite.html +156 -0
  9. data/doc/classes/X12/Empty.html +186 -0
  10. data/doc/classes/X12/Field.html +339 -0
  11. data/doc/classes/X12/Loop.html +202 -0
  12. data/doc/classes/X12/Parser.html +306 -0
  13. data/doc/classes/X12/Segment.html +277 -0
  14. data/doc/classes/X12/Table.html +198 -0
  15. data/doc/created.rid +1 -0
  16. data/doc/files/CHANGELOG.html +108 -0
  17. data/doc/files/README.html +474 -0
  18. data/doc/files/TODO.html +95 -0
  19. data/doc/files/lib/X12/Base_rb.html +83 -0
  20. data/doc/files/lib/X12/Composite_rb.html +83 -0
  21. data/doc/files/lib/X12/Empty_rb.html +83 -0
  22. data/doc/files/lib/X12/Field_rb.html +83 -0
  23. data/doc/files/lib/X12/Loop_rb.html +83 -0
  24. data/doc/files/lib/X12/Parser_rb.html +83 -0
  25. data/doc/files/lib/X12/Segment_rb.html +83 -0
  26. data/doc/files/lib/X12/Table_rb.html +83 -0
  27. data/doc/files/lib/X12_rb.html +100 -0
  28. data/doc/fr_class_index.html +35 -0
  29. data/doc/fr_file_index.html +38 -0
  30. data/doc/fr_method_index.html +62 -0
  31. data/doc/index.html +27 -0
  32. data/doc/rdoc-style.css +208 -0
  33. data/example/factory.rb +92 -0
  34. data/example/parse.rb +56 -0
  35. data/lib/X12.rb +50 -0
  36. data/lib/X12/Base.rb +192 -0
  37. data/lib/X12/Composite.rb +37 -0
  38. data/lib/X12/Empty.rb +43 -0
  39. data/lib/X12/Field.rb +81 -0
  40. data/lib/X12/Loop.rb +74 -0
  41. data/lib/X12/Parser.rb +98 -0
  42. data/lib/X12/Segment.rb +92 -0
  43. data/lib/X12/Table.rb +44 -0
  44. data/lib/X12/x12syntax.treetop +256 -0
  45. data/misc/997.d12 +885 -0
  46. data/misc/rdoc_template.rb +697 -0
  47. data/test/tc_factory_997.rb +130 -0
  48. data/test/tc_parse_997.rb +146 -0
  49. data/test/ts_x12.rb +27 -0
  50. metadata +108 -0
@@ -0,0 +1,37 @@
1
+ #--
2
+ # This file is part of the X12Parser library that provides tools to
3
+ # manipulate X12 messages using Ruby native syntax.
4
+ #
5
+ # http://x12parser.rubyforge.org
6
+ #
7
+ # Copyright (C) 2008 APP Design, Inc.
8
+ #
9
+ # This library is free software; you can redistribute it and/or
10
+ # modify it under the terms of the GNU Lesser General Public
11
+ # License as published by the Free Software Foundation; either
12
+ # version 2.1 of the License, or (at your option) any later version.
13
+ #
14
+ # This library is distributed in the hope that it will be useful,
15
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17
+ # Lesser General Public License for more details.
18
+ #
19
+ # You should have received a copy of the GNU Lesser General Public
20
+ # License along with this library; if not, write to the Free Software
21
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22
+ #++
23
+ #
24
+ module X12
25
+
26
+ # $Id: Composite.rb 35 2008-11-13 18:33:44Z ikk $
27
+ #
28
+ # Class implementing a composite field.
29
+
30
+ class Composite < Base
31
+
32
+ # Make a printable representation of the composite
33
+ def inspect
34
+ "Composite "+super.inspect
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,43 @@
1
+ #--
2
+ # This file is part of the X12Parser library that provides tools to
3
+ # manipulate X12 messages using Ruby native syntax.
4
+ #
5
+ # http://x12parser.rubyforge.org
6
+ #
7
+ # Copyright (C) 2008 APP Design, Inc.
8
+ #
9
+ # This library is free software; you can redistribute it and/or
10
+ # modify it under the terms of the GNU Lesser General Public
11
+ # License as published by the Free Software Foundation; either
12
+ # version 2.1 of the License, or (at your option) any later version.
13
+ #
14
+ # This library is distributed in the hope that it will be useful,
15
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17
+ # Lesser General Public License for more details.
18
+ #
19
+ # You should have received a copy of the GNU Lesser General Public
20
+ # License along with this library; if not, write to the Free Software
21
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22
+ #++
23
+ #
24
+ module X12
25
+
26
+ # $Id: Empty.rb 35 2008-11-13 18:33:44Z ikk $
27
+ #
28
+ # Class indicating the absense of any X12 element, be it loop, segment, or anything else like that.
29
+
30
+ class Empty < Base
31
+
32
+ # Create a new empty
33
+ def initialize
34
+ super(nil, [])
35
+ end
36
+
37
+ # Returns an empty string
38
+ def to_s
39
+ ''
40
+ end
41
+
42
+ end # Empty
43
+ end # X12
@@ -0,0 +1,81 @@
1
+ #--
2
+ # This file is part of the X12Parser library that provides tools to
3
+ # manipulate X12 messages using Ruby native syntax.
4
+ #
5
+ # http://x12parser.rubyforge.org
6
+ #
7
+ # Copyright (C) 2008 APP Design, Inc.
8
+ #
9
+ # This library is free software; you can redistribute it and/or
10
+ # modify it under the terms of the GNU Lesser General Public
11
+ # License as published by the Free Software Foundation; either
12
+ # version 2.1 of the License, or (at your option) any later version.
13
+ #
14
+ # This library is distributed in the hope that it will be useful,
15
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17
+ # Lesser General Public License for more details.
18
+ #
19
+ # You should have received a copy of the GNU Lesser General Public
20
+ # License along with this library; if not, write to the Free Software
21
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22
+ #++
23
+ #
24
+ module X12
25
+
26
+ # $Id: Field.rb 35 2008-11-13 18:33:44Z ikk $
27
+ #
28
+ # Class to represent a segment field. Please note, it's not a descendant of Base.
29
+
30
+ class Field
31
+ attr_reader :name, :type, :required, :min_length, :max_length, :validation
32
+ attr_writer :content
33
+
34
+ # Create a new field with given parameters
35
+ def initialize(name, type, required, min_length, max_length, validation)
36
+ @name = name
37
+ @type = type
38
+ @required = required == 'R' ? true : false
39
+ @min_length = min_length.to_i
40
+ @max_length = max_length.to_i
41
+ @validation = validation
42
+ @content = nil
43
+ end
44
+
45
+ # Returns printable string with field's content
46
+ def inspect
47
+ "Field #{name}|#{type}|#{required}|#{min_length}-#{max_length}|#{validation} <#{@content}>"
48
+ end
49
+
50
+ # Synonym for 'render'
51
+ def to_s
52
+ render
53
+ end
54
+
55
+ def render
56
+ # FIXME - this is for debug only
57
+ @content || ''
58
+ end # render
59
+
60
+ # Check if it's been set yet
61
+ def has_content?
62
+ !@content.nil?
63
+ end
64
+
65
+ # Erase the content
66
+ def set_empty!
67
+ @content = nil
68
+ end
69
+
70
+ # def to_regexp
71
+ # r = case type
72
+ # when 'I' : "\\d{#{min_length},#{max_length}}"
73
+ # when 'S' : ".{#{min_length},#{max_length}}"
74
+ # when /C.*/ : 'composite'
75
+ # when /"(.*)"/ : $1
76
+ # else ''
77
+ # end # case
78
+ # Regexp.new("#{CONSTANT[:field]}#{r}")
79
+ # end
80
+ end
81
+ end
@@ -0,0 +1,74 @@
1
+ #--
2
+ # This file is part of the X12Parser library that provides tools to
3
+ # manipulate X12 messages using Ruby native syntax.
4
+ #
5
+ # http://x12parser.rubyforge.org
6
+ #
7
+ # Copyright (C) 2008 APP Design, Inc.
8
+ #
9
+ # This library is free software; you can redistribute it and/or
10
+ # modify it under the terms of the GNU Lesser General Public
11
+ # License as published by the Free Software Foundation; either
12
+ # version 2.1 of the License, or (at your option) any later version.
13
+ #
14
+ # This library is distributed in the hope that it will be useful,
15
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17
+ # Lesser General Public License for more details.
18
+ #
19
+ # You should have received a copy of the GNU Lesser General Public
20
+ # License along with this library; if not, write to the Free Software
21
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22
+ #++
23
+ #
24
+ module X12
25
+
26
+ # $Id: Loop.rb 35 2008-11-13 18:33:44Z ikk $
27
+ #
28
+ # Implements nested loops of segments
29
+
30
+ class Loop < Base
31
+
32
+ # def regexp
33
+ # @regexp ||=
34
+ # Regexp.new(inject(''){|s, i|
35
+ # puts i.class
36
+ # s += case i
37
+ # when X12::Segment: "(#{i.regexp.source}){#{i.repeats.begin},#{i.repeats.end}}"
38
+ # when X12::Loop: "(.*?)"
39
+ # else
40
+ # ''
41
+ # end
42
+ # })
43
+ # end
44
+
45
+ # Parse a string and fill out internal structures with the pieces of it. Returns
46
+ # an unparsed portion of the string or the original string if nothing was parsed out.
47
+ def parse(str)
48
+ #puts "Parsing loop #{name}: "+str
49
+ s = str
50
+ nodes.each{|i|
51
+ m = i.parse(s)
52
+ s = m if m
53
+ }
54
+ if str == s
55
+ return nil
56
+ else
57
+ self.parsed_str = str[0..-s.length-1]
58
+ s = do_repeats(s)
59
+ end
60
+ #puts 'Parsed loop '+self.inspect
61
+ return s
62
+ end # parse
63
+
64
+ # Render all components of this loop as string suitable for EDI
65
+ def render
66
+ self.to_a.inject(''){|loop_str, i|
67
+ loop_str += i.nodes.inject(''){|nodes_str, j|
68
+ nodes_str += j.render
69
+ }
70
+ }
71
+ end # render
72
+
73
+ end # Loop
74
+ end # X12
@@ -0,0 +1,98 @@
1
+ #--
2
+ # This file is part of the X12Parser library that provides tools to
3
+ # manipulate X12 messages using Ruby native syntax.
4
+ #
5
+ # http://x12parser.rubyforge.org
6
+ #
7
+ # Copyright (C) 2008 APP Design, Inc.
8
+ #
9
+ # This library is free software; you can redistribute it and/or
10
+ # modify it under the terms of the GNU Lesser General Public
11
+ # License as published by the Free Software Foundation; either
12
+ # version 2.1 of the License, or (at your option) any later version.
13
+ #
14
+ # This library is distributed in the hope that it will be useful,
15
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17
+ # Lesser General Public License for more details.
18
+ #
19
+ # You should have received a copy of the GNU Lesser General Public
20
+ # License along with this library; if not, write to the Free Software
21
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22
+ #++
23
+ #
24
+ module X12
25
+
26
+ # $Id: Parser.rb 35 2008-11-13 18:33:44Z ikk $
27
+ #
28
+ # Main class for creating X12 parsers and factories.
29
+
30
+ class Parser
31
+
32
+ # Creates a parser out of a definition
33
+ def initialize(file_name)
34
+ str = File.open(file_name, 'r').read
35
+ treetop_parser = X12::X12syntaxParser.new
36
+ res = treetop_parser.parse(str)
37
+ throw Exception.new("Cannot parse X12 definition in #{file_name}") unless res
38
+ @x12_definition = res.get
39
+
40
+ # Populate fields in all segments found in all the loops
41
+ @x12_definition[X12::Loop].each_pair{|k, v|
42
+ #puts "Processing loop #{k}"
43
+ process_loop(v)
44
+ }
45
+ # @x12_definition.keys.each{|t|
46
+ # puts "**** #{t}"
47
+
48
+ # case
49
+ # when t==X12::Segment: @x12_definition[t].each{|i| puts i.inspect; puts i.regexp.source}
50
+ # when t==X12::Loop: @x12_definition[t].each{|i| puts i.inspect.gsub(/\\*\"/, '"') ; puts i.regexp.source}
51
+ # else
52
+ # puts @x12_definition[t].inspect
53
+ # end
54
+ # puts "\n\n"
55
+ # }
56
+
57
+ end
58
+
59
+ # Parse a loop of a given name out of a string. Throws an exception if the loop name is not defined.
60
+ def parse(loop_name, str)
61
+ loop = @x12_definition[X12::Loop][loop_name]
62
+ throw Exception.new("Cannot find a definition for loop #{loop_name}") unless loop
63
+ loop = loop.dup
64
+ loop.parse(str)
65
+ return loop
66
+ end # parse
67
+
68
+ # Make an empty loop to be filled out with information
69
+ def factory(loop_name)
70
+ loop = @x12_definition[X12::Loop][loop_name]
71
+ throw Exception.new("Cannot find a definition for loop #{loop_name}") unless loop
72
+ loop = loop.dup
73
+ return loop
74
+ end # factory
75
+
76
+ # Recursively scan the loop and instantiate fields' definitions for all its
77
+ # segments
78
+ def process_loop(loop)
79
+ loop.nodes.each{|i|
80
+ case i
81
+ when X12::Loop: process_loop(i)
82
+ when X12::Segment: process_segment(i)
83
+ else return
84
+ end
85
+ }
86
+ end
87
+
88
+ # Instantiate segment's fields as previously defined
89
+ def process_segment(segment)
90
+ segment_definition = @x12_definition[X12::Segment][segment.name]
91
+ return unless segment_definition
92
+ segment_definition.nodes.each_index{|i|
93
+ segment.nodes[i] = segment_definition.nodes[i]
94
+ }
95
+ end
96
+
97
+ end # Parser
98
+ end
@@ -0,0 +1,92 @@
1
+ #--
2
+ # This file is part of the X12Parser library that provides tools to
3
+ # manipulate X12 messages using Ruby native syntax.
4
+ #
5
+ # http://x12parser.rubyforge.org
6
+ #
7
+ # Copyright (C) 2008 APP Design, Inc.
8
+ #
9
+ # This library is free software; you can redistribute it and/or
10
+ # modify it under the terms of the GNU Lesser General Public
11
+ # License as published by the Free Software Foundation; either
12
+ # version 2.1 of the License, or (at your option) any later version.
13
+ #
14
+ # This library is distributed in the hope that it will be useful,
15
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17
+ # Lesser General Public License for more details.
18
+ #
19
+ # You should have received a copy of the GNU Lesser General Public
20
+ # License along with this library; if not, write to the Free Software
21
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22
+ #++
23
+ #
24
+ module X12
25
+
26
+ # $Id: Segment.rb 35 2008-11-13 18:33:44Z ikk $
27
+ #
28
+ # Implements a segment containing fields or composites
29
+
30
+ class Segment < Base
31
+
32
+ # Parses this segment out of a string, puts the match into value, returns the rest of the string - nil
33
+ # if cannot parse
34
+ def parse(str)
35
+ s = str
36
+ #puts "Parsing segment #{name} from #{s} with regexp [#{regexp.source}]"
37
+ m = regexp.match(s)
38
+ #puts "Matched #{m ? m[0] : 'nothing'}"
39
+
40
+ return nil unless m
41
+
42
+ s = m.post_match
43
+ self.parsed_str = m[0]
44
+ s = do_repeats(s)
45
+
46
+ #puts "Parsed segment "+self.inspect
47
+ return s
48
+ end # parse
49
+
50
+ # Render all components of this segment as string suitable for EDI
51
+ def render
52
+ self.to_a.inject(''){|repeat_str, i|
53
+ if i.repeats.begin < 1 and !i.has_content?
54
+ # Skip optional empty segments
55
+ repeat_str
56
+ else
57
+ # Have to render no matter how empty
58
+ repeat_str += i.name+i.nodes.reverse.inject(''){|nodes_str, j|
59
+ field = j.render
60
+ (j.required or nodes_str != '' or field != '') ? field_separator+field+nodes_str : nodes_str
61
+ } + segment_separator
62
+ end
63
+ }
64
+ end # render
65
+
66
+ # Returns a regexp that matches this particular segment
67
+ def regexp
68
+ @regexp ||= Regexp.new("^#{name}#{Regexp.escape(field_separator)}[^#{Regexp.escape(segment_separator)}]*#{Regexp.escape(segment_separator)}")
69
+ end
70
+
71
+ # Finds a field in the segment. Returns EMPTY if not found.
72
+ def find_field(str)
73
+ #puts "Finding field [#{str}] in #{self.class} #{name}"
74
+ # If there is such a field to begin with
75
+ field_num = nil
76
+ self.nodes.each_index{|i|
77
+ field_num = i if str == self.nodes[i].name
78
+ }
79
+ return EMPTY if field_num.nil?
80
+ #puts field_num
81
+
82
+ # Parse the segment if not parsed already
83
+ unless @fields
84
+ @fields = self.to_s.chop.split(Regexp.new(Regexp.escape(field_separator)))
85
+ self.nodes.each_index{|i| self.nodes[i].content = @fields[i+1] }
86
+ end
87
+ #puts self.nodes[field_num].inspect
88
+ return self.nodes[field_num]
89
+ end
90
+
91
+ end # Segment
92
+ end # X12
@@ -0,0 +1,44 @@
1
+ #--
2
+ # This file is part of the X12Parser library that provides tools to
3
+ # manipulate X12 messages using Ruby native syntax.
4
+ #
5
+ # http://x12parser.rubyforge.org
6
+ #
7
+ # Copyright (C) 2008 APP Design, Inc.
8
+ #
9
+ # This library is free software; you can redistribute it and/or
10
+ # modify it under the terms of the GNU Lesser General Public
11
+ # License as published by the Free Software Foundation; either
12
+ # version 2.1 of the License, or (at your option) any later version.
13
+ #
14
+ # This library is distributed in the hope that it will be useful,
15
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17
+ # Lesser General Public License for more details.
18
+ #
19
+ # You should have received a copy of the GNU Lesser General Public
20
+ # License along with this library; if not, write to the Free Software
21
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22
+ #++
23
+ #
24
+ module X12
25
+
26
+ # $Id: Table.rb 35 2008-11-13 18:33:44Z ikk $
27
+ #
28
+ # This just a named hash to store validation tables.
29
+
30
+ class Table < Hash
31
+ attr_reader :name
32
+
33
+ # Create a new table with given name and hash content.
34
+ def initialize(name, name_values)
35
+ @name = name
36
+ self.merge!(name_values)
37
+ end
38
+
39
+ # Return a printable string representing this table
40
+ def inspect
41
+ "Table #{name} -- #{super.inspect}"
42
+ end
43
+ end
44
+ end