zebra-zpl 1.0.5 → 1.1.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.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +62 -0
  3. data/CONTRIBUTING.md +49 -0
  4. data/Gemfile +6 -0
  5. data/README.md +259 -76
  6. data/docs/example.rb +249 -0
  7. data/docs/images/barcode.png +0 -0
  8. data/docs/images/datamatrix.png +0 -0
  9. data/docs/images/earth.jpg +0 -0
  10. data/docs/images/graphics.png +0 -0
  11. data/docs/images/image.png +0 -0
  12. data/docs/images/image_inverted.png +0 -0
  13. data/docs/images/images.png +0 -0
  14. data/docs/images/justification.png +0 -0
  15. data/docs/images/qrcode.png +0 -0
  16. data/docs/images/rotation.png +0 -0
  17. data/docs/images/text.png +0 -0
  18. data/lib/zebra/print_job.rb +7 -13
  19. data/lib/zebra/zpl.rb +20 -13
  20. data/lib/zebra/zpl/barcode.rb +29 -12
  21. data/lib/zebra/zpl/barcode_type.rb +4 -1
  22. data/lib/zebra/zpl/box.rb +16 -4
  23. data/lib/zebra/zpl/comment.rb +15 -0
  24. data/lib/zebra/zpl/datamatrix.rb +76 -0
  25. data/lib/zebra/zpl/graphic.rb +91 -0
  26. data/lib/zebra/zpl/image.rb +91 -0
  27. data/lib/zebra/zpl/label.rb +2 -13
  28. data/lib/zebra/zpl/pdf417.rb +50 -0
  29. data/lib/zebra/zpl/qrcode.rb +2 -2
  30. data/lib/zebra/zpl/text.rb +44 -20
  31. data/lib/zebra/zpl/version.rb +1 -1
  32. data/spec/fixtures/default.jpg +0 -0
  33. data/spec/spec_helper.rb +6 -2
  34. data/spec/zebra/print_job_spec.rb +13 -18
  35. data/spec/zebra/zpl/barcode_spec.rb +70 -63
  36. data/spec/zebra/zpl/box_spec.rb +27 -31
  37. data/spec/zebra/zpl/character_set_spec.rb +7 -7
  38. data/spec/zebra/zpl/comment_spec.rb +18 -0
  39. data/spec/zebra/zpl/datamatrix_spec.rb +124 -0
  40. data/spec/zebra/zpl/graphics_spec.rb +227 -0
  41. data/spec/zebra/zpl/image_spec.rb +113 -0
  42. data/spec/zebra/zpl/label_spec.rb +40 -52
  43. data/spec/zebra/zpl/pdf417_spec.rb +108 -0
  44. data/spec/zebra/zpl/qrcode_spec.rb +92 -92
  45. data/spec/zebra/zpl/text_spec.rb +57 -55
  46. data/zebra-zpl.gemspec +14 -15
  47. metadata +71 -22
data/lib/zebra/zpl/box.rb CHANGED
@@ -5,9 +5,11 @@ module Zebra
5
5
  class Box
6
6
  include Printable
7
7
 
8
- class InvalidLineThickness < StandardError; end
8
+ class InvalidLineThickness < StandardError; end
9
+ class InvalidRoundingDegree < StandardError; end
10
+ class InvalidColorError < StandardError; end
9
11
 
10
- attr_reader :line_thickness, :box_width, :box_height, :width
12
+ attr_reader :line_thickness, :box_width, :box_height, :width, :color, :rounding_degree
11
13
 
12
14
  def line_thickness=(thickness)
13
15
  raise InvalidLineThickness unless thickness.nil? || thickness.to_i.to_s == thickness.to_s
@@ -27,10 +29,20 @@ module Zebra
27
29
  @box_height = height
28
30
  end
29
31
 
32
+ def rounding_degree=(value)
33
+ raise InvalidLineThickness unless (1..8).include?(value.to_i)
34
+ @rounding_degree = value
35
+ end
36
+
37
+ def color=(value)
38
+ raise InvalidColorError unless %w[B W].include?(value&.upcase)
39
+ @color = value
40
+ end
41
+
30
42
  def to_zpl
31
43
  check_attributes
