barcode1dtools 1.0.1.0 → 1.0.2.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.
@@ -20,11 +20,26 @@ module Barcode1DTools
20
20
  # Because of this, there are no options for including a check
21
21
  # digit or validating one. It is always included.
22
22
  #
23
- # val = "29382-38"
24
- # bc = Barcode1DTools::Code128.new(val)
25
- # pattern = bc.bars
26
- # rle_pattern = bc.rle
27
- # width = bc.width
23
+ # Be sure to use Latin-1 (ISO-8859-1) in Ruby 1.9+ for any
24
+ # strings that use high characters. They will be encoded and
25
+ # decoded properly.
26
+ #
27
+ # == Example
28
+ # val = "This is a test"
29
+ # bc = Barcode1DTools::Code128.new(val)
30
+ # # Pass an array if you wish to use FNC characters
31
+ # val = [:fnc_1, "42184037211"]
32
+ # bc = Barcode1DTools::Code128.new(val)
33
+ # pattern = bc.bars
34
+ # rle_pattern = bc.rle
35
+ # width = bc.width
36
+ #
37
+ # It is possible to pass a raw value to be encoded by using the
38
+ # option :raw_value => true when creating the object. This
39
+ # must include the start character, string (each character
40
+ # being between 0 and 105 inclusive), the checksum character,
41
+ # and the stop character. No checks are performed on the
42
+ # string.
28
43
  #
29
44
  # The object created is immutable.
30
45
  #
@@ -34,21 +49,22 @@ module Barcode1DTools
34
49
  #
35
50
  # Code128 characters consist of 3 bars and 3 spaces.
36
51
  #
52
+ # == Formats
37
53
  # There are two formats for the returned pattern:
38
54
  #
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.
55
+ # *bars* - 1s and 0s specifying black lines and white spaces. Actual
56
+ # characters can be changed from "1" and 0" with options
57
+ # :line_character and :space_character.
42
58
  #
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.
59
+ # *rle* - Run-length-encoded version of the pattern. The first
60
+ # number is always a black line, with subsequent digits
61
+ # alternating between spaces and lines. The digits specify
62
+ # the width of each line or space.
47
63
  #
48
64
  # The "width" method will tell you the total end-to-end width, in
49
65
  # units, of the entire barcode.
50
66
  #
51
- #== Rendering
67
+ # == Rendering
52
68
  #
53
69
  # The quiet zone on each side should be at least the greater of 10
54
70
  # unit widths or 6.4mm. Typically a textual rendition of the
@@ -79,7 +95,7 @@ module Barcode1DTools
79
95
  '2331112'
80
96
  ]
81
97
 
82
- # Quicker decoding
98
+ # Helps with quicker decoding
83
99
  PATTERN_LOOKUP = (0..106).inject({}) { |a,c| a[PATTERNS[c]] = c; a }
84
100
 
85
101
  # For ease. These can also be looked up in any
@@ -98,11 +114,15 @@ module Barcode1DTools
98
114
  FNC_3 = 96
99
115
  # Note that FNC_4 is 100 in set B and 101 in set A
100
116
 
117
+ # Guard/start patterns
101
118
  GUARD_PATTERN_RIGHT_RLE = PATTERNS[STOP]
102
119
  START_A_RLE = PATTERNS[START_A]
103
120
  START_B_RLE = PATTERNS[START_B]
104
121
  START_C_RLE = PATTERNS[START_C]
105
122
 
123
+ # These are the standard labels for the low-ascii (0-31) characters.
124
+ # They aren't actually used here, but are included as they are
125
+ # useful for debugging.
106
126
  LOW_ASCII_LABELS = [
107
127
  'NUL', 'SOH', 'STX', 'ETX', 'EOT', 'ENQ', 'ACK', 'BEL',
108
128
  'BS', 'HT', 'LF', 'VT', 'FF', 'CR', 'SO', 'SI', 'DLE',
@@ -137,11 +157,17 @@ module Barcode1DTools
137
157
  }
138
158
 
139
159
  class << self
