barby 0.6.2 → 0.6.8

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 (52) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +2 -0
  3. data/CHANGELOG +8 -0
  4. data/Gemfile +5 -0
  5. data/README.md +108 -0
  6. data/Rakefile +15 -0
  7. data/barby.gemspec +31 -0
  8. data/lib/barby/barcode.rb +3 -3
  9. data/lib/barby/barcode/bookland.rb +0 -1
  10. data/lib/barby/barcode/codabar.rb +82 -0
  11. data/lib/barby/barcode/code_128.rb +22 -20
  12. data/lib/barby/barcode/code_25.rb +6 -3
  13. data/lib/barby/barcode/code_25_interleaved.rb +2 -2
  14. data/lib/barby/barcode/code_39.rb +2 -1
  15. data/lib/barby/barcode/data_matrix.rb +1 -1
  16. data/lib/barby/barcode/ean_13.rb +1 -1
  17. data/lib/barby/barcode/gs1_128.rb +5 -1
  18. data/lib/barby/barcode/qr_code.rb +2 -1
  19. data/lib/barby/outputter.rb +1 -1
  20. data/lib/barby/outputter/cairo_outputter.rb +16 -3
  21. data/lib/barby/outputter/png_outputter.rb +43 -7
  22. data/lib/barby/outputter/prawn_outputter.rb +12 -4
  23. data/lib/barby/outputter/rmagick_outputter.rb +43 -11
  24. data/lib/barby/outputter/svg_outputter.rb +11 -13
  25. data/lib/barby/version.rb +2 -2
  26. data/test/barcodes.rb +20 -0
  27. data/test/bookland_test.rb +54 -0
  28. data/test/codabar_test.rb +58 -0
  29. data/test/code_128_test.rb +470 -0
  30. data/test/code_25_iata_test.rb +19 -0
  31. data/test/code_25_interleaved_test.rb +116 -0
  32. data/test/code_25_test.rb +110 -0
  33. data/test/code_39_test.rb +210 -0
  34. data/test/code_93_test.rb +144 -0
  35. data/test/data_matrix_test.rb +30 -0
  36. data/test/ean13_test.rb +169 -0
  37. data/test/ean8_test.rb +100 -0
  38. data/test/outputter/cairo_outputter_test.rb +129 -0
  39. data/test/outputter/html_outputter_test.rb +68 -0
  40. data/test/outputter/pdfwriter_outputter_test.rb +37 -0
  41. data/test/outputter/png_outputter_test.rb +49 -0
  42. data/test/outputter/prawn_outputter_test.rb +79 -0
  43. data/test/outputter/rmagick_outputter_test.rb +83 -0
  44. data/test/outputter/svg_outputter_test.rb +89 -0
  45. data/test/outputter_test.rb +134 -0
  46. data/test/pdf_417_test.rb +45 -0
  47. data/test/qr_code_test.rb +78 -0
  48. data/test/test_helper.rb +24 -0
  49. data/test/upc_supplemental_test.rb +109 -0
  50. metadata +160 -19
  51. data/README +0 -93
  52. data/lib/barby/outputter/point_matrix.rb +0 -211
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 25c48f523056303c71f3477a056906f12613bde3
4
- data.tar.gz: 1860f349c37684539345aef410f09a570a50f319
2
+ SHA256:
3
+ metadata.gz: 64d74091ea1f3aa79457c34878fc3b0d6f4c805dbb985d12eb372f29a7837e36
4
+ data.tar.gz: a8a61c1af0a401a1b36bc675653d2063e569443d434a57b5a2d95c7abfc1d193
5
5
  SHA512:
6
- metadata.gz: a793a5c6a5a5fba522ec2300ec703a3340edd5c45d249b9ca5d2056c2460555e6f4944c0cc4d9ccb8863f6a068a1aa2083f5f5181820d0c70b7a79d2c9cf2799
7
- data.tar.gz: f7acba5a08dea02a79c1620a2b4743e1b77a1f53469d83bf4d58229c5f5e618dc3f89959d2e858b8dbf80c0fef7ef33cfe211f5bdf28d750d9e578178d4bda6d
6
+ metadata.gz: 99143c0bf41695fa1416956073bcb6c9d7257c677fa36337638f890681665bacd51c4b04cd3412008592c8f23e4130fec74363eb425c776f8c827bf360d07c5b
7
+ data.tar.gz: d1b1f6aa2a63484b00f79bd184bef605b75850152dd54600b7eb25434f114c45c6994ce725af7535edefb8a536fc93f3e42c7d4bd2547c6f88d8da90d0947f8f
@@ -0,0 +1,2 @@
1
+ *.swp
2
+ Gemfile.lock
data/CHANGELOG CHANGED
@@ -1,3 +1,11 @@
1
+ * 0.6.7
2
+
3
+ * RMagick outputter should use line command for lines [joshuaflanagan]
4
+
5
+ * 0.6.6
6
+
7
+ * Add support for Codabar symbology [labocho]
8
+
1
9
  * 0.6.1
