escper 1.1.4 → 1.1.5
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +180 -0
- data/escper.gemspec +9 -6
- data/{lib/escper → examples}/test.png +0 -0
- data/lib/escper.rb +27 -1
- data/lib/escper/log.rb +9 -0
- data/lib/escper/printer.rb +34 -28
- data/lib/escper/vendor_printer.rb +52 -0
- data/lib/escper/version.rb +1 -1
- metadata +49 -12
- data/README +0 -40
data/README.md
ADDED
@@ -0,0 +1,180 @@
|
|
1
|
+
Escper (read: "escaper") -- Easy printing to serial thermal printers
|
2
|
+
=======================================================================
|
3
|
+
|
4
|
+
Installation
|
5
|
+
------------
|
6
|
+
|
7
|
+
gem install escper
|
8
|
+
|
9
|
+
Introduction
|
10
|
+
------------
|
11
|
+
|
12
|
+
Escper is a collection of essential tools that make printing of plain text and images to one or many serial thermal printers easy. Both USB and serial (RS232) printers are supported and detected automatically. Escper is useful for Ruby based Point of Sale systems that want to print receipts or tickets.
|
13
|
+
|
14
|
+
While the actual printing is just writing a string to a device node inside of `/dev`, there is some preprocessing necessary. Thermal printers usually have a narrow character set, do not support UTF-8, only ASCII-8BIT. Escper makes it possible to just send UTF-8 text and it does all the conversion work under the covers. For special characters, Escper will map UTF-8 characters to the ASCII-8BIT codes that are actually supported by the currently set codepage on the printer (have a look at the user manual of your printer). The file `lib/escper/codepages.yml` is an example for matching UTF-8 codes to ASCII codes.
|
15
|
+
|
16
|
+
Another tricky usecase is where text is mixed with images. Images are transformed into ESCPOS compatible printing data, which is supported by the majority of thermal printers. When mixing text and images, Escper will transform special UTF-8 characters according to the above mentioned codepages.yml file, but leave the image data unchanged.
|
17
|
+
|
18
|
+
Some Point of Sale systems, especially those for restaurants, have to send tickets to several printers at the same time (e.g. kitchen, bar, etc.). Escper makes this easy. Have a look at the usage examples below.
|
19
|
+
|
20
|
+
Usecase: Convert image to ESCPOS code
|
21
|
+
------------
|
22
|
+
|
23
|
+
Load Escper:
|
24
|
+
|
25
|
+
require 'escper'
|
26
|
+
|
27
|
+
The source of the image can be a file:
|
28
|
+
|
29
|
+
escpos_code = Escper::Img.new('/path/to/test.png', :file).to_s
|
30
|
+
|
31
|
+
The source of the image can also be data which is uploaded from a HTML form:
|
32
|
+
|
33
|
+
escpos_code = Escper::Img.new(data.read, :blob).to_s
|
34
|
+
|
35
|
+
"Data" is a variable containing the image data of a multipart HTML form.
|
36
|
+
|
37
|
+
Alternatively, the source can be an ImageMagick canvas:
|
38
|
+
|
39
|
+
canvas = Magick::Image.new(512, 128)
|
40
|
+
gc = Magick::Draw.new
|
41
|
+
gc.stroke('black')
|
42
|
+
gc.stroke_width(5)
|
43
|
+
gc.fill('white')
|
44
|
+
gc.fill_opacity(0)
|
45
|
+
gc.stroke_antialias(false)
|
46
|
+
gc.stroke_linejoin('round')
|
47
|
+
gc.translate(-10,-39)
|
48
|
+
gc.scale(1.11,0.68)
|
49
|
+
gc.path("M 14,57 L 14,56 L 15,58 L 13,58 L 14,57 L 21,59 28,60 34,62 40,65 46,67 52,68 56,70 61,72 66,73 70,74 75,74")
|
50
|
+
gc.draw(canvas)
|
51
|
+
escpos_code = Escper::Img.new(canvas,:obj).to_s
|
52
|
+
|
53
|
+
For optimal visual results, when using a file or a blob, the image should previously be converted to an indexed, black and white 1-bit palette image. In Gimp, click on "Image -> Mode -> Indexed..." and select "Use black and white (1-bit) palette". For dithering, choose "Floyd-Steinberg (reduced color bleeding)". The image size depends on the resolution of the printer. The Escper gem contains a test image in `examples/escper.png`.
|
54
|
+
|
55
|
+
To send an image directly to a thermal receipt printer in just one line:
|
56
|
+
|
57
|
+
File.open('/dev/usb/lp0','w') { |f| f.write Escper::Img.new('/path/to/image.png').to_s }
|
58
|
+
|
59
|
+
Usecase: Print UTF-8 text to several serial printers at the same time
|
60
|
+
------------
|
61
|
+
|
62
|
+
First, create printer objects which are simply containers for data about the printer. If you develop your application in a framework like Rails, you also can use the models from this application instead of creating them from within Escper. The only requirements are that the objects respond to the methods `id`, `name`, `path`, `copies` and `codepage`.
|
63
|
+
|
64
|
+
vp1 = Escper::VendorPrinter.new :id => 1, :name => 'Printer 1 USB', :path => '/dev/usb/lp0', :copies => 1
|
65
|
+
vp2 = Escper::VendorPrinter.new :id => 2, :name => 'Printer 2 USB', :path => '/dev/usb/lp0', :copies => 1
|
66
|
+
vp3 = Escper::VendorPrinter.new :id => 3, :name => 'Printer 3 RS232', :path => '/dev/ttyUSB0', :copies => 1
|
67
|
+
|
68
|
+
`id` must be unique numbers which will be needed later during printing. `name` is an arbitrary string which is only used for logging. `path` is the path to a regular file or the device node of the thermal printer which usually lives under `/dev`. Device nodes can be of the type USB or serial (RS232). `copies` are the number of copies of pages that the printer should print. Optionally, you can pass in the key `codepage` which is a number that must correspond to one of the YAML keys in the file `codepages.yml`. By making the `codepage` a parameter of the printer model, it is possible to use several different printers from different manufacturers with different character sets at the same time.
|
69
|
+
|
70
|
+
Next, initialize the printing engine of Escper by passing it an array of the printer objects. It is also possible to pass it a single printer model instead of an array:
|
71
|
+
|
72
|
+
print_engine = Escper::Printer.new 'local', [vp1, vp2, vp3]
|
73
|
+
|
74
|
+
Now, open all device nodes as specified in `new`:
|
75
|
+
|
76
|
+
print_engine.open
|
77
|
+
|
78
|
+
Once all device nodes are openend for writing, you can print text. Text must be UTF-8 encoded. The fist parameter is the `id` of the printer object that should be printed to. The second parameter, the text, will be printed immediately:
|
79
|
+
|
80
|
+
print_engine.print 1, 'print text to printer 1'
|
81
|
+
print_engine.print 2, 'print text to printer 1'
|
82
|
+
print_engine.print 3, 'print text to printer 1'
|
83
|
+
|
84
|
+
The `print` method will return an array which contains the number of bytes actually written to the device node, as well as the raw text that was written to the device node.
|
85
|
+
|
86
|
+
After printing is finished, don't forget to close the device nodes which were openened during the `open` call:
|
87
|
+
|
88
|
+
print_engine.close
|
89
|
+
|
90
|
+
|
91
|
+
Usecase: Print UTF8 text mixed with binary images
|
92
|
+
------------
|
93
|
+
|
94
|
+
Create a printer object:
|
95
|
+
|
96
|
+
vp1 = Escper::VendorPrinter.new :id => 1, :name => 'Printer 1 USB', :path => '/dev/usb/lp0', :copies => 1
|
97
|
+
|
98
|
+
Render images into ESCPOS, stored in variables:
|
99
|
+
|
100
|
+
image_escpos1 = Escper::Img.new('/path/to/test1.png', :file).to_s
|
101
|
+
image_escpos2 = Escper::Img.new('/path/to/test2.png', :file).to_s
|
102
|
+
|
103
|
+
This raw image data now must be stored in a hash, whith a unique key that gives the image a unique name:
|
104
|
+
|
105
|
+
raw_images = {:image1 => image_escpos1, :image2 => image_escpos2}
|
106
|
+
|
107
|
+
Initialize the print engine:
|
108
|
+
|
109
|
+
print_engine = Escper::Printer.new 'local', vp1
|
110
|
+
|
111
|
+
Open the printer device nodes:
|
112
|
+
|
113
|
+
print_engine.open
|
114
|
+
|
115
|
+
Print text and image at the same time:
|
116
|
+
|
117
|
+
print_engine.print 1, 'print text and image1 {::escper}image1{:/} and image 2 {::escper}image1{:/} to printer 1', raw_images
|
118
|
+
|
119
|
+
Note that the magic tag `{::escper}image_key{:/}` will be replaced by Escper with the image that is stored in the hash `raw_images` with the key `image_key`.
|
120
|
+
|
121
|
+
After printing is done, close the device nodes again:
|
122
|
+
|
123
|
+
print_engine.close
|
124
|
+
|
125
|
+
|
126
|
+
Fallback mode
|
127
|
+
----------------------
|
128
|
+
|
129
|
+
If a device node is busy or not writable, Escper will create fallback files instead and append the print data to that file. The fallback files will have the name of the printers and will be saved inside of `/tmp`, or, when you include Escper from Rails, in the `tmp` folder of the Rails app source.
|
130
|
+
|
131
|
+
Configuration
|
132
|
+
----------------------
|
133
|
+
|
134
|
+
You can configure Escper by calling in your project:
|
135
|
+
|
136
|
+
Escper.setup do |config|
|
137
|
+
config.codepage_file = File.join('path', 'to', 'codepages.yml')
|
138
|
+
config.use_safe_device_path = false
|
139
|
+
config.safe_device_path = File.join('path', 'to', 'outputdir')
|
140
|
+
end
|
141
|
+
|
142
|
+
`codepage_file` specifies the path to `codepages.yml`. (for an explanation see above)
|
143
|
+
|
144
|
+
`use_safe_device_path` can be set to `true` when you are running Escper on a remote server and no actual writes to device nodes should occur. In this case, all print data will be stored in regular files in the path `safe_device_path` with safe file names, which can be further processed or submitted by other programs.
|
145
|
+
|
146
|
+
Additional Features
|
147
|
+
----------------------
|
148
|
+
|
149
|
+
For additional features, please study the source code.
|
150
|
+
|
151
|
+
|
152
|
+
Contact
|
153
|
+
----------------------
|
154
|
+
|
155
|
+
Ask for support or additional features!
|
156
|
+
|
157
|
+
Red (E) Tools Ltd.
|
158
|
+
|
159
|
+
office@red-e.eu
|
160
|
+
|
161
|
+
www.red-e.eu
|
162
|
+
|
163
|
+
|
164
|
+
Licence
|
165
|
+
----------------------
|
166
|
+
|
167
|
+
Copyright (C) 2011-2013 Red (E) Tools Ltd. <office@red-e.eu>
|
168
|
+
|
169
|
+
This program is free software: you can redistribute it and/or modify
|
170
|
+
it under the terms of the GNU Affero General Public License as
|
171
|
+
published by the Free Software Foundation, either version 3 of the
|
172
|
+
License, or (at your option) any later version.
|
173
|
+
|
174
|
+
This program is distributed in the hope that it will be useful,
|
175
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
176
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
177
|
+
GNU Affero General Public License for more details.
|
178
|
+
|
179
|
+
You should have received a copy of the GNU Affero General Public License
|
180
|
+
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
data/escper.gemspec
CHANGED
@@ -6,16 +6,19 @@ Gem::Specification.new do |s|
|
|
6
6
|
s.name = "escper"
|
7
7
|
s.version = Escper::VERSION
|
8
8
|
s.platform = Gem::Platform::RUBY
|
9
|
-
s.authors = ["
|
10
|
-
s.email = ["office@
|
11
|
-
s.homepage = "http://
|
12
|
-
s.summary = %q{
|
13
|
-
s.description = %q{}
|
9
|
+
s.authors = ["Red (E) Tools Ltd."]
|
10
|
+
s.email = ["office@red-e.eu"]
|
11
|
+
s.homepage = "http://red-e.eu"
|
12
|
+
s.summary = %q{Collection of essential tools that make printing of plain text and images to one or many serial thermal printers easy.}
|
13
|
+
s.description = %q{Both USB and serial (RS232) printers are supported and detected automatically. Escper is useful for Ruby based Point of Sale systems that want to print receipts or tickets.}
|
14
14
|
|
15
|
-
s.rubyforge_project = "escper"
|
15
|
+
#s.rubyforge_project = "escper"
|
16
16
|
|
17
17
|
s.files = `git ls-files`.split("\n")
|
18
18
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
19
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
20
|
s.require_paths = ["lib"]
|
21
|
+
|
22
|
+
s.add_dependency('rmagick')
|
23
|
+
s.add_dependency('serialport')
|
21
24
|
end
|
File without changes
|
data/lib/escper.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
require 'RMagick'
|
2
|
+
require 'yaml'
|
3
|
+
#require 'active_record'
|
2
4
|
|
3
5
|
dir = File.dirname(__FILE__)
|
4
6
|
Dir[File.expand_path("#{dir}/escper/*.rb")].uniq.each do |file|
|
@@ -6,7 +8,31 @@ Dir[File.expand_path("#{dir}/escper/*.rb")].uniq.each do |file|
|
|
6
8
|
end
|
7
9
|
|
8
10
|
module Escper
|
9
|
-
mattr_accessor :codepage_file, :use_safe_device_path, :safe_device_path
|
11
|
+
#mattr_accessor :codepage_file, :use_safe_device_path, :safe_device_path
|
12
|
+
|
13
|
+
def self.codepage_file
|
14
|
+
@@codepage_file
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.codepage_file=(codepage_file)
|
18
|
+
@@codepage_file = codepage_file
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.use_safe_device_path
|
22
|
+
@@use_safe_device_path
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.use_safe_device_path=(use_safe_device_path)
|
26
|
+
@@use_safe_device_path = use_safe_device_path
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.safe_device_path
|
30
|
+
@@safe_device_path
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.safe_device_path=(safe_device_path)
|
34
|
+
@@safe_device_path = safe_device_path
|
35
|
+
end
|
10
36
|
|
11
37
|
@@codepage_file = File.join(File.dirname(__FILE__), 'escper', 'codepages.yml')
|
12
38
|
@@use_safe_device_path = false
|
data/lib/escper/log.rb
ADDED
data/lib/escper/printer.rb
CHANGED
@@ -2,19 +2,24 @@ module Escper
|
|
2
2
|
class Printer
|
3
3
|
# mode can be local or sass
|
4
4
|
# vendor_printers can either be a single VendorPrinter object, or an Array of VendorPrinter objects, or an ActiveRecord Relation containing VendorPrinter objects.
|
5
|
-
def initialize(mode, vendor_printers=nil, subdomain=nil)
|
5
|
+
def initialize(mode='local', vendor_printers=nil, subdomain=nil)
|
6
6
|
@mode = mode
|
7
7
|
@subdomain = subdomain
|
8
8
|
@open_printers = Hash.new
|
9
9
|
@codepages_lookup = YAML::load(File.read(Escper.codepage_file))
|
10
10
|
@file_mode = 'wb'
|
11
|
-
if
|
11
|
+
if defined?(Rails)
|
12
|
+
@fallback_root_path = Rails.root
|
13
|
+
else
|
14
|
+
@fallback_root_path = '/'
|
15
|
+
end
|
16
|
+
if vendor_printers.kind_of?(Array) or (defined?(ActiveRecord) == true and vendor_printers.kind_of?(ActiveRecord::Relation))
|
12
17
|
@vendor_printers = vendor_printers
|
13
18
|
elsif vendor_printers.kind_of? VendorPrinter
|
14
19
|
@vendor_printers = [vendor_printers]
|
15
20
|
else
|
16
21
|
# If no available VendorPrinters are initialized, create a set of temporary VendorPrinters with usual device paths.
|
17
|
-
puts "No VendorPrinters specified. Creating a set of temporary printers with
|
22
|
+
puts "No VendorPrinters specified. Creating a set of temporary printers with common device paths"
|
18
23
|
paths = ['/dev/ttyUSB0', '/dev/ttyUSB1', '/dev/ttyUSB2', '/dev/usb/lp0', '/dev/usb/lp1', '/dev/usb/lp2', '/dev/salor-hospitality-front', '/dev/salor-hospitality-top', '/dev/salor-hospitality-back-top-left', '/dev/salor-hospitality-back-top-right', '/dev/salor-hospitality-back-bottom-left', '/dev/salor-hospitality-back-bottom-right']
|
19
24
|
@vendor_printers = Array.new
|
20
25
|
paths.size.times do |i|
|
@@ -25,8 +30,8 @@ module Escper
|
|
25
30
|
|
26
31
|
def print(printer_id, text, raw_text_insertations={})
|
27
32
|
return if @open_printers == {}
|
28
|
-
|
29
|
-
|
33
|
+
Escper.log "[PRINTING]============"
|
34
|
+
Escper.log "[PRINTING]PRINTING..."
|
30
35
|
printer = @open_printers[printer_id]
|
31
36
|
raise 'Mismatch between open_printers and printer_id' if printer.nil?
|
32
37
|
|
@@ -34,15 +39,16 @@ module Escper
|
|
34
39
|
codepage ||= 0
|
35
40
|
output_text = Printer.merge_texts(text, raw_text_insertations, codepage)
|
36
41
|
|
37
|
-
|
42
|
+
Escper.log "[PRINTING] Printing on #{ printer[:name] } @ #{ printer[:device].inspect }."
|
38
43
|
bytes_written = nil
|
39
44
|
printer[:copies].times do |i|
|
40
45
|
# The method .write works both for SerialPort object and File object, so we don't have to distinguish here.
|
41
46
|
bytes_written = @open_printers[printer_id][:device].write output_text
|
42
|
-
|
47
|
+
Escper.log "[PRINTING]ERROR: Byte count mismatch: sent #{text.length} written #{bytes_written}" unless output_text.length == bytes_written
|
43
48
|
end
|
44
49
|
# The method .flush works both for SerialPort object and File object, so we don't have to distinguish here. It is not really neccessary, since the close method will theoretically flush also.
|
45
50
|
@open_printers[printer_id][:device].flush
|
51
|
+
Escper.log "[PRINTING] #{ output_text[0..60] }"
|
46
52
|
return bytes_written, output_text
|
47
53
|
end
|
48
54
|
|
@@ -57,8 +63,8 @@ module Escper
|
|
57
63
|
end
|
58
64
|
|
59
65
|
def identify(chartest=nil)
|
60
|
-
|
61
|
-
|
66
|
+
Escper.log "[PRINTING]============"
|
67
|
+
Escper.log "[PRINTING]TESTING Printers..."
|
62
68
|
open
|
63
69
|
@open_printers.each do |id, value|
|
64
70
|
init = "\e@"
|
@@ -70,7 +76,7 @@ module Escper
|
|
70
76
|
"#{ value[:name] }\r\n" +
|
71
77
|
"#{ value[:device].inspect }"
|
72
78
|
|
73
|
-
|
79
|
+
Escper.log "[PRINTING] Testing #{value[:device].inspect }"
|
74
80
|
if chartest
|
75
81
|
print(id, init + Escper::Asciifier.all_chars + cut)
|
76
82
|
else
|
@@ -82,8 +88,8 @@ module Escper
|
|
82
88
|
end
|
83
89
|
|
84
90
|
def open
|
85
|
-
|
86
|
-
|
91
|
+
Escper.log "[PRINTING]============"
|
92
|
+
Escper.log "[PRINTING]OPEN Printers..."
|
87
93
|
@vendor_printers.size.times do |i|
|
88
94
|
p = @vendor_printers[i]
|
89
95
|
name = p.name
|
@@ -96,60 +102,60 @@ module Escper
|
|
96
102
|
@file_mode = 'ab'
|
97
103
|
end
|
98
104
|
|
99
|
-
|
105
|
+
Escper.log "[PRINTING] Trying to open #{ name } @ #{ path } ..."
|
100
106
|
pid = p.id ? p.id : i
|
101
107
|
begin
|
102
108
|
printer = SerialPort.new path, 9600
|
103
109
|
@open_printers.merge! pid => { :name => name, :path => path, :copies => p.copies, :device => printer, :codepage => codepage }
|
104
|
-
|
110
|
+
Escper.log "[PRINTING] Success for SerialPort: #{ printer.inspect }"
|
105
111
|
next
|
106
112
|
rescue Exception => e
|
107
|
-
|
113
|
+
Escper.log "[PRINTING] Failed to open as SerialPort: #{ e.inspect }"
|
108
114
|
end
|
109
115
|
|
110
116
|
begin
|
111
117
|
printer = File.open path, @file_mode
|
112
118
|
@open_printers.merge! pid => { :name => name, :path => path, :copies => p.copies, :device => printer, :codepage => codepage }
|
113
|
-
|
119
|
+
Escper.log "[PRINTING] Success for File: #{ printer.inspect }"
|
114
120
|
next
|
115
121
|
rescue Errno::EBUSY
|
116
|
-
|
117
|
-
|
122
|
+
Escper.log "[PRINTING] The File #{ path } is already open."
|
123
|
+
Escper.log "[PRINTING] Trying to reuse already opened printers."
|
118
124
|
previously_opened_printers = @open_printers.clone
|
119
125
|
previously_opened_printers.each do |key, val|
|
120
|
-
|
126
|
+
Escper.log "[PRINTING] Trying to reuse already opened File #{ key }: #{ val.inspect }"
|
121
127
|
if val[:path] == p[:path] and val[:device].class == File
|
122
|
-
|
128
|
+
Escper.log "[PRINTING] Reused."
|
123
129
|
@open_printers.merge! pid => { :name => name, :path => path, :copies => p.copies, :device => val[:device], :codepage => codepage }
|
124
130
|
break
|
125
131
|
end
|
126
132
|
end
|
127
133
|
unless @open_printers.has_key? p.id
|
128
|
-
path = File.join(
|
134
|
+
path = File.join(@fallback_root_path, 'tmp')
|
129
135
|
printer = File.open(File.join(path, "#{ p.id }-#{ name }-fallback-busy.salor"), @file_mode)
|
130
136
|
@open_printers.merge! pid => { :name => name, :path => path, :copies => p.copies, :device => printer, :codepage => codepage }
|
131
|
-
|
137
|
+
Escper.log "[PRINTING] Failed to open as either SerialPort or USB File and resource IS busy. This should not have happened. Created #{ printer.inspect } instead."
|
132
138
|
end
|
133
139
|
next
|
134
140
|
rescue Exception => e
|
135
|
-
path = File.join(
|
141
|
+
path = File.join(@fallback_root_path, 'tmp')
|
136
142
|
printer = File.open(File.join(path, "#{ p.id }-#{ name }-fallback-notbusy.salor"), @file_mode)
|
137
143
|
@open_printers.merge! pid => { :name => name, :path => path, :copies => p.copies, :device => printer, :codepage => codepage }
|
138
|
-
|
144
|
+
Escper.log "[PRINTING] Failed to open as either SerialPort or USB File and resource is NOT busy. Created #{ printer.inspect } instead."
|
139
145
|
end
|
140
146
|
end
|
141
147
|
end
|
142
148
|
|
143
149
|
def close
|
144
|
-
|
145
|
-
|
150
|
+
Escper.log "[PRINTING]============"
|
151
|
+
Escper.log "[PRINTING]CLOSING Printers..."
|
146
152
|
@open_printers.each do |key, value|
|
147
153
|
begin
|
148
154
|
value[:device].close
|
149
|
-
|
155
|
+
Escper.log "[PRINTING] Closing #{ value[:name] } @ #{ value[:device].inspect }"
|
150
156
|
@open_printers.delete(key)
|
151
157
|
rescue Exception => e
|
152
|
-
|
158
|
+
Escper.log "[PRINTING] Error during closing of #{ value[:device] }: #{ e.inspect }"
|
153
159
|
end
|
154
160
|
end
|
155
161
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Escper
|
2
|
+
class VendorPrinter
|
3
|
+
|
4
|
+
def initialize(attrs)
|
5
|
+
@name = attrs[:name]
|
6
|
+
@path = attrs[:path]
|
7
|
+
@copies = attrs[:copies]
|
8
|
+
@codepage = attrs[:codepage]
|
9
|
+
@id = attrs[:id]
|
10
|
+
end
|
11
|
+
|
12
|
+
def name
|
13
|
+
@name
|
14
|
+
end
|
15
|
+
|
16
|
+
def name=(name)
|
17
|
+
@name = name
|
18
|
+
end
|
19
|
+
|
20
|
+
def path
|
21
|
+
@path
|
22
|
+
end
|
23
|
+
|
24
|
+
def path=(path)
|
25
|
+
@path = path
|
26
|
+
end
|
27
|
+
|
28
|
+
def copies
|
29
|
+
@copies
|
30
|
+
end
|
31
|
+
|
32
|
+
def copies=(copies)
|
33
|
+
@copies = copies
|
34
|
+
end
|
35
|
+
|
36
|
+
def codepage
|
37
|
+
@codepage
|
38
|
+
end
|
39
|
+
|
40
|
+
def codepage=(codepage)
|
41
|
+
@codepage = codepage
|
42
|
+
end
|
43
|
+
|
44
|
+
def id
|
45
|
+
@id
|
46
|
+
end
|
47
|
+
|
48
|
+
def id=(id)
|
49
|
+
@id = id
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/lib/escper/version.rb
CHANGED
metadata
CHANGED
@@ -1,36 +1,72 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: escper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
|
-
-
|
8
|
+
- Red (E) Tools Ltd.
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
13
|
-
dependencies:
|
14
|
-
|
12
|
+
date: 2013-03-04 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rmagick
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: serialport
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
description: Both USB and serial (RS232) printers are supported and detected automatically.
|
47
|
+
Escper is useful for Ruby based Point of Sale systems that want to print receipts
|
48
|
+
or tickets.
|
15
49
|
email:
|
16
|
-
- office@
|
50
|
+
- office@red-e.eu
|
17
51
|
executables: []
|
18
52
|
extensions: []
|
19
53
|
extra_rdoc_files: []
|
20
54
|
files:
|
21
55
|
- .gitignore
|
22
56
|
- Gemfile
|
23
|
-
- README
|
57
|
+
- README.md
|
24
58
|
- Rakefile
|
25
59
|
- escper.gemspec
|
60
|
+
- examples/test.png
|
26
61
|
- lib/escper.rb
|
27
62
|
- lib/escper/asciifier.rb
|
28
63
|
- lib/escper/codepages.yml
|
29
64
|
- lib/escper/image.rb
|
65
|
+
- lib/escper/log.rb
|
30
66
|
- lib/escper/printer.rb
|
31
|
-
- lib/escper/
|
67
|
+
- lib/escper/vendor_printer.rb
|
32
68
|
- lib/escper/version.rb
|
33
|
-
homepage: http://
|
69
|
+
homepage: http://red-e.eu
|
34
70
|
licenses: []
|
35
71
|
post_install_message:
|
36
72
|
rdoc_options: []
|
@@ -49,9 +85,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
49
85
|
- !ruby/object:Gem::Version
|
50
86
|
version: '0'
|
51
87
|
requirements: []
|
52
|
-
rubyforge_project:
|
53
|
-
rubygems_version: 1.8.
|
88
|
+
rubyforge_project:
|
89
|
+
rubygems_version: 1.8.23
|
54
90
|
signing_key:
|
55
91
|
specification_version: 3
|
56
|
-
summary:
|
92
|
+
summary: Collection of essential tools that make printing of plain text and images
|
93
|
+
to one or many serial thermal printers easy.
|
57
94
|
test_files: []
|
data/README
DELETED
@@ -1,40 +0,0 @@
|
|
1
|
-
= Escper (read: "escaper") -- Convert an image to ESCPOS commands for thermal receipt printers
|
2
|
-
|
3
|
-
== Usage:
|
4
|
-
|
5
|
-
gem install escper
|
6
|
-
|
7
|
-
Test it in a Ruby script:
|
8
|
-
|
9
|
-
require 'escper'
|
10
|
-
puts Escper::Image.new('test.png', :file).to_s
|
11
|
-
|
12
|
-
Or if you read the image from an image upload form in Rails, do this:
|
13
|
-
|
14
|
-
Escper::Image.new(data.read, :blob).to_s
|
15
|
-
|
16
|
-
where "data" is a variable containing the image data of a multipart HTML form.
|
17
|
-
|
18
|
-
|
19
|
-
For optimal visual results, image.png should previously be converted to an indexed, black and white 1-bit palette image. In Gimp, click on "Image -> Mode -> Indexed..." and select "Use black and white (1-bit) palette". For dithering, choose "Floyd-Steinberg (reduced color bleeding)". The image size depends on the resolution of the printer.
|
20
|
-
|
21
|
-
To send an image directly to a thermal receipt printer:
|
22
|
-
|
23
|
-
File.open('/dev/usb/lp0','w') { |f| f.write Escper::Image.new('image.png').to_s }
|
24
|
-
|
25
|
-
== Licence
|
26
|
-
|
27
|
-
Copyright (C) 2011-2012 Michael Franzl <michael@billgastro.com>
|
28
|
-
|
29
|
-
This program is free software: you can redistribute it and/or modify
|
30
|
-
it under the terms of the GNU Affero General Public License as
|
31
|
-
published by the Free Software Foundation, either version 3 of the
|
32
|
-
License, or (at your option) any later version.
|
33
|
-
|
34
|
-
This program is distributed in the hope that it will be useful,
|
35
|
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
36
|
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
37
|
-
GNU Affero General Public License for more details.
|
38
|
-
|
39
|
-
You should have received a copy of the GNU Affero General Public License
|
40
|
-
along with this program. If not, see <http://www.gnu.org/licenses/>.
|