140
- # Code128 can encode anything
160
+ # Returns true if Code128 can encode the value.
161
+ # Code128 can encode anything, so this is always true.
141
162
  def can_encode?(value)
142
163
  true
143
164
  end
144
165
 
166
+ # Generates the check digit for the encoded string. Code 128
167
+ # creates the check digit based on the encoded value, so it's of
168
+ # no use outside of this module. Because the same payload may
169
+ # be represented in more than one way, the check digit can't be
170
+ # determined from the original payload value.
145
171
  def generate_check_digit_for(value)
146
172
  md = parse_code128(value)
147
173
  start = md[1].unpack('C')
@@ -149,30 +175,32 @@ module Barcode1DTools
149
175
  [md[2].unpack('C*').inject(start.first) { |a,c| (mult+=1)*c+a } % 103].pack('C')
150
176
  end
151
177
 
178
+ # Validates the check digit given an encoded value.
152
179
  def validate_check_digit_for(value)
153
180
  payload, check_digit = split_payload_and_check_digit(value)
154
181
  self.generate_check_digit_for(payload) == check_digit
155
182
  end
156
183
 
184
+ # Splits the payload (raw) and check digit.
157
185
  def split_payload_and_check_digit(value)
158
186
  md = value.to_s.match(/\A(.*)(.)\z/)
159
187
  [md[1], md[2]]
160
188
  end
161
189
 
162
- # Returns match data - 1: start character 2: payload
163
- # 3: check digit 4: stop character
190
+ # Given a raw encoded value, this returns match data -
191
+ # 1: start character 2: payload 3: check digit 4: stop
192
+ # character.
164
193
  def parse_code128(str)
165
194
  str.match(/\A([\x67-\x69])([\x00-\x66]*?)(?:([\x00-\x66])(\x6a))?\z/)
166
195
  end
167
196
 
168
197
  # Convert a code128 encoded string to an ASCII/Latin-1
169
- # representation. The return value is an array if there
170
- # are any FNC codes included. Use the option
171
- # :no_latin1 => true to simply return FNC 4 instead of
172
- # coding the following characters to the high Latin-1
198
+ # representation. The return value is an array Use the
199
+ # option :no_latin1 => true to simply return FNC 4 instead
200
+ # of coding the following characters to the high Latin-1
173
201
  # range. Use :raw_array => true if you wish to see an
174
- # array of the actual characters in the code. It will
175
- # turn any ASCII/Latin-1 characters to their standard
202
+ # array of the actual characters in the code. It will turn
203
+ # any ASCII/Latin-1 characters to their standard
176
204
  # representation, but it also includes all start, shift,
177
205
  # code change, etc. characters. Useful for debugging.
178
206
  def code128_to_latin1(str, options = {})
@@ -449,6 +477,7 @@ module Barcode1DTools
449
477
 
450
478
  end
451
479
 
480
+ # Create a new Code128 object given a value.
452
481
  # Options are :line_character, :space_character, and
453
482
  # :raw_value.
454
483
  def initialize(value, options = {})
@@ -488,22 +517,22 @@ module Barcode1DTools
488
517
  @check_digit = md[3]
489
518
  end
490
519
 
491
- # variable bar width, no w/n string
520
+ # Code 128 is variable bar width, no w/n string
492
521
  def wn
493
522
  raise NotImplementedError
494
523
  end
495
524
 
496
- # returns a run-length-encoded string representation
525
+ # Returns a run-length-encoded string representation
497
526
  def rle
498
527
  @rle ||= gen_rle(@encoded_string, @options)
499
528
  end
500
529
 
501
- # returns 1s and 0s (for "black" and "white")
530
+ # Returns 1s and 0s (for "black" and "white")
502
531
  def bars
503
532
  @bars ||= self.class.rle_to_bars(self.rle, @options)
504
533
  end
505
534
 
506
- # returns the total unit width of the bar code
535
+ # Returns the total unit width of the bar code
507
536
  def width
508
537
  @width ||= rle.split('').inject(0) { |a,c| a + c.to_i }
509
538
  end
@@ -22,14 +22,15 @@ module Barcode1DTools
22
22
  # dash "-", period ".", dollar sign "$", forward slash "/", plus