32
- # "^FO#{x},#{y}^GB#{box_width},#{box_height},#{line_thickness}^FS"
33
- "^FO#{x},#{y}^GB#{box_width},#{box_height},#{line_thickness}^FS"
44
+ puts "The Box class is deprecated. Please switch to the Graphic class (graphic_type = box)." unless ENV['RUBY_ENV'] == 'test'
45
+ "^FO#{x},#{y}^GB#{box_width},#{box_height},#{line_thickness},#{color},#{rounding_degree}^FS"
34
46
  end
35
47
 
36
48
  private
@@ -0,0 +1,15 @@
1
+ module Zebra
2
+ module Zpl
3
+ class Comment
4
+ attr_accessor :data
5
+
6
+ def initialize(options = {})
7
+ options.each_pair { |attribute, value| self.__send__ "#{attribute}=", value }
8
+ end
9
+
10
+ def to_zpl
11
+ "^FX#{data}^FS"
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,76 @@
1
+ require "zebra/zpl/printable"
2
+
3
+ module Zebra
4
+ module Zpl
5
+ class Datamatrix
6
+ include Printable
7
+
8
+ class InvalidOrientationError < StandardError; end
9
+ class InvalidQualityFactorError < StandardError; end
10
+ class InvalidSizeError < StandardError; end
11
+ class InvalidFormatError < StandardError; end
12
+ class InvalidRatioError < StandardError; end
13
+
14
+ attr_reader :symbol_height, :columns, :rows, :format, :aspect_ratio, :width
15
+ attr_accessor :escape_sequence
16
+
17
+ def width=(width)
18
+ @width = width || 0
19
+ end
20
+
21
+ def orientation=(value)
22
+ raise InvalidOrientationError unless %w[N R I B].include?(value)
23
+ @orientation = value
24
+ end
25
+
26
+ def orientation
27
+ @orientation || 'N'
28
+ end
29
+
30
+ def symbol_height=(height)
31
+ @symbol_height = height
32
+ end
33
+
34
+ def quality=(level)
35
+ raise InvalidQualityFactorError unless [0, 50, 80, 100, 140, 200].include?(level.to_i)
36
+ @quality = level
37
+ end
38
+
39
+ def quality
40
+ @quality || 200
41
+ end
42
+
43
+ def columns=(n)
44
+ raise InvalidSizeError unless (9..49).include?(n.to_i)
45
+ @columns = n
46
+ end
47
+
48
+ def rows=(n)
49
+ raise InvalidSizeError unless (9..49).include?(n.to_i)
50
+ @rows = n
51
+ end
52
+
53
+ def format=(value)
54
+ raise InvalidFormatError unless (0..6).include?(value.to_i)
55
+ @format = value
56
+ end
57
+
58
+ def aspect_ratio=(value)
59
+ raise InvalidRatioError unless [1, 2].include?(value.to_i)
60
+ @aspect_ratio = value
61
+ end
62
+
63
+ def to_zpl
64
+ check_attributes
65
+ "^FW#{rotation}^FO#{x},#{y}^BY,,10^BX#{orientation},#{symbol_height},#{quality},#{columns},#{rows},#{format},#{escape_sequence},#{aspect_ratio}^FD#{data}^FS"
66
+ end
67
+
68
+ private
69
+
70
+ def check_attributes
71
+ super
72
+ raise MissingAttributeError.new("the symbol height to be used is not given") unless @symbol_height
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,91 @@
1
+ require "zebra/zpl/printable"
2
+
3
+ module Zebra
4
+ module Zpl
5
+ class Graphic
6
+ include Printable
7
+
8
+ class InvalidGraphicType < StandardError; end
9
+ class InvalidLineThickness < StandardError; end
10
+ class InvalidColorError < StandardError; end
11
+ class InvalidOrientationError < StandardError; end
12
+ class InvalidRoundingDegree < StandardError; end
13
+ class InvalidSymbolType < StandardError; end
14
+
15
+ attr_reader :graphic_type, :graphic_width, :graphic_height, :line_thickness, :color, :orientation, :rounding_degree, :symbol_type
16
+
17
+ BOX = "B"
18
+ CIRCLE = "C"
19
+ DIAGONAL = "D"
20
+ ELLIPSE = "E"
21
+ SYMBOL = "S"
22
+
23
+ def graphic_type=(type)
24
+ raise InvalidGraphicType unless %w(E B D C S).include? type
25
+ @graphic_type = type
26
+ end
27
+
28
+ def graphic_width=(width)
29
+ @graphic_width = width
30
+ end
31
+
32
+ def graphic_height=(height)
33
+ @graphic_height = height
34
+ end
35
+
36
+ def line_thickness=(thickness)
37
+ raise InvalidLineThickness unless thickness.nil? || thickness.to_i.to_s == thickness.to_s
38
+ @line_thickness = thickness
39
+ end
40
+
41
+ def color=(value)
42
+ raise InvalidColorError unless %w[B W].include?(value&.upcase)
43
+ @color = value
44
+ end
45
+
46
+ def orientation=(value)
47
+ raise InvalidOrientationError unless %w[R L].include?(value&.upcase)
48
+ @orientation = value
49
+ end
50
+
51
+ def rounding_degree=(value)
52
+ raise InvalidRoundingDegree unless (0..8).include?(value.to_i)
53
+ @rounding_degree = value
54
+ end
55
+
56
+ def symbol_type=(value)
57
+ raise InvalidSymbolType unless %w[A B C D E].include?(value.upcase)
58
+ @symbol_type = value
59
+ end
60
+
61
+ def to_zpl
62
+ check_attributes
63
+ graphic = case graphic_type
64
+ when "B"
65
+ "B#{graphic_width},#{graphic_height},#{line_thickness},#{color},#{rounding_degree}"
66
+ when "C"
67
+ "C#{graphic_width},#{line_thickness},#{color}"
68
+ when "D"
69
+ "D#{graphic_width},#{graphic_height},#{line_thickness},#{color},#{orientation}"
70
+ when "E"
71
+ "E#{graphic_width},#{graphic_height},#{line_thickness},#{color}"
72
+ when "S"
73
+ sym = !symbol_type.nil? ? "^FD#{symbol_type}" : ''
74
+ "S,#{graphic_height},#{graphic_width}#{sym}"
75
+ end
76
+ "^FW#{rotation}^FO#{x},#{y}^G#{graphic}^FS"
77
+ end
78
+
79
+ private
80
+
81
+ def has_data?
82
+ false
83
+ end
84
+
85
+ def check_attributes
86
+ super
87
+ raise InvalidGraphicType if @graphic_type.nil?
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,91 @@
1
+ module Zebra
2
+ module Zpl
3
+ class Image
4
+ include Printable
5
+
6
+ class InvalidSizeError < StandardError; end
7
+ class InvalidRotationError < StandardError; end
8
+ class InvalidThresholdError < StandardError; end
9
+
10
+ attr_reader :path
11
+ attr_writer :invert, :compress
12
+
13
+ def path=(p)
14
+ @img = Img2Zpl::Image.open(p)
15
+ @path = @img.path
16
+ end
17
+
18
+ def width=(value)
19
+ raise InvalidSizeError.new('Invalid image width') unless value.to_i.positive?
20
+ @width = value.to_i
21
+ end
22
+
23
+ def width
24
+ @width || @img.width
25
+ end
26
+
27
+ def height=(value)
28
+ raise InvalidSizeError.new('Invalid image height') unless value.to_i.positive?
29
+ @height = value.to_i
30
+ end
31
+
32
+ def height
33
+ @height || @img.height
34
+ end
35
+
36
+ def rotation=(rot)
37
+ raise InvalidRotationError unless (true if Float(rot) rescue false)
38
+ @rotation = rot
39
+ end
40
+
41
+ def rotation
42
+ @rotation || 0
43
+ end
44
+
45
+ def black_threshold=(value)
46
+ raise InvalidThresholdError.new('Invalid black threshold') unless value.to_f >= 0 && value.to_f <= 1
47
+ @black_threshold = value.to_f
48
+ end
49
+
50
+ def black_threshold
51
+ @black_threshold || 0.5
52
+ end
53
+
54
+ def invert
55
+ @invert || false
56
+ end
57
+
58
+ def compress
59
+ @compress || true
60
+ end
61
+
62
+ def to_zpl
63
+ check_attributes
64
+ modify
65
+ graphics = @img.to_zpl(
66
+ black_threshold: black_threshold,
67
+ invert: invert,
68
+ compress: compress
69
+ )
70
+ "^FO#{x},#{y}#{graphics}"
71
+ end
72
+
73
+ private
74
+
75
+ def has_data?
76
+ false
77
+ end
78
+
79
+ def modify
80
+ @img.resize("#{width}x#{height}") if @width || @height
81
+ @img.rotate(@rotation) if @rotation
82
+ end
83
+
84
+ def check_attributes
85
+ super
86
+ raise MissingAttributeError.new("the path is invalid or not given") unless @path
87
+ end
88
+
89
+ end
90
+ end
91
+ end
@@ -9,34 +9,24 @@ module Zebra
9
9
 
