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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +62 -0
- data/CONTRIBUTING.md +49 -0
- data/Gemfile +6 -0
- data/README.md +259 -76
- data/docs/example.rb +249 -0
- data/docs/images/barcode.png +0 -0
- data/docs/images/datamatrix.png +0 -0
- data/docs/images/earth.jpg +0 -0
- data/docs/images/graphics.png +0 -0
- data/docs/images/image.png +0 -0
- data/docs/images/image_inverted.png +0 -0
- data/docs/images/images.png +0 -0
- data/docs/images/justification.png +0 -0
- data/docs/images/qrcode.png +0 -0
- data/docs/images/rotation.png +0 -0
- data/docs/images/text.png +0 -0
- data/lib/zebra/print_job.rb +7 -13
- data/lib/zebra/zpl.rb +20 -13
- data/lib/zebra/zpl/barcode.rb +29 -12
- data/lib/zebra/zpl/barcode_type.rb +4 -1
- data/lib/zebra/zpl/box.rb +16 -4
- data/lib/zebra/zpl/comment.rb +15 -0
- data/lib/zebra/zpl/datamatrix.rb +76 -0
- data/lib/zebra/zpl/graphic.rb +91 -0
- data/lib/zebra/zpl/image.rb +91 -0
- data/lib/zebra/zpl/label.rb +2 -13
- data/lib/zebra/zpl/pdf417.rb +50 -0
- data/lib/zebra/zpl/qrcode.rb +2 -2
- data/lib/zebra/zpl/text.rb +44 -20
- data/lib/zebra/zpl/version.rb +1 -1
- data/spec/fixtures/default.jpg +0 -0
- data/spec/spec_helper.rb +6 -2
- data/spec/zebra/print_job_spec.rb +13 -18
- data/spec/zebra/zpl/barcode_spec.rb +70 -63
- data/spec/zebra/zpl/box_spec.rb +27 -31
- data/spec/zebra/zpl/character_set_spec.rb +7 -7
- data/spec/zebra/zpl/comment_spec.rb +18 -0
- data/spec/zebra/zpl/datamatrix_spec.rb +124 -0
- data/spec/zebra/zpl/graphics_spec.rb +227 -0
- data/spec/zebra/zpl/image_spec.rb +113 -0
- data/spec/zebra/zpl/label_spec.rb +40 -52
- data/spec/zebra/zpl/pdf417_spec.rb +108 -0
- data/spec/zebra/zpl/qrcode_spec.rb +92 -92
- data/spec/zebra/zpl/text_spec.rb +57 -55
- data/zebra-zpl.gemspec +14 -15
- 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
|
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
|
-
|
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,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
|
data/lib/zebra/zpl/label.rb
CHANGED
@@ -9,34 +9,24 @@ module Zebra
|
|
9
9
|
|
10
10
|
attr_writer :copies
|
11
11
|
attr_reader :elements, :tempfile
|
12
|
-
attr_accessor :width, :length, :
|
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
|
data/lib/zebra/zpl/qrcode.rb
CHANGED
@@ -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
|
data/lib/zebra/zpl/text.rb
CHANGED
@@ -5,13 +5,19 @@ module Zebra
|
|
5
5
|
class Text
|
6
6
|
include Printable
|
7
7
|
|
8
|
-
|
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
|
-
|
43
|
-
end
|
44
|
-
|
45
|
-
def v_multiplier
|
46
|
-
|
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
|
54
|
-
|
55
|
-
@h_multiplier = multiplier
|
72
|
+
def max_lines
|
73
|
+
@max_lines || 4
|
56
74
|
end
|
57
75
|
|
58
|
-
def
|
59
|
-
|
60
|
-
|
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
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
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
|