23
23
  # sign "+", percent sign "%", as well as a space " ".
24
24
  #
25
- # val = "THIS IS A TEST"
26
- # bc = Barcode1DTools::Code3of9.new(val)
27
- # pattern = bc.bars
28
- # rle_pattern = bc.rle
29
- # wn_pattern = bc.wn
30
- # width = bc.width
31
- # # Note that the check digit is actually one of the characters.
32
- # check_digit = Barcode1DTools::Code3of9.generate_check_digit_for(num)
25
+ # == Example
26
+ # val = "THIS IS A TEST"
27
+ # bc = Barcode1DTools::Code3of9.new(val)
28
+ # pattern = bc.bars
29
+ # rle_pattern = bc.rle
30
+ # wn_pattern = bc.wn
31
+ # width = bc.width
32
+ # # Note that the check digit is actually one of the characters.
33
+ # check_digit = Barcode1DTools::Code3of9.generate_check_digit_for(num)
33
34
  #
34
35
  # The object created is immutable.
35
36
  #
@@ -41,27 +42,28 @@ module Barcode1DTools
41
42
  # "wide" or "narrow", with "wide" lines or spaces being twice the
42
43
  # width of narrow lines or spaces.
43
44
  #
45
+ # == Formats
44
46
  # There are three formats for the returned pattern:
45
47
  #
46
- # bars - 1s and 0s specifying black lines and white spaces. Actual
47
- # characters can be changed from "1" and 0" with options
48
- # :line_character and :space_character.
48
+ # *bars* - 1s and 0s specifying black lines and white spaces. Actual
49
+ # characters can be changed from "1" and 0" with options
50
+ # :line_character and :space_character.
49
51
  #
50
- # rle - Run-length-encoded version of the pattern. The first
51
- # number is always a black line, with subsequent digits
52
- # alternating between spaces and lines. The digits specify
53
- # the width of each line or space.
52
+ # *rle* - Run-length-encoded version of the pattern. The first
53
+ # number is always a black line, with subsequent digits
54
+ # alternating between spaces and lines. The digits specify
55
+ # the width of each line or space.
54
56
  #
55
- # wn - The native format for this barcode type. The string
56
- # consists of a series of "w" and "n" characters. The first
57
- # item is always a black line, with subsequent characters
58
- # alternating between spaces and lines. A "wide" item
59
- # is twice the width of a "narrow" item.
57
+ # *wn* - The native format for this barcode type. The string
58
+ # consists of a series of "w" and "n" characters. The first
59
+ # item is always a black line, with subsequent characters
60
+ # alternating between spaces and lines. A "wide" item
61
+ # is twice the width of a "narrow" item.
60
62
  #
61
63
  # The "width" method will tell you the total end-to-end width, in
62
64
  # units, of the entire barcode.
63
65
  #
64
- #== Miscellaneous Information
66
+ # == Miscellaneous Information
65
67
  #
66
68
  # Code 3 of 9 can encode text and digits. There is also a way to do
67
69
  # "full ascii" mode, but it's not recommended. Full ascii mode uses
@@ -72,14 +74,14 @@ module Barcode1DTools
72
74
  # only for shifting. However, if you need to use a full character
73
75
  # set, Code 128 is probably a better choice.
74
76
  #
75
- # Note:
77
+ # *Note:*
76
78
  # Please note that Code 3 of 9 is not suggested for new applications
77
79
  # due to the fact that the code is sparse and doesn't encode a full
78
80
  # range of characters without using the "full ascii extensions",
79
81
  # which cause it to be even more sparse. For newer 1D applications
80
82
  # use Code 128.
81
83
  #
82
- #== Rendering
84
+ # == Rendering
83
85
  #
84
86
  # Code 3 of 9 may be rendered however the programmer wishes. Since
85
87
  # there is a simple mapping between number of characters and length of
@@ -145,8 +147,13 @@ module Barcode1DTools
145
147
  '%' => { 'position' => 42, 'wn' => 'nnnwnwnwn' }
146
148
  }
147
149
 