10
10
  attr_writer :copies
11
11
  attr_reader :elements, :tempfile
12
- attr_accessor :width, :length, :gap, :print_speed, :print_density
12
+ attr_accessor :width, :length, :print_speed
13
13
 
14
14
  def initialize(options = {})
15
15
  options.each_pair { |key, value| self.__send__("#{key}=", value) if self.respond_to?("#{key}=") }
16
16
  @elements = []
17
17
  end
18
18
 
19
- def length_and_gap=(length_and_gap)
20
- self.length = length_and_gap[0]
21
- self.gap = length_and_gap[1]
22
- end
23
-
24
19
  def print_speed=(s)
25
20
  raise InvalidPrintSpeedError unless (0..6).include?(s)
26
21
  @print_speed = s
27
22
  end
28
23
 
29
- def print_density=(d)
30
- raise InvalidPrintDensityError unless (0..15).include?(d)
31
- @print_density = d
32
- end
33
-
34
24
  def copies
35
25
  @copies || 1
36
26
  end
37
27
 
38
28
  def <<(element)
39
- element.width = self.width
29
+ element.width = self.width if element.respond_to?("width=") && element.width.nil?
40
30
  elements << element
41
31
  end
42
32
 
@@ -75,7 +65,6 @@ module Zebra
75
65
  end