2
10
 
3
11
  * Fix single-pixel error with RMagick [James Brink]
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ gemspec
@@ -0,0 +1,108 @@
1
+ # Barby
2
+ Barby is a Ruby library that generates barcodes in a variety of symbologies.
3
+
4
+ Its functionality is split into _barcode_ and "_outputter_" objects:
5
+ * [`Barby::Barcode` objects] [symbologies] turn data into a binary representation for a given symbology.
6
+ * [`Barby::Outputter`] [outputters] then takes this representation and turns it into images, PDF, etc.
7
+
8
+ You can easily add a symbology without having to worry about graphical
9
+ representation. If it can be represented as the usual 1D or 2D matrix of
10
+ lines or squares, outputters will do that for you.
11
+
12
+ Likewise, you can easily add an outputter for a format that doesn't have one
13
+ yet, and it will work with all existing symbologies.
14
+
15
+ For more information, check out [the Barby wiki][wiki].
16
+
17
+
18
+ ### New require policy
19
+
20
+ Barcode symbologies are no longer required automatically, so you'll have to
21
+ require the ones you need.
22
+
23
+ If you need EAN-13, `require 'barby/barcode/ean_13'`. Full list of symbologies and filenames below.
24
+
25
+ ## Example
26
+
27
+ ```ruby
28
+ require 'barby'
29
+ require 'barby/barcode/code_128'
30
+ require 'barby/outputter/ascii_outputter'
31
+
32
+ barcode = Barby::Code128B.new('BARBY')
33
+
34
+ puts barcode.to_ascii #Implicitly uses the AsciiOutputter
35
+
36
+ ## # # # # ## # # ## ## # ### # # ## ### ## # ## ### ### ## ### # ##
37
+ ## # # # # ## # # ## ## # ### # # ## ### ## # ## ### ### ## ### # ##
38
+ ## # # # # ## # # ## ## # ### # # ## ### ## # ## ### ### ## ### # ##
39
+ ## # # # # ## # # ## ## # ### # # ## ### ## # ## ### ### ## ### # ##
40
+ ## # # # # ## # # ## ## # ### # # ## ### ## # ## ### ### ## ### # ##
41
+ ## # # # # ## # # ## ## # ### # # ## ### ## # ## ### ### ## ### # ##
42
+ ## # # # # ## # # ## ## # ### # # ## ### ## # ## ### ### ## ### # ##
43
+ ## # # # # ## # # ## ## # ### # # ## ### ## # ## ### ### ## ### # ##
44
+ ## # # # # ## # # ## ## # ### # # ## ### ## # ## ### ### ## ### # ##
45
+ ## # # # # ## # # ## ## # ### # # ## ### ## # ## ### ### ## ### # ##
46
+ B A R B Y
47
+ ```
48
+
49
+ ## Supported symbologies
50
+
51
+ ```ruby
52
+ require 'barby/barcode/<filename>'
53
+ ```
54
+
55
+ | Name | Filename | Dependencies |
56
+ | ----------------------------------- | --------------------- | ---------------------------------- |
57
+ | Code 25 | `code_25` | ─ |
58
+ | ├─ Interleaved | `code_25_interleaved` | ─ |
59
+ | └─ IATA | `code_25_iata` | ─ |
60
+ | Code 39 | `code_39` | ─ |
61
+ | └─ Extended | `code_39` | ─ |
62
+ | Code 93 | `code_93` | ─ |
63
+ | Code 128 (A, B, and C) | `code_128` | ─ |
64
+ | └─ GS1 128 | `gs1_128` | ─ |
65
+ | EAN-13 | `ean_13` | ─ |
66
+ | ├─ Bookland | `bookland` | ─ |
67
+ | └─ UPC-A | `ean_13` | ─ |
68
+ | EAN-8 | `ean_8` | ─ |
69
+ | UPC/EAN supplemental, 2 & 5 digits | `upc_supplemental` | ─ |
70
+ | QR Code | `qr_code` | `rqrcode` |
71
+ | DataMatrix (Semacode) | `data_matrix` | `semacode` or `semacode-ruby19` |
72
+ | PDF417 | `pdf_417` | JRuby |
73
+
74
+
75
+ ## Outputters
76
+
77
+ ```ruby
78
+ require 'barby/outputter/<filename>_outputter'
79
+ ```
80
+
81
+ | filename | dependencies |
82
+ | ----------- | ------------- |
83
+ | `ascii` | ─ |
84
+ | `cairo` | cairo |
85
+ | `html` | ─ |
86
+ | `pdfwriter` | ─ |
87
+ | `png` | chunky_png |
88
+ | `prawn` | prawn |
89
+ | `rmagick` | rmagick |
90
+ | `svg` | ─ |
91
+
92
+ ### Formats supported by outputters
93
+
94
+ * Text (mostly for testing)
95
+ * PNG, JPEG, GIF
96
+ * PS, EPS
97
+ * SVG
98
+ * PDF
99
+ * HTML
100
+
101
+ ---
102
+
103
+ For more information, check out [the Barby wiki][wiki].
104
+
105
+
106
+ [wiki]: https://github.com/toretore/barby/wiki
107
+ [symbologies]: https://github.com/toretore/barby/wiki/Symbologies
108
+ [outputters]: https://github.com/toretore/barby/wiki/Outputters
@@ -0,0 +1,15 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rdoc/task'
4
+
5
+ Rake::TestTask.new do |t|
6
+ t.libs = ['lib','test']
7
+ t.test_files = Dir.glob("test/**/*_test.rb").sort
8
+ t.verbose = true
9
+ end
10
+
11
+ RDoc::Task.new do |rdoc|
12
+ rdoc.main = "README"
13
+ rdoc.rdoc_files.include("README", "lib")
14
+ rdoc.rdoc_dir = 'doc'
15
+ end
@@ -0,0 +1,31 @@
1
+ $:.push File.expand_path("../lib", __FILE__)
2
+ require "barby/version"
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "barby"
6
+ s.version = Barby::VERSION::STRING
7
+ s.platform = Gem::Platform::RUBY
8
+ s.summary = "The Ruby barcode generator"
9
+ s.email = "toredarell@gmail.com"
10
+ s.homepage = "http://toretore.github.com/barby"
11
+ s.description = "Barby creates barcodes."
12
+ s.authors = ['Tore Darell']
13
+
14
+ s.rubyforge_project = "barby"
15
+
16
+ s.extra_rdoc_files = ["README.md"]
17
+
18
+ s.files = `git ls-files`.split("\n")
19
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
20
+ s.test_files.delete("test/outputter/rmagick_outputter_test.rb")
21
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
22
+ s.require_paths = ["lib"]
23
+
24
+ s.add_development_dependency "minitest", "~> 5.11"
25
+ s.add_development_dependency "bundler", "~> 1.16"
26
+ s.add_development_dependency "rake", "~> 10.0"
27
+ s.add_development_dependency "semacode-ruby19", "~> 0.7"
28
+ s.add_development_dependency "rqrcode", "~> 0.10"
29
+ s.add_development_dependency "prawn", "~> 2.2"
30
+ s.add_development_dependency "cairo", "~> 1.15"
31
+ end
@@ -17,7 +17,7 @@ module Barby
17
17
  # '101100111000111100001'