150
+ # Guard pattern
148
151
  SIDE_GUARD_PATTERN = 'nwnnwnwnn'
149
152
 
153
+ # This table is useful for implementing "full ascii" mode.
154
+ # It is a 128 element array that will return the character
155
+ # or characters to represent the ascii character at a
156
+ # particular code point.
150
157
  FULL_ASCII_LOOKUP = [
151
158
  '%U', '$A', '$B', '$C', '$D', '$E', '$F', '$G', '$H', '$I',
152
159
  '$J', '$K', '$L', '$M', '$N', '$O', '$P', '$Q', '$R', '$S',
@@ -163,6 +170,9 @@ module Barcode1DTools
163
170
  '%S', '%T'
164
171
  ]
165
172
 
173
+ # This is a reverse lookup. Given a character or character pair
174
+ # from a "full ascii" representation this will give the ascii
175
+ # code point as well as a character name.
166
176
  FULL_ASCII_REVERSE_LOOKUP = {
167
177
  '%U' => { 'position' => 0, 'name' => '<NUL>' },
168
178
  '$A' => { 'position' => 1, 'name' => '<SOH>' },
@@ -297,6 +307,7 @@ module Barcode1DTools
297
307
  '%Z' => { 'position' => 127, 'name' => '<DEL>' }
298
308
  }
299
309
 
310
+ # Default w/n ratio.
300
311
  WN_RATIO = 2
301
312
 
302
313
  DEFAULT_OPTIONS = {
@@ -309,7 +320,9 @@ module Barcode1DTools
309
320
  }
310
321
 
311
322
  class << self
312
- # returns true or false
323
+ # Returns true if the given value can be encoded
324
+ # in the Code 3 of 9 symbology. See CHAR_SEQUENCE
325
+ # for a full list of characters and their positions.
313
326
  def can_encode?(value)
314
327
  value.to_s =~ /\A[0-9A-Z\-\. \$\/\+%]*\z/
315
328
  end
@@ -325,7 +338,7 @@ module Barcode1DTools
325
338
  CHAR_SEQUENCE[sum % 43,1]
326
339
  end
327
340
 
328
- # validates the check digit given a string - assumes check digit
341
+ # Validates the check digit given a string - assumes check digit
329
342
  # is last digit of string.
330
343
  def validate_check_digit_for(value)
331
344
  raise UnencodableCharactersError unless self.can_encode?(value)
@@ -398,6 +411,7 @@ module Barcode1DTools
398
411
  end
399
412
  end
400
413
 
414
+ # Create a new Code3of9 barcode object.
401
415
  # Options are :line_character, :space_character, :w_character,
402
416
  # :n_character, :skip_checksum, and :checksum_included.
403
417
  def initialize(value, options = {})
@@ -432,17 +446,17 @@ module Barcode1DTools
432
446
  @wn ||= wn_str.tr('wn', @options[:w_character].to_s + @options[:n_character].to_s)
433
447
  end
434
448
 
435
- # returns a run-length-encoded string representation
449
+ # Returns a run-length-encoded string representation
436
450
  def rle
437
451
  @rle ||= self.class.wn_to_rle(self.wn, @options)
438
452
  end
439
453
 
440
- # returns 1s and 0s (for "black" and "white")
454
+ # Returns 1s and 0s (for "black" and "white")
441
455
  def bars
442
456
  @bars ||= self.class.rle_to_bars(self.rle, @options)
443
457
  end
444
458
 
445
- # returns the total unit width of the bar code
459
+ # Returns the total unit width of the bar code
446
460
  def width
447
461
  @width ||= rle.split('').inject(0) { |a,c| a + c.to_i }
448
462
  end
@@ -21,40 +21,42 @@ module Barcode1DTools
21
21
  # dash "-", period ".", dollar sign "$", forward slash "/", plus
22
22
  # sign "+", percent sign "%", as well as a space " ".
23
23
  #