76
66
 
77
67
  def persist
78
- # debugger
79
68
  tempfile = Tempfile.new "zebra_label"
80
69
  dump_contents tempfile
81
70
  tempfile.close
@@ -0,0 +1,50 @@
1
+ require "zebra/zpl/printable"
2
+
3
+ module Zebra
4
+ module Zpl
5
+ class PDF417
6
+ include Printable
7
+
8
+ class InvalidScaleFactorError < StandardError; end
9
+ class InvalidSecurityLevelError < StandardError; end
10
+ class InvalidRowColumnNumberError < StandardError; end
11
+
12
+ attr_reader :row_height, :security_level, :column_number, :row_number, :truncate
13
+
14
+ def row_height=(value)
15
+ @row_height = value
16
+ end
17
+
18
+ def row_number=(value)
19
+ raise InvalidRowColumnNumberError unless (3..90).include?(value.to_i)
20
+ @row_number = value
21
+ end
22
+
23
+ def column_number=(value)
24
+ raise InvalidRowColumnNumberError unless (1..30).include?(value.to_i)
25
+ @column_number = value
26
+ end
27
+
28
+ def truncate=(value)
29
+ @truncate = value
30
+ end
31
+
32
+ def security_level=(value)
33
+ raise InvalidSecurityLevelError unless (0..8).include?(value.to_i)
34
+ @security_level = value
35
+ end
36
+
37
+ def to_zpl
38
+ check_attributes
39
+ "^FO#{x},#{y}^BY,,10^B7#{rotation},#{row_height},#{security_level},#{column_number},#{row_number},#{truncate} ^FD #{data} ^FS"
40
+ end
41
+
42
+ private
43
+
44
+ def check_attributes
45
+ super
46
+ raise InvalidRowColumnNumberError if !@row_number.nil? && !@column_number.nil? && @row_number.to_i * @column_number.to_i > 928
47
+ end
48
+ end
49
+ end
50
+ end
@@ -8,7 +8,7 @@ module Zebra
8
8
  class InvalidScaleFactorError < StandardError; end
9
9
  class InvalidCorrectionLevelError < StandardError; end
10
10
 
11
- attr_reader :scale_factor, :correction_level
11
+ attr_reader :scale_factor, :correction_level, :width
12
12
 
13
13
  def width=(width)
14
14
  @width = width || 0
@@ -26,7 +26,7 @@ module Zebra
26
26
 
27
27
  def to_zpl
28
28
  check_attributes
29
- "^FW#{rotation}^FO#{x},#{y}^BQN,2,#{scale_factor},,3^FD#{correction_level}A,#{data}^FS"
29
+ "^FW#{rotation}^FO#{x},#{y}^BY,,10^BQN,2,#{scale_factor},,3^FD#{correction_level}A,#{data}^FS"
30
30
  end