18
18
  # end
19
19
  # end
20
- #
20
+ #
21
21
  # require 'barby/outputter/ascii_outputter'
22
22
  # puts StaticBarcode.new.to_ascii(:height => 3)
23
23
  #
@@ -33,8 +33,8 @@ module Barby
33
33
  # end
34
34
  # end
35
35
  class Barcode
36
-
37
-
36
+
37
+
38
38
  #Every barcode must have an encoding method. This method returns
39
39
  #a string containing a series of 1 and 0, representing bars and
40
40
  #spaces. One digit is the width of one "module" or X dimension.
@@ -132,7 +132,6 @@ module Barby
132
132
  end
133
133
 
134
134
  def inspect
135
- klass = (self.class.ancestors + [self.class.name]).join(':')
136
135
  "#<#{self.class}:0x#{'%014x' % object_id} #{formatted_isbn}>"
137
136
  end
138
137
 
@@ -0,0 +1,82 @@
1
+ require "barby/barcode"
2
+
3
+ module Barby
4
+ # https://en.wikipedia.org/wiki/Codabar
5
+ class Codabar < Barcode1D
6
+ BLACK_NARROW_WIDTH = 1
7
+ WHITE_NARROW_WIDTH = 2
8
+ WIDE_WIDTH_RATE = 3
9
+ SPACING = 5 # must be equal to or wider than white narrow width
10
+ CHARACTERS = "0123456789-$:/.+ABCD".freeze
11
+ # even: black, odd: white
12
+ # 0: narrow, 1: wide
13
+ BINARY_EXPRESSION = [
14
+ "0000011", # 0
15
+ "0000110", # 1
16
+ "0001001", # 2
17
+ "1100000", # 3
18
+ "0010010", # 4
19
+ "1000010", # 5
20
+ "0100001", # 6
21
+ "0100100", # 7
22
+ "0110000", # 8
23
+ "1001000", # 9
24
+ "0001100", # -
25
+ "0011000", # $
26
+ "1000101", # :
27
+ "1010001", # /
28
+ "1010100", # .
29
+ "0010101", # +
30
+ "0011010", # A
31
+ "0101001", # B
32
+ "0001011", # C
33
+ "0001110", # D
34
+ ].each(&:freeze)
35
+ CHARACTER_TO_BINARY = Hash[CHARACTERS.chars.zip(BINARY_EXPRESSION)].freeze
36
+ FORMAT = /\A[ABCD][0123456789\-\$:\/\.\+]+[ABCD]\z/.freeze
37
+ ONE = "1".freeze
38
+ ZERO = "0".freeze
39
+
40
+ attr_accessor :data, :black_narrow_width, :white_narrow_width, :wide_width_rate, :spacing
41
+
42
+ def initialize(data)
43
+ self.data = data
44
+ raise ArgumentError, 'data not valid' unless valid?
45
+
46
+ self.black_narrow_width = BLACK_NARROW_WIDTH
47
+ self.white_narrow_width = WHITE_NARROW_WIDTH
48
+ self.wide_width_rate = WIDE_WIDTH_RATE
49
+ self.spacing = SPACING
50
+ end
51
+
52
+ def encoding
53
+ data.chars.map{|c| binary_to_bars(CHARACTER_TO_BINARY[c]) }.join(ZERO * spacing)
54
+ end
55
+
56
+ def valid?
57
+ data =~ FORMAT
58
+ end
59
+
60
+ private
61
+ def binary_to_bars(bin)
62
+ bin.chars.each_with_index.map{|c, i|
63
+ black = i % 2 == 0
64
+ narrow = c == ZERO
65
+
66
+ if black
67
+ if narrow
68
+ ONE * black_narrow_width
69
+ else
70
+ ONE * (black_narrow_width * wide_width_rate).to_i
71
+ end
72
+ else
73
+ if narrow
74
+ ZERO * white_narrow_width
75
+ else
76
+ ZERO * (white_narrow_width * wide_width_rate).to_i
77
+ end
78
+ end
79
+ }.join
80
+ end
81
+ end
82
+ end
@@ -18,6 +18,14 @@ module Barby
18
18
  #As an example, here's one that starts out as type A and then switches to B and then C:
19
19
  #
20
20
  # Code128A.new("ABC123\306def\3074567")
21
+ #
22
+ #
23
+ #GS1-128/EAN-128/UCC-128
24
+ #
25
+ #To make a GS1-128 code, prefix the data with FNC1 and the Application Identifier:
26
+ #
27
+ # #AI=00, data=12345
28
+ # Code128.new("#{Code128::FNC1}0012345")
21
29
  class Code128 < Barcode1D
22
30
 
23
31
  FNC1 = "\xc1"
@@ -175,7 +183,7 @@ module Barby
175
183
 
176
184
 
177
185
  def type=(type)
178
- type.upcase!
186
+ type = type.upcase
179
187
  raise ArgumentError, 'type must be A, B or C' unless type =~ /^[ABC]$/
180
188
  @type = type
181
189
  end
@@ -230,7 +238,8 @@ module Barby
230
238
  #there are no more extras, the barcode ends with that object.
231
239
  #Most barcodes probably don't change charsets and don't have extras.
232
240
  def extra
233
- @extra
241
+ return @extra if defined?(@extra)
242
+ @extra = nil
234
243
  end
235
244
 
236
245
  #Set the extra for this barcode. The argument is a string starting with the
@@ -396,6 +405,9 @@ module Barby
396
405
  LOWR_RE = /[a-z]/
397
406
  DGTS_RE = /\d{4,}/
398
407
 