24
- # val = "THIS IS A TEST"
25
- # bc = Barcode1DTools::Code93.new(val)
26
- # pattern = bc.bars
27
- # rle_pattern = bc.rle
28
- # width = bc.width
29
- # # Note that the check digits are actually two of the characters.
30
- # check_digit = Barcode1DTools::Code93.generate_check_digit_for(num)
24
+ # == Example
25
+ # val = "THIS IS A TEST"
26
+ # bc = Barcode1DTools::Code93.new(val)
27
+ # pattern = bc.bars
28
+ # rle_pattern = bc.rle
29
+ # width = bc.width
30
+ # # Note that the check digits are actually two of the characters.
31
+ # check_digit = Barcode1DTools::Code93.generate_check_digit_for(num)
31
32
  #
32
33
  # The object created is immutable.
33
34
  #
34
35
  # Barcode1DTools::Code93 creates the patterns that you need to
35
- # display Code 93 barcodes. It can also decode a simple w/n
36
+ # display Code 93 barcodes. It can also decode a simple rle
36
37
  # string.
37
38
  #
38
39
  # Code 93 barcodes consist of lines and spaces that are from
39
40
  # one to four units wide each. A particular character has 3 bars
40
41
  # and 3 spaces.
41
42
  #
43
+ # == Formats
42
44
  # There are two formats for the returned pattern:
43
45
  #
44
- # bars - 1s and 0s specifying black lines and white spaces. Actual
45
- # characters can be changed from "1" and 0" with options
46
- # :line_character and :space_character.
46
+ # *bars* - 1s and 0s specifying black lines and white spaces. Actual
47
+ # characters can be changed from "1" and 0" with options
48
+ # :line_character and :space_character.
47
49
  #
48
- # rle - Run-length-encoded version of the pattern. The first
49
- # number is always a black line, with subsequent digits
50
- # alternating between spaces and lines. The digits specify
51
- # the width of each line or space.
50
+ # *rle* - Run-length-encoded version of the pattern. The first
51
+ # number is always a black line, with subsequent digits
52
+ # alternating between spaces and lines. The digits specify
53
+ # the width of each line or space.
52
54
  #
53
55
  # The "width" method will tell you the total end-to-end width, in
54
56
  # units, of the entire barcode. Note that the w/n format is
55
57
  # unavailable for this symbology.
56
58
  #
57
- #== Miscellaneous Information
59
+ # == Miscellaneous Information
58
60
  #
59
61
  # Code 93 can encode any ascii character from 0 to 127. The design
60
62
  # is identical to Code 3 of 9 in most respects, with the main
@@ -76,7 +78,7 @@ module Barcode1DTools
76
78
  # Internally, the four shift characters are represented as characters
77
79
  # 128 "($)", 129 "(%)", 130 "(/)", and 131 "(+)".
78
80
  #
79
- #== Rendering
81
+ # == Rendering
80
82
  #
81
83
  # Code 93 may be rendered however the programmer wishes. Since
82
84
  # there is a simple mapping between number of characters and length of
@@ -146,12 +148,17 @@ module Barcode1DTools
146
148
  "\x83" => {'position' => 46, 'display' => '(+)', 'rle' => '122211', 'bars' => '100110010'},
147
149
  }
148
150
 
149
- # Note that the right side has another thin line
151
+ # Left guard pattern
150
152
  LEFT_GUARD_PATTERN = '101011110'
153
+ # Left guard pattern as an RLE string
151
154
  LEFT_GUARD_PATTERN_RLE = '111141'
155
+ # Right guard pattern - just the left pattern with another bar
152
156
  RIGHT_GUARD_PATTERN = LEFT_GUARD_PATTERN + '1'
157
+ # Right guard pattern as RLE - just the left pattern with another bar
153
158
  RIGHT_GUARD_PATTERN_RLE = LEFT_GUARD_PATTERN_RLE + '1'
154
159
 
160
+ # This is a lookup table for the full ASCII mode. Index this with an ascii
161
+ # codepoint to get a one or two character representation of any character.
155
162
  FULL_ASCII_LOOKUP = [
156
163
  "\x81U", "\x80A", "\x80B", "\x80C", "\x80D", "\x80E", "\x80F", "\x80G", "\x80H", "\x80I",
157
164
  "\x80J", "\x80K", "\x80L", "\x80M", "\x80N", "\x80O", "\x80P", "\x80Q", "\x80R", "\x80S",
@@ -168,6 +175,8 @@ module Barcode1DTools
168
175
  "\x81S", "\x81T"
169
176
  ]