31
31
 
32
32
  private
@@ -5,13 +5,19 @@ module Zebra
5
5
  class Text
6
6
  include Printable
7
7
 
8
- attr_reader :font_size, :font_type, :width
8
+ class InvalidMaxLinesError < StandardError; end
9
+
10
+ attr_reader :font_size, :font_type, :width, :line_spacing, :hanging_indent, :bold
9
11
 
10
12
  def font_size=(f)
11
13
  FontSize.validate_font_size f
12
14
  @font_size = f
13
15
  end
14
16
 
17
+ def bold=(value)
18
+ @bold = value
19
+ end
20
+
15
21
  def width=(width)
16
22
  unless (margin.nil? || margin < 1)
17
23
  @width = (width - (margin*2))
@@ -20,6 +26,19 @@ module Zebra
20
26
  end
21
27
  end
22
28
 
29
+ def max_lines=(value)
30
+ raise InvalidMaxLinesError unless value.to_i >= 1
31
+ @max_lines = value
32
+ end
33
+
34
+ def line_spacing=(value)
35
+ @line_spacing = value || 0
36
+ end
37
+
38
+ def hanging_indent=(value)
39
+ @hanging_indent = value || 0
40
+ end
41
+
23
42
  def font_type=(type)
24
43
  FontType.validate_font_type type
25
44
  @font_type = type
@@ -38,35 +57,40 @@ module Zebra
38
57
  @print_mode || PrintMode::NORMAL
39
58
  end
40
59
 
41
- def h_multiplier
42
- @h_multiplier || HorizontalMultiplier::VALUE_1
43
- end
44
-
45
- def v_multiplier
46
- @v_multiplier || VerticalMultiplier::VALUE_1
47
- end
60
+ # def h_multiplier
61
+ # @h_multiplier || HorizontalMultiplier::VALUE_1
62
+ # end
63
+ #
64
+ # def v_multiplier
65
+ # @v_multiplier || VerticalMultiplier::VALUE_1
66
+ # end
48
67
 
49
68
  def print_mode
50
69
  @print_mode || PrintMode::NORMAL
51
70
  end
52
71
 
53
- def h_multiplier=(multiplier)
54
- HorizontalMultiplier.validate_multiplier multiplier
55
- @h_multiplier = multiplier
72
+ def max_lines
73
+ @max_lines || 4
56
74
  end
57
75
 
58
- def v_multiplier=(multiplier)
59
- VerticalMultiplier.validate_multiplier multiplier
60
- @v_multiplier = multiplier
61
- end
76
+ # def h_multiplier=(multiplier)
77
+ # HorizontalMultiplier.validate_multiplier multiplier
78
+ # @h_multiplier = multiplier
79
+ # end
80
+ #
81
+ # def v_multiplier=(multiplier)
82
+ # VerticalMultiplier.validate_multiplier multiplier
83
+ # @v_multiplier = multiplier
84
+ # end
62
85
 
63
86
  def to_zpl
64
87
  check_attributes
65
- # ["A#{x}", y, rotation, font_size, h_multiplier, v_multiplier, print_mode, "\"#{data}\""].join(",")
66
- # "^FO25,25^FB600,100,0,C,0^FDFoo^FS"
67
-
68
- # "^CF#{font_type},#{font_size}^FO#{x},#{y}^FB609,4,0,#{justification},0^FD#{data}^FS"
69
- "^FW#{rotation}^CF#{font_type},#{font_size}^CI28^FO#{x},#{y}^FB#{width},4,0,#{justification},0^FD#{data}^FS"
88
+ if !bold.nil?
89
+ "^FW#{rotation}^CF#{font_type},#{font_size}^CI28^FO#{x+2},#{y}^FB#{width},#{max_lines},#{line_spacing},#{justification},#{hanging_indent}^FD#{data}^FS" +
90
+ "^FW#{rotation}^CF#{font_type},#{font_size}^CI28^FO#{x},#{y+2}^FB#{width},#{max_lines},#{line_spacing},#{justification},#{hanging_indent}^FD#{data}^FS"
91
+ else
92
+ "^FW#{rotation}^CF#{font_type},#{font_size}^CI28^FO#{x},#{y}^FB#{width},#{max_lines},#{line_spacing},#{justification},#{hanging_indent}^FD#{data}^FS"
93
+ end
70
94
  end
71
95
 
72
96
  private