408
+ # pairs of digits and FNC1 characters
409
+ CODEC_CHARS_RE = /(?:\d{2}|#{FNC1}){2,}/
410
+
399
411
  class << self
400
412
 
401
413
 
@@ -415,7 +427,7 @@ module Barby
415
427
  #shortest encoding possible
416
428
  def apply_shortest_encoding_for_data(data)
417
429
  extract_codec(data).map do |block|
418
- if possible_codec_segment?(block)
430
+ if codec_segment?(block)
419
431
  "#{CODEC}#{block}"
420
432
  else
421
433
  if control_before_lowercase?(block)
@@ -445,25 +457,15 @@ module Barby
445
457
  # # C A or B C A or B
446
458
  # extract_codec("12345abc678910DEF11") => ["1234", "5abc", "678910", "DEF11"]
447
459
  def extract_codec(data)
448
- segments = data.split(/(\d{4,})/).reject(&:empty?)
449
- segments.each_with_index do |s,i|
450
- if possible_codec_segment?(s) && s.size.odd?
451
- if i == 0
452
- if segments[1]
453
- segments[1].insert(0, s.slice!(-1))
454
- else
455
- segments[1] = s.slice!(-1)
456
- end
457
- else
458
- segments[i-1].insert(-1, s.slice!(0)) if segments[i-1]
459
- end
460
- end
461
- end
462
- segments
460
+ data.split(/
461
+ (^(?:#{CODEC_CHARS_RE})) # matches digits that appear at the beginning of the barcode
462
+ |
463
+ ((?:#{CODEC_CHARS_RE})(?!\d)) # matches digits that appear later in the barcode
464
+ /x).reject(&:empty?)
463
465
  end
464
466
 
465
- def possible_codec_segment?(data)
466
- data =~ /\A\d{4,}\Z/
467
+ def codec_segment?(data)
468
+ data =~ /\A#{CODEC_CHARS_RE}\Z/
467
469
  end
468
470
 
469
471
  def control_character?(char)
@@ -28,11 +28,14 @@ module Barby
28
28
  9 => [N,W,N,W,N]
29
29
  }
30
30
 
31
- attr_accessor :data, :narrow_width, :wide_width, :space_width, :include_checksum
31
+ attr_accessor :include_checksum
32
+ attr_writer :narrow_width, :wide_width, :space_width
33
+ attr_reader :data
34
+
32
35
 
33
-
34
36
  def initialize(data)
35
37
  self.data = data
38
+ @narrow_width, @wide_width, @space_width = nil
36
39
  end
37
40
 
38
41
 
@@ -105,7 +108,7 @@ module Barby
105
108
  #Mod10
106
109
  def checksum
107
110
  evens, odds = even_and_odd_digits
108
- sum = odds.inject(0){|sum,d| sum + d } + evens.inject(0){|sum,d| sum + (d*3) }
111
+ sum = odds.inject(0){|s,d| s + d } + evens.inject(0){|s,d| s + (d*3) }
109
112
  sum %= 10
110
113
  sum.zero? ? 0 : 10-sum
111
114
  end
@@ -14,9 +14,9 @@ module Barby
14
14
 
15
15
 
16
16
  def digit_pairs(d=nil)
17
- (d || digits).inject [] do |ary,d|
17
+ (d || digits).inject [] do |ary,i|
18
18
  ary << [] if !ary.last || ary.last.size == 2
19
- ary.last << d
19
+ ary.last << i
20
20
  ary
21
21
  end
22
22
  end
@@ -87,7 +87,8 @@ module Barby
87
87
  START_ENCODING = [N,W,N,N,W,N,W,N,N] # *
88
88
  STOP_ENCODING = [N,W,N,N,W,N,W,N,N] # *
89
89
 
90
- attr_accessor :data, :spacing, :narrow_width, :wide_width, :extended, :include_checksum
90
+ attr_accessor :data, :extended, :include_checksum
91
+ attr_writer :spacing, :narrow_width, :wide_width
91
92
 
92
93
  # Do not surround "data" with the mandatory "*" as is this is done automically for you.
93
94
  # So instead of passing "*123456*" as "data", just pass "123456".
@@ -7,7 +7,7 @@ module Barby
7
7
  #Uses the semacode library (gem install semacode) to encode DataMatrix barcodes
8
8
  class DataMatrix < Barcode2D
9
9
 
10
- attr_accessor :data
10
+ attr_reader :data
11
11
 
12
12
 
13
13
  def initialize(data)