170
177
 
178
+ # This is the reverse lookup. Given a character or character pair you
179
+ # can find the ascii value.
171
180
  FULL_ASCII_REVERSE_LOOKUP = {
172
181
  "\x81U" => { 'position' => 0, 'name' => '<NUL>' },
173
182
  "\x80A" => { 'position' => 1, 'name' => '<SOH>' },
@@ -308,7 +317,10 @@ module Barcode1DTools
308
317
  :force_full_ascii => false
309
318
  }
310
319
 
320
+ # Set to true if the string is using the "full ascii" representation.
311
321
  attr_accessor :full_ascii
322
+ # If full_ascii is true, this is the encoded string including the
323
+ # shift characters. Otherwise, it is the same as "value".
312
324
  attr_accessor :full_ascii_value
313
325
 
314
326
  class << self
@@ -317,6 +329,8 @@ module Barcode1DTools
317
329
  value.to_s =~ /\A[\x00-\x7f]*\z/
318
330
  end
319
331
 
332
+ # Returns true if the given value has characters that
333
+ # fall outside the native range.
320
334
  def requires_full_ascii?(value)
321
335
  value.to_s !~ /\A[0-9A-Z\-\. \$\/\+%]*\z/
322
336
  end
@@ -336,7 +350,7 @@ module Barcode1DTools
336
350
  "#{check_c}#{check_k}"
337
351
  end
338
352
 
339
- # validates the check digit given a string - assumes check digit
353
+ # Validates the check digit given a string - assumes check digit
340
354
  # is last digit of string.
341
355
  def validate_check_digit_for(value)
342
356
  md = value.to_s.match(/^(.*)(..)$/)
@@ -400,7 +414,7 @@ module Barcode1DTools
400
414
  str.bytes.collect { |c| FULL_ASCII_LOOKUP[c] }.join
401
415
  end
402
416
 
403
- # Decodes a "full ascii" string from Code 3 of 9 into standard
417
+ # Decodes a "full ascii" string from Code 93 into standard
404
418
  # ascii. Note that this will silently fail if a string is
405
419
  # malformed.
406
420
  def decode_full_ascii(str)
@@ -412,6 +426,7 @@ module Barcode1DTools
412
426
  end
413
427
  end
414
428
 
429
+ # Create a new Code93 barcode object.
415
430
  # Options are :line_character, :space_character, :force_full_ascii,
416
431
  # and :checksum_included.
417
432
  def initialize(value, options = {})
@@ -444,30 +459,30 @@ module Barcode1DTools
444
459
  end
445
460
  end
446
461
 
447
- # Returns a string of "w" or "n" ("wide" and "narrow")
462
+ # Returns a string of "w" or "n" ("wide" and "narrow"). For Code93 this
463
+ # simply raises a NotImplementedError.
448
464
  def wn
449
465
  raise NotImplementedError
450
466
  end
451
467
 
452
- # returns a run-length-encoded string representation
468
+ # Returns a run-length-encoded string representation
453
469
  def rle
454
470
  @rle ||= gen_rle(@encoded_string)
455
471
  end
456
472
 
457
- # returns 1s and 0s (for "black" and "white")
473
+ # Returns 1s and 0s (for "black" and "white")
458
474
  def bars
459
475
  @bars ||= self.class.rle_to_bars(self.rle, @options)
460
476
  end
461
477
 
462
- # returns the total unit width of the bar code
478
+ # Returns the total unit width of the bar code
463
479
  def width
464
480
  @width ||= rle.split('').inject(0) { |a,c| a + c.to_i }
465
481
  end
466
482
 
467
483
  private
468
484
 
469
- # Creates the actual w/n pattern. Note that there is a narrow space
470
- # between each character.
485
+ # Creates the actual rle pattern.
471
486
  def gen_rle(str)
472
487
  @rle_str ||=
473
488
  ([LEFT_GUARD_PATTERN_RLE] +