File: code_25.rb

package info (click to toggle)
ruby-barby 0.5.1-3
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 360 kB
  • ctags: 511
  • sloc: ruby: 2,169; java: 1,228; makefile: 7
file content (193 lines) | stat: -rw-r--r-- 3,809 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
require 'barby/barcode'

module Barby


  #Standard/Industrial 2 of 5, non-interleaved
  #
  #Checksum not included by default, to include it,
  #set include_checksum = true
  class Code25 < Barcode1D

    WIDE   = W = true
    NARROW = N = false

    START_ENCODING = [W,W,N]
    STOP_ENCODING  = [W,N,W]

    ENCODINGS = {
      0 => [N,N,W,W,N],
      1 => [W,N,N,N,W],
      2 => [N,W,N,N,W],
      3 => [W,W,N,N,N],
      4 => [N,N,W,N,W],
      5 => [W,N,W,N,N],
      6 => [N,W,W,N,N],
      7 => [N,N,N,W,W],
      8 => [W,N,N,W,N],
      9 => [N,W,N,W,N]
    }

    attr_accessor :data, :narrow_width, :wide_width, :space_width, :include_checksum

  
    def initialize(data)
      self.data = data
    end


    def data_encoding
      digit_encodings.join
    end

    def data_encoding_with_checksum
      digit_encodings_with_checksum.join
    end

    def encoding
      start_encoding+(include_checksum? ? data_encoding_with_checksum : data_encoding)+stop_encoding
    end


    def characters
      data.split(//)
    end

    def characters_with_checksum
      characters.push(checksum.to_s)
    end

    def digits
      characters.map{|c| c.to_i }
    end

    def digits_with_checksum
      digits.push(checksum)
    end

    def even_and_odd_digits
      alternater = false
      digits.reverse.partition{ alternater = !alternater }
    end


    def digit_encodings
      raise_invalid unless valid?
      digits.map{|d| encoding_for(d) }
    end
    alias character_encodings digit_encodings

    def digit_encodings_with_checksum
      raise_invalid unless valid?
      digits_with_checksum.map{|d| encoding_for(d) }
    end
    alias character_encodings_with_checksum digit_encodings_with_checksum


    #Returns the encoding for a single digit
    def encoding_for(digit)
      encoding_for_bars(ENCODINGS[digit])
    end

    #Generate encoding for an array of W,N
    def encoding_for_bars(*bars)
      wide, narrow, space = wide_encoding, narrow_encoding, space_encoding
      bars.flatten.inject '' do |enc,bar|
        enc + (bar == WIDE ? wide : narrow) + space
      end
    end

    def encoding_for_bars_without_end_space(*a)
      encoding_for_bars(*a).gsub(/0+$/, '')
    end


    #Mod10
    def checksum
      evens, odds = even_and_odd_digits
      sum = odds.inject(0){|sum,d| sum + d } + evens.inject(0){|sum,d| sum + (d*3) }
      sum %= 10
      sum.zero? ? 0 : 10-sum
    end

    def checksum_encoding
      encoding_for(checksum)
    end


    #The width of a narrow bar in xdims
    def narrow_width
      @narrow_width || 1
    end

    #The width of a wide bar in xdims
    #By default three times as wide as a narrow bar
    def wide_width
      @wide_width || narrow_width*3
    end

    #The width of the space between the bars in xdims
    #By default the same width as a narrow bar
    #
    #A space serves only as a separator for the bars,
    #there is no encoded meaning in them
    def space_width
      @space_width || narrow_width
    end


    #2 of 5 doesn't require a checksum, but you can include a Mod10 checksum
    #by setting +include_checksum+ to true
    def include_checksum?
      include_checksum
    end


    def data=(data)
      @data = "#{data}"
    end


    def start_encoding
      encoding_for_bars(START_ENCODING)
    end

    def stop_encoding
      encoding_for_bars_without_end_space(STOP_ENCODING)
    end


    def narrow_encoding
      '1' * narrow_width
    end

    def wide_encoding
      '1' * wide_width
    end

    def space_encoding
      '0' * space_width
    end


    def valid?
      data =~ /^[0-9]*$/
    end


    def to_s
      (include_checksum? ? characters_with_checksum : characters).join
    end


  private

    def raise_invalid
      raise ArgumentError, "data not valid"
    end


  end


end