barcode1dtools 0.9.6.0 → 0.9.7.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.
- data/lib/barcode1dtools.rb +8 -2
- data/lib/barcode1dtools/codabar.rb +1 -2
- data/lib/barcode1dtools/code11.rb +1 -2
- data/lib/barcode1dtools/coop2of5.rb +222 -0
- data/lib/barcode1dtools/iata2of5.rb +223 -0
- data/lib/barcode1dtools/industrial2of5.rb +223 -0
- data/lib/barcode1dtools/matrix2of5.rb +222 -0
- data/lib/barcode1dtools/postnet.rb +223 -0
- data/test/test_barcode1dcoop2of5.rb +79 -0
- data/test/test_barcode1diata2of5.rb +79 -0
- data/test/test_barcode1dindustrial2of5.rb +79 -0
- data/test/test_barcode1dmatrix2of5.rb +79 -0
- data/test/test_barcode1dpostnet.rb +87 -0
- metadata +20 -4
data/lib/barcode1dtools.rb
CHANGED
@@ -16,8 +16,9 @@ module Barcode1DTools
|
|
16
16
|
# 1-dimensional barcode patterns for various code types. The
|
17
17
|
# library currently includes EAN-13, EAN-8, UPC-A, UPC-E, UPC
|
18
18
|
# Supplemental 2, UPC Supplemental 5, Interleaved 2 of 5 (I 2/5),
|
19
|
-
#
|
20
|
-
#
|
19
|
+
# COOP 2 of 5, Matrix 2 of 5, Industrial 2 of 5, IATA 2 of 5,
|
20
|
+
# PostNet, Code 3 of 9, Code 93, Code 11, and Codabar, but will
|
21
|
+
# be expanded to include most 1D symbologies in the near future.
|
21
22
|
#
|
22
23
|
#== Example
|
23
24
|
# ean13 = Barcode1DTools::EAN13.new('0012676510226', :line_character => 'x', :space_character => ' ')
|
@@ -121,3 +122,8 @@ require 'barcode1dtools/code3of9'
|
|
121
122
|
require 'barcode1dtools/code93'
|
122
123
|
require 'barcode1dtools/codabar'
|
123
124
|
require 'barcode1dtools/code11'
|
125
|
+
require 'barcode1dtools/coop2of5'
|
126
|
+
require 'barcode1dtools/industrial2of5'
|
127
|
+
require 'barcode1dtools/iata2of5'
|
128
|
+
require 'barcode1dtools/matrix2of5'
|
129
|
+
require 'barcode1dtools/postnet'
|
@@ -62,8 +62,7 @@ module Barcode1DTools
|
|
62
62
|
# is twice the width of a "narrow" item.
|
63
63
|
#
|
64
64
|
# The "width" method will tell you the total end-to-end width, in
|
65
|
-
# units, of the entire barcode.
|
66
|
-
# unavailable for this symbology.
|
65
|
+
# units, of the entire barcode.
|
67
66
|
#
|
68
67
|
#== Rendering
|
69
68
|
#
|
@@ -53,8 +53,7 @@ module Barcode1DTools
|
|
53
53
|
# is twice the width of a "narrow" item.
|
54
54
|
#
|
55
55
|
# The "width" method will tell you the total end-to-end width, in
|
56
|
-
# units, of the entire barcode.
|
57
|
-
# unavailable for this symbology.
|
56
|
+
# units, of the entire barcode.
|
58
57
|
#
|
59
58
|
#== Rendering
|
60
59
|
#
|
@@ -0,0 +1,222 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright 2012 Michael Chaney Consulting Corporation
|
3
|
+
#
|
4
|
+
# Released under the terms of the MIT License or the GNU
|
5
|
+
# General Public License, v. 2
|
6
|
+
#++
|
7
|
+
|
8
|
+
module Barcode1DTools
|
9
|
+
|
10
|
+
# Barcode1DTools::Coop2of5 - Create and decode bar patterns for
|
11
|
+
# COOP 2 of 5. The value encoded is a number with digits 0-9.
|
12
|
+
# Internally, the value is treated as a string to preserve
|
13
|
+
# leading zeroes.
|
14
|
+
#
|
15
|
+
# Use :checksum_included => true if you have already added a
|
16
|
+
# checksum and wish to have it validated, or :skip_checksum =>
|
17
|
+
# true if you don't wish to add one or have it validated.
|
18
|
+
#
|
19
|
+
# COOP 2 of 5 is low-density and limited. It should not be
|
20
|
+
# used in any new applications.
|
21
|
+
#
|
22
|
+
# val = "3423"
|
23
|
+
# bc = Barcode1DTools::Coop2of5.new(val)
|
24
|
+
# pattern = bc.bars
|
25
|
+
# rle_pattern = bc.rle
|
26
|
+
# width = bc.width
|
27
|
+
#
|
28
|
+
# The object created is immutable.
|
29
|
+
#
|
30
|
+
# Barcode1DTools::Coop2of5 creates the patterns that you need to
|
31
|
+
# display COOP 2 of 5 barcodes. It can also decode a simple w/n
|
32
|
+
# string.
|
33
|
+
#
|
34
|
+
# Coop2of5 characters consist of 3 bars and 2 spaces, with a narrow
|
35
|
+
# space between them. 2 of the bars/spaces in each symbol are wide.
|
36
|
+
#
|
37
|
+
# There are three formats for the returned pattern:
|
38
|
+
#
|
39
|
+
# bars - 1s and 0s specifying black lines and white spaces. Actual
|
40
|
+
# characters can be changed from "1" and 0" with options
|
41
|
+
# :line_character and :space_character.
|
42
|
+
#
|
43
|
+
# rle - Run-length-encoded version of the pattern. The first
|
44
|
+
# number is always a black line, with subsequent digits
|
45
|
+
# alternating between spaces and lines. The digits specify
|
46
|
+
# the width of each line or space.
|
47
|
+
#
|
48
|
+
# wn - The native format for this barcode type. The string
|
49
|
+
# consists of a series of "w" and "n" characters. The first
|
50
|
+
# item is always a black line, with subsequent characters
|
51
|
+
# alternating between spaces and lines. A "wide" item
|
52
|
+
# is twice the width of a "narrow" item.
|
53
|
+
#
|
54
|
+
# The "width" method will tell you the total end-to-end width, in
|
55
|
+
# units, of the entire barcode.
|
56
|
+
#
|
57
|
+
#== Rendering
|
58
|
+
#
|
59
|
+
# The standard w/n ratio seems to be 2:1. There seem to be no real
|
60
|
+
# standards for display.
|
61
|
+
|
62
|
+
class Coop2of5 < Barcode1D
|
63
|
+
|
64
|
+
# Character sequence - 0-based offset in this string is character
|
65
|
+
# number
|
66
|
+
CHAR_SEQUENCE = "0123456789"
|
67
|
+
|
68
|
+
# Patterns for making bar codes. Note that the position
|
69
|
+
# weights are 7, 4, 2, 1 and the last bit is parity.
|
70
|
+
# Each letter is an alternating bar then space, and there
|
71
|
+
# is a narrow space between each character.
|
72
|
+
PATTERNS = {
|
73
|
+
'0'=> {'val'=>0 ,'wn'=>'wwnnn'},
|
74
|
+
'1'=> {'val'=>1 ,'wn'=>'nnnww'},
|
75
|
+
'2'=> {'val'=>2 ,'wn'=>'nnwnw'},
|
76
|
+
'3'=> {'val'=>3 ,'wn'=>'nnwwn'},
|
77
|
+
'4'=> {'val'=>4 ,'wn'=>'nwnnw'},
|
78
|
+
'5'=> {'val'=>5 ,'wn'=>'nwnwn'},
|
79
|
+
'6'=> {'val'=>6 ,'wn'=>'nwwnn'},
|
80
|
+
'7'=> {'val'=>7 ,'wn'=>'wnnnw'},
|
81
|
+
'8'=> {'val'=>8 ,'wn'=>'wnnwn'},
|
82
|
+
'9'=> {'val'=>9 ,'wn'=>'wnwnn'}
|
83
|
+
}
|
84
|
+
|
85
|
+
GUARD_PATTERN_LEFT_WN = 'wnw'
|
86
|
+
GUARD_PATTERN_RIGHT_WN = 'nww'
|
87
|
+
|
88
|
+
DEFAULT_OPTIONS = {
|
89
|
+
:line_character => '1',
|
90
|
+
:space_character => '0',
|
91
|
+
:w_character => 'w',
|
92
|
+
:n_character => 'n',
|
93
|
+
:wn_ratio => '2'
|
94
|
+
}
|
95
|
+
|
96
|
+
class << self
|
97
|
+
# Coop2of5 can encode digits
|
98
|
+
def can_encode?(value)
|
99
|
+
value.to_s =~ /\A[0-9]+\z/
|
100
|
+
end
|
101
|
+
|
102
|
+
def generate_check_digit_for(value)
|
103
|
+
raise UnencodableCharactersError unless self.can_encode?(value)
|
104
|
+
mult = 3
|
105
|
+
value = value.reverse.split('').inject(0) { |a,c| mult = 4 - mult ; a + c.to_i * mult }
|
106
|
+
(10 - (value % 10)) % 10
|
107
|
+
end
|
108
|
+
|
109
|
+
def validate_check_digit_for(value)
|
110
|
+
raise UnencodableCharactersError unless self.can_encode?(value)
|
111
|
+
md = value.match(/^(\d+?)(\d)$/)
|
112
|
+
self.generate_check_digit_for(md[1]) == md[2].to_i
|
113
|
+
end
|
114
|
+
|
115
|
+
# Decode a string in rle format. This will return a Coop2of5
|
116
|
+
# object.
|
117
|
+
def decode(str, options = {})
|
118
|
+
if str =~ /[^1-3]/ && str =~ /[^wn]/
|
119
|
+
raise UnencodableCharactersError, "Pattern must be rle or wn"
|
120
|
+
end
|
121
|
+
|
122
|
+
# ensure a wn string
|
123
|
+
if str =~ /[1-3]/
|
124
|
+
str = str.tr('123','nww')
|
125
|
+
end
|
126
|
+
|
127
|
+
if str.reverse =~ /\A#{GUARD_PATTERN_LEFT_WN}n.*?#{GUARD_PATTERN_RIGHT_WN}\z/
|
128
|
+
str.reverse!
|
129
|
+
end
|
130
|
+
|
131
|
+
unless str =~ /\A#{GUARD_PATTERN_LEFT_WN}n(.*?)#{GUARD_PATTERN_RIGHT_WN}\z/
|
132
|
+
raise UnencodableCharactersError, "Start/stop pattern is not detected."
|
133
|
+
end
|
134
|
+
|
135
|
+
wn_pattern = $1
|
136
|
+
|
137
|
+
# Each pattern is 3 bars and 2 spaces, with a space between.
|
138
|
+
unless wn_pattern.size % 6 == 0
|
139
|
+
raise UnencodableCharactersError, "Wrong number of bars."
|
140
|
+
end
|
141
|
+
|
142
|
+
decoded_string = ''
|
143
|
+
|
144
|
+
wn_pattern.scan(/(.{5})n/).each do |chunk|
|
145
|
+
|
146
|
+
chunk = chunk.first
|
147
|
+
found = false
|
148
|
+
|
149
|
+
PATTERNS.each do |char,hsh|
|
150
|
+
if chunk == hsh['wn']
|
151
|
+
decoded_string += char
|
152
|
+
found = true
|
153
|
+
break;
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
raise UndecodableCharactersError, "Invalid sequence: #{chunk}" unless found
|
158
|
+
|
159
|
+
end
|
160
|
+
|
161
|
+
Coop2of5.new(decoded_string, options)
|
162
|
+
end
|
163
|
+
|
164
|
+
end
|
165
|
+
|
166
|
+
# Options are :line_character, :space_character, :w_character,
|
167
|
+
# :n_character, :checksum_included, and :skip_checksum.
|
168
|
+
def initialize(value, options = {})
|
169
|
+
|
170
|
+
@options = DEFAULT_OPTIONS.merge(options)
|
171
|
+
|
172
|
+
# Can we encode this value?
|
173
|
+
raise UnencodableCharactersError unless self.class.can_encode?(value)
|
174
|
+
|
175
|
+
@value = value.to_s
|
176
|
+
|
177
|
+
if @options[:skip_checksum]
|
178
|
+
@encoded_string = value.to_s
|
179
|
+
@value = value.to_s
|
180
|
+
@check_digit = nil
|
181
|
+
elsif @options[:checksum_included]
|
182
|
+
@encoded_string = value.to_s
|
183
|
+
raise ChecksumError unless self.class.validate_check_digit_for(@encoded_string)
|
184
|
+
md = @encoded_string.match(/^(\d+?)(\d)$/)
|
185
|
+
@value, @check_digit = md[1], md[2].to_i
|
186
|
+
else
|
187
|
+
@value = value.to_s
|
188
|
+
@check_digit = self.class.generate_check_digit_for(@value)
|
189
|
+
@encoded_string = "#{@value}#{@check_digit}"
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
# Returns a string of "w" or "n" ("wide" and "narrow")
|
194
|
+
def wn
|
195
|
+
@wn ||= wn_str.tr('wn', @options[:w_character].to_s + @options[:n_character].to_s)
|
196
|
+
end
|
197
|
+
|
198
|
+
# returns a run-length-encoded string representation
|
199
|
+
def rle
|
200
|
+
@rle ||= self.class.wn_to_rle(self.wn, @options)
|
201
|
+
end
|
202
|
+
|
203
|
+
# returns 1s and 0s (for "black" and "white")
|
204
|
+
def bars
|
205
|
+
@bars ||= self.class.rle_to_bars(self.rle, @options)
|
206
|
+
end
|
207
|
+
|
208
|
+
# returns the total unit width of the bar code
|
209
|
+
def width
|
210
|
+
@width ||= rle.split('').inject(0) { |a,c| a + c.to_i }
|
211
|
+
end
|
212
|
+
|
213
|
+
private
|
214
|
+
|
215
|
+
# Creates the actual w/n pattern. Note that there is a narrow space
|
216
|
+
# between each character.
|
217
|
+
def wn_str
|
218
|
+
@wn_str ||= GUARD_PATTERN_LEFT_WN + 'n' + @encoded_string.split('').collect { |c| PATTERNS[c]['wn'] }.join('n') + 'n' + GUARD_PATTERN_RIGHT_WN
|
219
|
+
end
|
220
|
+
|
221
|
+
end
|
222
|
+
end
|
@@ -0,0 +1,223 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright 2012 Michael Chaney Consulting Corporation
|
3
|
+
#
|
4
|
+
# Released under the terms of the MIT License or the GNU
|
5
|
+
# General Public License, v. 2
|
6
|
+
#++
|
7
|
+
|
8
|
+
module Barcode1DTools
|
9
|
+
|
10
|
+
# Barcode1DTools::IATA2of5 - Create and decode bar patterns for
|
11
|
+
# IATA 2 of 5. The value encoded is a number with digits 0-9.
|
12
|
+
# Internally, the value is treated as a string to preserve
|
13
|
+
# leading zeroes. This is identical to Industrial 2 of 5 but
|
14
|
+
# with different guard patterns.
|
15
|
+
#
|
16
|
+
# Use :checksum_included => true if you have already added a
|
17
|
+
# checksum and wish to have it validated, or :skip_checksum =>
|
18
|
+
# true if you don't want to add it or wish to skip checking.
|
19
|
+
#
|
20
|
+
# IATA 2 of 5 is low-density and limited. It should not be
|
21
|
+
# used in any new applications.
|
22
|
+
#
|
23
|
+
# val = "3423"
|
24
|
+
# bc = Barcode1DTools::IATA2of5.new(val)
|
25
|
+
# pattern = bc.bars
|
26
|
+
# rle_pattern = bc.rle
|
27
|
+
# width = bc.width
|
28
|
+
#
|
29
|
+
# The object created is immutable.
|
30
|
+
#
|
31
|
+
# Barcode1DTools::IATA2of5 creates the patterns that you need to
|
32
|
+
# display IATA 2 of 5 barcodes. It can also decode a simple w/n
|
33
|
+
# string.
|
34
|
+
#
|
35
|
+
# IATA2of5 characters consist of 3 bars and 2 spaces, with a narrow
|
36
|
+
# space between them. 2 of the bars/spaces in each symbol are wide.
|
37
|
+
#
|
38
|
+
# There are three formats for the returned pattern:
|
39
|
+
#
|
40
|
+
# bars - 1s and 0s specifying black lines and white spaces. Actual
|
41
|
+
# characters can be changed from "1" and 0" with options
|
42
|
+
# :line_character and :space_character.
|
43
|
+
#
|
44
|
+
# rle - Run-length-encoded version of the pattern. The first
|
45
|
+
# number is always a black line, with subsequent digits
|
46
|
+
# alternating between spaces and lines. The digits specify
|
47
|
+
# the width of each line or space.
|
48
|
+
#
|
49
|
+
# wn - The native format for this barcode type. The string
|
50
|
+
# consists of a series of "w" and "n" characters. The first
|
51
|
+
# item is always a black line, with subsequent characters
|
52
|
+
# alternating between spaces and lines. A "wide" item
|
53
|
+
# is twice the width of a "narrow" item.
|
54
|
+
#
|
55
|
+
# The "width" method will tell you the total end-to-end width, in
|
56
|
+
# units, of the entire barcode.
|
57
|
+
#
|
58
|
+
#== Rendering
|
59
|
+
#
|
60
|
+
# The standard w/n ratio seems to be 2:1. There seem to be no real
|
61
|
+
# standards for display.
|
62
|
+
|
63
|
+
class IATA2of5 < Barcode1D
|
64
|
+
|
65
|
+
# Character sequence - 0-based offset in this string is character
|
66
|
+
# number
|
67
|
+
CHAR_SEQUENCE = "0123456789"
|
68
|
+
|
69
|
+
# Patterns for making bar codes. Note that the position
|
70
|
+
# weights are 1, 2, 4, and 7 and the last bit is parity.
|
71
|
+
# The patterns are for the bars, all spaces are narrow.
|
72
|
+
PATTERNS = {
|
73
|
+
'0'=> {'val'=>0 ,'wn'=>'nnnnwnwnn'},
|
74
|
+
'1'=> {'val'=>1 ,'wn'=>'wnnnnnnnw'},
|
75
|
+
'2'=> {'val'=>2 ,'wn'=>'nnwnnnnnw'},
|
76
|
+
'3'=> {'val'=>3 ,'wn'=>'wnwnnnnnn'},
|
77
|
+
'4'=> {'val'=>4 ,'wn'=>'nnnnwnnnw'},
|
78
|
+
'5'=> {'val'=>5 ,'wn'=>'wnnnwnnnn'},
|
79
|
+
'6'=> {'val'=>6 ,'wn'=>'nnwnwnnnn'},
|
80
|
+
'7'=> {'val'=>7 ,'wn'=>'nnnnnnwnw'},
|
81
|
+
'8'=> {'val'=>8 ,'wn'=>'wnnnnnwnn'},
|
82
|
+
'9'=> {'val'=>9 ,'wn'=>'nnwnnnwnn'}
|
83
|
+
}
|
84
|
+
|
85
|
+
GUARD_PATTERN_LEFT_WN = 'nnn'
|
86
|
+
GUARD_PATTERN_RIGHT_WN = 'wnn'
|
87
|
+
|
88
|
+
DEFAULT_OPTIONS = {
|
89
|
+
:line_character => '1',
|
90
|
+
:space_character => '0',
|
91
|
+
:w_character => 'w',
|
92
|
+
:n_character => 'n',
|
93
|
+
:wn_ratio => '2'
|
94
|
+
}
|
95
|
+
|
96
|
+
class << self
|
97
|
+
# IATA2of5 can encode digits
|
98
|
+
def can_encode?(value)
|
99
|
+
value.to_s =~ /\A[0-9]+\z/
|
100
|
+
end
|
101
|
+
|
102
|
+
def generate_check_digit_for(value)
|
103
|
+
raise UnencodableCharactersError unless self.can_encode?(value)
|
104
|
+
mult = 3
|
105
|
+
value = value.reverse.split('').inject(0) { |a,c| mult = 4 - mult ; a + c.to_i * mult }
|
106
|
+
(10 - (value % 10)) % 10
|
107
|
+
end
|
108
|
+
|
109
|
+
def validate_check_digit_for(value)
|
110
|
+
raise UnencodableCharactersError unless self.can_encode?(value)
|
111
|
+
md = value.match(/^(\d+?)(\d)$/)
|
112
|
+
self.generate_check_digit_for(md[1]) == md[2].to_i
|
113
|
+
end
|
114
|
+
|
115
|
+
# Decode a string in rle format. This will return a IATA2of5
|
116
|
+
# object.
|
117
|
+
def decode(str, options = {})
|
118
|
+
if str =~ /[^1-3]/ && str =~ /[^wn]/
|
119
|
+
raise UnencodableCharactersError, "Pattern must be rle or wn"
|
120
|
+
end
|
121
|
+
|
122
|
+
# ensure a wn string
|
123
|
+
if str =~ /[1-3]/
|
124
|
+
str = str.tr('123','nww')
|
125
|
+
end
|
126
|
+
|
127
|
+
if str.reverse =~ /\A#{GUARD_PATTERN_LEFT_WN}n.*?#{GUARD_PATTERN_RIGHT_WN}\z/
|
128
|
+
str.reverse!
|
129
|
+
end
|
130
|
+
|
131
|
+
# Note that every other character is an "n"
|
132
|
+
unless str =~ /\A([wn]n)+[wn]\z/ && str =~ /\A#{GUARD_PATTERN_LEFT_WN}n(.*?)#{GUARD_PATTERN_RIGHT_WN}\z/
|
133
|
+
raise UnencodableCharactersError, "Start/stop pattern is not detected."
|
134
|
+
end
|
135
|
+
|
136
|
+
wn_pattern = $1
|
137
|
+
|
138
|
+
# Each pattern is 5 bars and 4 spaces, with a space between.
|
139
|
+
unless wn_pattern.size % 10 == 0
|
140
|
+
raise UnencodableCharactersError, "Wrong number of bars."
|
141
|
+
end
|
142
|
+
|
143
|
+
decoded_string = ''
|
144
|
+
|
145
|
+
wn_pattern.scan(/(.{9})n/).each do |chunk|
|
146
|
+
|
147
|
+
chunk = chunk.first
|
148
|
+
found = false
|
149
|
+
|
150
|
+
PATTERNS.each do |char,hsh|
|
151
|
+
if chunk == hsh['wn']
|
152
|
+
decoded_string += char
|
153
|
+
found = true
|
154
|
+
break;
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
raise UndecodableCharactersError, "Invalid sequence: #{chunk}" unless found
|
159
|
+
|
160
|
+
end
|
161
|
+
|
162
|
+
IATA2of5.new(decoded_string, options)
|
163
|
+
end
|
164
|
+
|
165
|
+
end
|
166
|
+
|
167
|
+
# Options are :line_character, :space_character, :w_character,
|
168
|
+
# :n_character, :checksum_included, and :skip_checksum.
|
169
|
+
def initialize(value, options = {})
|
170
|
+
|
171
|
+
@options = DEFAULT_OPTIONS.merge(options)
|
172
|
+
|
173
|
+
# Can we encode this value?
|
174
|
+
raise UnencodableCharactersError unless self.class.can_encode?(value)
|
175
|
+
|
176
|
+
@value = value.to_s
|
177
|
+
|
178
|
+
if @options[:skip_checksum]
|
179
|
+
@encoded_string = value.to_s
|
180
|
+
@value = value.to_s
|
181
|
+
@check_digit = nil
|
182
|
+
elsif @options[:checksum_included]
|
183
|
+
@encoded_string = value.to_s
|
184
|
+
raise ChecksumError unless self.class.validate_check_digit_for(@encoded_string)
|
185
|
+
md = @encoded_string.match(/^(\d+?)(\d)$/)
|
186
|
+
@value, @check_digit = md[1], md[2].to_i
|
187
|
+
else
|
188
|
+
@value = value.to_s
|
189
|
+
@check_digit = self.class.generate_check_digit_for(@value)
|
190
|
+
@encoded_string = "#{@value}#{@check_digit}"
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
# Returns a string of "w" or "n" ("wide" and "narrow")
|
195
|
+
def wn
|
196
|
+
@wn ||= wn_str.tr('wn', @options[:w_character].to_s + @options[:n_character].to_s)
|
197
|
+
end
|
198
|
+
|
199
|
+
# returns a run-length-encoded string representation
|
200
|
+
def rle
|
201
|
+
@rle ||= self.class.wn_to_rle(self.wn, @options)
|
202
|
+
end
|
203
|
+
|
204
|
+
# returns 1s and 0s (for "black" and "white")
|
205
|
+
def bars
|
206
|
+
@bars ||= self.class.rle_to_bars(self.rle, @options)
|
207
|
+
end
|
208
|
+
|
209
|
+
# returns the total unit width of the bar code
|
210
|
+
def width
|
211
|
+
@width ||= rle.split('').inject(0) { |a,c| a + c.to_i }
|
212
|
+
end
|
213
|
+
|
214
|
+
private
|
215
|
+
|
216
|
+
# Creates the actual w/n pattern. Note that there is a narrow space
|
217
|
+
# between every single bar.
|
218
|
+
def wn_str
|
219
|
+
@wn_str ||= GUARD_PATTERN_LEFT_WN + 'n' + @encoded_string.split('').collect { |c| PATTERNS[c]['wn'] }.join('n') + 'n' + GUARD_PATTERN_RIGHT_WN
|
220
|
+
end
|
221
|
+
|
222
|
+
end
|
223
|
+
end
|