a2_printer 0.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.
- data/Gemfile +3 -0
- data/README.md +32 -0
- data/lib/a2_printer.rb +332 -0
- data/lib/serial_connection.rb +18 -0
- data/test/a2_printer_test.rb +194 -0
- data/test/test_helper.rb +18 -0
- metadata +91 -0
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
A2 Printer
|
2
|
+
==========
|
3
|
+
|
4
|
+
A small library for working with cheap thermal "A2" printers, such as those available from Adafruit and Sparkfun.
|
5
|
+
|
6
|
+
Simple example
|
7
|
+
------
|
8
|
+
|
9
|
+
serial_connection = SerialConnection.new("/dev/serial")
|
10
|
+
printer = A2Printer.new(serial_connection)
|
11
|
+
|
12
|
+
printer.begin
|
13
|
+
printer.println("Hello world!")
|
14
|
+
printer.feed
|
15
|
+
printer.bold_on
|
16
|
+
printer.println("BOOM!")
|
17
|
+
printer.bold_off
|
18
|
+
|
19
|
+
|
20
|
+
Writing to a file
|
21
|
+
--------
|
22
|
+
|
23
|
+
This can be useful if you're going to use some other mechanism to send the bytes to the printer
|
24
|
+
|
25
|
+
commands_file = File.open("serial_commands.data", "w")
|
26
|
+
printer = A2Printer.new(commands_file)
|
27
|
+
printer.begin
|
28
|
+
printer.println("Hello world!")
|
29
|
+
|
30
|
+
# etc ...
|
31
|
+
|
32
|
+
commands_file.close
|
data/lib/a2_printer.rb
ADDED
@@ -0,0 +1,332 @@
|
|
1
|
+
require "serial_connection"
|
2
|
+
|
3
|
+
class A2Printer
|
4
|
+
def initialize(connection)
|
5
|
+
@connection = connection
|
6
|
+
@print_mode = 0
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_page
|
10
|
+
write_bytes(18, 84)
|
11
|
+
end
|
12
|
+
|
13
|
+
def begin(heat_time=150)
|
14
|
+
reset()
|
15
|
+
|
16
|
+
heat_interval = 50 # 2 is default from page 23 of datasheet. Controls speed of printing and darkness
|
17
|
+
print_density = 15 # Not sure what the default is. Testing shows the max helps darken text. From page 23.
|
18
|
+
print_break_time = 15 # Not sure what the default is. Testing shows the max helps darken text. From page 23.
|
19
|
+
|
20
|
+
write_bytes(27, 55)
|
21
|
+
write_bytes(7) # Default 64 dots = 8*('7'+1)
|
22
|
+
write_bytes(heat_time) # Default 80 or 800us
|
23
|
+
write_bytes(heat_interval) # Default 2 or 20us
|
24
|
+
|
25
|
+
# Modify the print density and timeout
|
26
|
+
write_bytes(18, 35)
|
27
|
+
print_setting = (print_density<<4) | print_break_time
|
28
|
+
write_bytes(print_setting) # Combination of print_density and print_break_time
|
29
|
+
end
|
30
|
+
|
31
|
+
# reset printer
|
32
|
+
def reset
|
33
|
+
write_bytes(27, 64)
|
34
|
+
end
|
35
|
+
|
36
|
+
# reset formatting
|
37
|
+
def set_default
|
38
|
+
online
|
39
|
+
normal
|
40
|
+
underline_off
|
41
|
+
justify(:left)
|
42
|
+
set_line_height(32)
|
43
|
+
set_barcode_height(50)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Feeds by the specified number of lines
|
47
|
+
def feed(lines=1)
|
48
|
+
# The datasheet claims sending bytes 27, 100, <x> will work
|
49
|
+
# but it feeds much much more.
|
50
|
+
lines.times { write(10) }
|
51
|
+
end
|
52
|
+
|
53
|
+
# Feeds by the specified number of rows of pixels
|
54
|
+
def feed_rows(rows)
|
55
|
+
write_bytes(27, 74, rows)
|
56
|
+
end
|
57
|
+
|
58
|
+
def flush
|
59
|
+
write_bytes(12)
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_page
|
63
|
+
write_bytes(18, 84)
|
64
|
+
end
|
65
|
+
|
66
|
+
def print(string)
|
67
|
+
string.bytes { |b| write(b) }
|
68
|
+
end
|
69
|
+
|
70
|
+
def println(string)
|
71
|
+
print(string + "\n")
|
72
|
+
end
|
73
|
+
|
74
|
+
def write(c)
|
75
|
+
return if (c == 0x13)
|
76
|
+
write_bytes(c)
|
77
|
+
end
|
78
|
+
|
79
|
+
def write_bytes(*bytes)
|
80
|
+
bytes.each { |b| @connection.putc(b) }
|
81
|
+
end
|
82
|
+
|
83
|
+
# Character commands
|
84
|
+
|
85
|
+
INVERSE_MASK = (1 << 1)
|
86
|
+
UPDOWN_MASK = (1 << 2)
|
87
|
+
BOLD_MASK = (1 << 3)
|
88
|
+
DOUBLE_HEIGHT_MASK = (1 << 4)
|
89
|
+
DOUBLE_WIDTH_MASK = (1 << 5)
|
90
|
+
STRIKE_MASK = (1 << 6)
|
91
|
+
|
92
|
+
def set_print_mode(mask)
|
93
|
+
@print_mode |= mask;
|
94
|
+
write_print_mode
|
95
|
+
end
|
96
|
+
|
97
|
+
def unset_print_mode(mask)
|
98
|
+
@print_mode &= ~mask;
|
99
|
+
write_print_mode
|
100
|
+
end
|
101
|
+
|
102
|
+
def write_print_mode
|
103
|
+
write_bytes(27, 33, @print_mode)
|
104
|
+
end
|
105
|
+
|
106
|
+
# This will reset bold, inverse, strikeout, upside down and font size
|
107
|
+
# It does not reset underline, justification or line height
|
108
|
+
def normal
|
109
|
+
@print_mode = 0
|
110
|
+
write_print_mode
|
111
|
+
end
|
112
|
+
|
113
|
+
def inverse_on
|
114
|
+
set_print_mode(INVERSE_MASK)
|
115
|
+
end
|
116
|
+
|
117
|
+
def inverse_off
|
118
|
+
unset_print_mode(INVERSE_MASK)
|
119
|
+
end
|
120
|
+
|
121
|
+
def upside_down_on
|
122
|
+
set_print_mode(UPDOWN_MASK);
|
123
|
+
end
|
124
|
+
|
125
|
+
def upside_down_off
|
126
|
+
unset_print_mode(UPDOWN_MASK);
|
127
|
+
end
|
128
|
+
|
129
|
+
def double_height_on
|
130
|
+
set_print_mode(DOUBLE_HEIGHT_MASK)
|
131
|
+
end
|
132
|
+
|
133
|
+
def double_height_off
|
134
|
+
unset_print_mode(DOUBLE_HEIGHT_MASK)
|
135
|
+
end
|
136
|
+
|
137
|
+
def double_width_on
|
138
|
+
set_print_mode(DOUBLE_WIDTH_MASK)
|
139
|
+
end
|
140
|
+
|
141
|
+
def double_width_off
|
142
|
+
unset_print_mode(DOUBLE_WIDTH_MASK)
|
143
|
+
end
|
144
|
+
|
145
|
+
def strike_on
|
146
|
+
set_print_mode(STRIKE_MASK)
|
147
|
+
end
|
148
|
+
|
149
|
+
def strike_off
|
150
|
+
unset_print_mode(STRIKE_MASK)
|
151
|
+
end
|
152
|
+
|
153
|
+
def bold_on
|
154
|
+
set_print_mode(BOLD_MASK)
|
155
|
+
end
|
156
|
+
|
157
|
+
def bold_off
|
158
|
+
unset_print_mode(BOLD_MASK)
|
159
|
+
end
|
160
|
+
|
161
|
+
def set_size(size)
|
162
|
+
byte = case size
|
163
|
+
when :small
|
164
|
+
0
|
165
|
+
when :medium
|
166
|
+
10
|
167
|
+
when :large
|
168
|
+
25
|
169
|
+
end
|
170
|
+
|
171
|
+
write_bytes(29, 33, byte, 10)
|
172
|
+
end
|
173
|
+
|
174
|
+
# Underlines of different weights can be produced:
|
175
|
+
# 0 - no underline
|
176
|
+
# 1 - normal underline
|
177
|
+
# 2 - thick underline
|
178
|
+
def underline_on(weight=1)
|
179
|
+
write_bytes(27, 45, weight)
|
180
|
+
end
|
181
|
+
|
182
|
+
def underline_off
|
183
|
+
underline_on(0)
|
184
|
+
end
|
185
|
+
|
186
|
+
def justify(position)
|
187
|
+
byte = case position
|
188
|
+
when :left
|
189
|
+
0
|
190
|
+
when :center
|
191
|
+
1
|
192
|
+
when :right
|
193
|
+
2
|
194
|
+
end
|
195
|
+
|
196
|
+
write_bytes(0x1B, 0x61, byte)
|
197
|
+
end
|
198
|
+
|
199
|
+
# Bitmaps
|
200
|
+
|
201
|
+
class Bitmap
|
202
|
+
attr_reader :width, :height
|
203
|
+
|
204
|
+
def initialize(width_or_source, height=nil, source=nil)
|
205
|
+
if height.nil? && source.nil?
|
206
|
+
set_source(width_or_source)
|
207
|
+
extract_width_and_height_from_data
|
208
|
+
else
|
209
|
+
set_source(source)
|
210
|
+
@width = width_or_source
|
211
|
+
@height = height
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
def each_block
|
216
|
+
row_start = 0
|
217
|
+
width_in_bytes = width / 8
|
218
|
+
while row_start < height do
|
219
|
+
chunk_height = ((height - row_start) > 255) ? 255 : (height - row_start)
|
220
|
+
bytes = (0...(width_in_bytes * chunk_height)).map { @data.getbyte }
|
221
|
+
yield width_in_bytes, chunk_height, bytes
|
222
|
+
row_start += 255
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
private
|
227
|
+
|
228
|
+
def set_source(source)
|
229
|
+
if source.respond_to?(:getbyte)
|
230
|
+
@data = source
|
231
|
+
else
|
232
|
+
@data = StringIO.new(source.map(&:chr).join)
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
def extract_width_and_height_from_data
|
237
|
+
tmp = @data.getbyte
|
238
|
+
@width = (@data.getbyte << 8) + tmp
|
239
|
+
tmp = @data.getbyte
|
240
|
+
@height = (@data.getbyte << 8) + tmp
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
def print_bitmap(*args)
|
245
|
+
bitmap = Bitmap.new(*args)
|
246
|
+
return if (bitmap.width > 384) # maximum width of the printer
|
247
|
+
bitmap.each_block do |w, h, bytes|
|
248
|
+
write_bytes(18, 42)
|
249
|
+
write_bytes(h, w)
|
250
|
+
write_bytes(*bytes)
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
# def print_bitmap(stream)
|
255
|
+
# tmp = stream.getbyte
|
256
|
+
# width = (stream.getbyte << 8) + tmp
|
257
|
+
#
|
258
|
+
# tmp = stream.getbyte
|
259
|
+
# height = (stream.getbyte << 8) + tmp
|
260
|
+
#
|
261
|
+
# print_bitmap(width, height, stream)
|
262
|
+
# end
|
263
|
+
|
264
|
+
# Barcodes
|
265
|
+
|
266
|
+
def set_barcode_height(val)
|
267
|
+
# default is 50
|
268
|
+
write_bytes(29, 104, val)
|
269
|
+
end
|
270
|
+
|
271
|
+
UPC_A = 0
|
272
|
+
UPC_E = 1
|
273
|
+
EAN13 = 2
|
274
|
+
EAN8 = 3
|
275
|
+
CODE39 = 4
|
276
|
+
I25 = 5
|
277
|
+
CODEBAR = 6
|
278
|
+
CODE93 = 7
|
279
|
+
CODE128 = 8
|
280
|
+
CODE11 = 9
|
281
|
+
MSI = 10
|
282
|
+
|
283
|
+
def print_barcode(text, type)
|
284
|
+
write_bytes(29, 107, type) # set the type first
|
285
|
+
text.bytes { |b| write(b) }
|
286
|
+
write(0) # Terminator
|
287
|
+
end
|
288
|
+
|
289
|
+
# Take the printer offline. Print commands sent after this will be
|
290
|
+
# ignored until `online` is called
|
291
|
+
def offline
|
292
|
+
write_bytes(27, 61, 0)
|
293
|
+
end
|
294
|
+
|
295
|
+
# Take the printer back online. Subsequent print commands will be
|
296
|
+
# obeyed.
|
297
|
+
def online
|
298
|
+
write_bytes(27, 61, 1)
|
299
|
+
end
|
300
|
+
|
301
|
+
# Put the printer into a low-energy state immediately
|
302
|
+
def sleep
|
303
|
+
sleep_after(0)
|
304
|
+
end
|
305
|
+
|
306
|
+
# Put the printer into a low-energy state after the given number
|
307
|
+
# of seconds
|
308
|
+
def sleep_after(seconds)
|
309
|
+
write_bytes(27, 56, seconds)
|
310
|
+
end
|
311
|
+
|
312
|
+
# Wake the printer from a low-energy state. This command will wait
|
313
|
+
# for 50ms (as directed by the datasheet) before allowing further
|
314
|
+
# commands to be send.
|
315
|
+
def wake
|
316
|
+
write_bytes(255)
|
317
|
+
# delay(50) # ?
|
318
|
+
end
|
319
|
+
|
320
|
+
# ==== not working? ====
|
321
|
+
def tab
|
322
|
+
write(9)
|
323
|
+
end
|
324
|
+
|
325
|
+
def set_char_spacing(spacing)
|
326
|
+
write_bytes(27, 32, 0, 10)
|
327
|
+
end
|
328
|
+
|
329
|
+
def set_line_height(val=32)
|
330
|
+
write_bytes(27, 51, val) # default is 32
|
331
|
+
end
|
332
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require "serialport"
|
2
|
+
|
3
|
+
class SerialConnection
|
4
|
+
def initialize(port=nil)
|
5
|
+
port_str = port || "/dev/tty.usbserial-FTF8DKJT"
|
6
|
+
baud_rate = 19200
|
7
|
+
data_bits = 8
|
8
|
+
stop_bits = 1
|
9
|
+
parity = SerialPort::NONE
|
10
|
+
@serial = SerialPort.new(port_str, baud_rate, data_bits, stop_bits, parity)
|
11
|
+
@serial.sync = true
|
12
|
+
end
|
13
|
+
|
14
|
+
def putc(byte)
|
15
|
+
@serial.putc(byte)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
@@ -0,0 +1,194 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
require "a2_printer"
|
3
|
+
|
4
|
+
describe A2Printer do
|
5
|
+
def sent_bytes
|
6
|
+
@test_connection.bytes
|
7
|
+
end
|
8
|
+
|
9
|
+
before do
|
10
|
+
@test_connection = TestConnection.new
|
11
|
+
@printer = A2Printer.new(@test_connection)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "can be reset" do
|
15
|
+
@printer.reset
|
16
|
+
sent_bytes.must_equal [27, 64]
|
17
|
+
end
|
18
|
+
|
19
|
+
it "prints a test page" do
|
20
|
+
@printer.test_page
|
21
|
+
sent_bytes.must_equal [18, 84]
|
22
|
+
end
|
23
|
+
|
24
|
+
it "can be flushed" do
|
25
|
+
@printer.flush
|
26
|
+
sent_bytes.must_equal [12]
|
27
|
+
end
|
28
|
+
|
29
|
+
it "can be set offline" do
|
30
|
+
@printer.offline
|
31
|
+
sent_bytes.must_equal [27, 61, 0]
|
32
|
+
end
|
33
|
+
|
34
|
+
it "can be set offline" do
|
35
|
+
@printer.online
|
36
|
+
sent_bytes.must_equal [27, 61, 1]
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "feeding" do
|
40
|
+
it "feeds a single line" do
|
41
|
+
@printer.feed
|
42
|
+
sent_bytes.must_equal [10]
|
43
|
+
end
|
44
|
+
|
45
|
+
it "feeds multiple lines" do
|
46
|
+
@printer.feed(3)
|
47
|
+
sent_bytes.must_equal [10, 10, 10]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "initializing" do
|
52
|
+
it "resets the print settings" do
|
53
|
+
@printer.begin(100)
|
54
|
+
sent_bytes.must_equal [
|
55
|
+
27, 64, # reset
|
56
|
+
27, 55, # start control parameter command
|
57
|
+
7, # dots
|
58
|
+
100, # heat time
|
59
|
+
50, # heat interval
|
60
|
+
18, 35, # start print density command
|
61
|
+
(15 << 4) | 15 # print density
|
62
|
+
]
|
63
|
+
end
|
64
|
+
|
65
|
+
it "sets the defaults" do
|
66
|
+
@printer.expects(:online)
|
67
|
+
@printer.expects(:justify).with(:left)
|
68
|
+
@printer.expects(:normal)
|
69
|
+
@printer.expects(:underline_off)
|
70
|
+
@printer.expects(:set_line_height).with(32)
|
71
|
+
@printer.set_default
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe "printing characters" do
|
76
|
+
it "sends the characters as bytes" do
|
77
|
+
@printer.print("hello")
|
78
|
+
sent_bytes.must_equal %w(h e l l o).map(&:ord)
|
79
|
+
end
|
80
|
+
|
81
|
+
it "sends a newline character when printing with println" do
|
82
|
+
@printer.println("hello")
|
83
|
+
sent_bytes.must_equal %w(h e l l o).map(&:ord) + [10]
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
describe "printing bitmaps" do
|
88
|
+
describe "shorter than 255 rows" do
|
89
|
+
before do
|
90
|
+
@printer.print_bitmap(width=8, height=8, [1,2,3,4,5,6,7,8])
|
91
|
+
end
|
92
|
+
|
93
|
+
it "writes the prefix" do
|
94
|
+
sent_bytes[0,2].must_equal [18, 42]
|
95
|
+
end
|
96
|
+
|
97
|
+
it "writes the number of rows of the bitmap" do
|
98
|
+
sent_bytes[2,1].must_equal [8]
|
99
|
+
end
|
100
|
+
|
101
|
+
it "writes the width of the bitmap in bytes" do
|
102
|
+
sent_bytes[3,1].must_equal [1]
|
103
|
+
end
|
104
|
+
|
105
|
+
it "writes the bitmap data" do
|
106
|
+
sent_bytes[4..-1].must_equal [1,2,3,4,5,6,7,8]
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
describe "longer than 255 rows" do
|
111
|
+
before do
|
112
|
+
@printer.print_bitmap(width=8, height=256, [3]*256)
|
113
|
+
end
|
114
|
+
|
115
|
+
it "writes the prefix" do
|
116
|
+
sent_bytes[0,2].must_equal [18, 42]
|
117
|
+
end
|
118
|
+
|
119
|
+
it "writes the number of rows of the first bitmap chunk" do
|
120
|
+
sent_bytes[2,1].must_equal [255]
|
121
|
+
end
|
122
|
+
|
123
|
+
it "writes the width of the bitmap in bytes" do
|
124
|
+
sent_bytes[3,1].must_equal [1]
|
125
|
+
end
|
126
|
+
|
127
|
+
it "writes the first chunk of bitmap data" do
|
128
|
+
sent_bytes[4,255].must_equal [3] * 255
|
129
|
+
end
|
130
|
+
|
131
|
+
it "writes the prefix a second time" do
|
132
|
+
sent_bytes[259,2].must_equal [18, 42]
|
133
|
+
end
|
134
|
+
|
135
|
+
it "writes the number of rows of the second bitmap chunk" do
|
136
|
+
sent_bytes[261,1].must_equal [1]
|
137
|
+
end
|
138
|
+
|
139
|
+
it "writes the width of the bitmap in bytes" do
|
140
|
+
sent_bytes[262,1].must_equal [1]
|
141
|
+
end
|
142
|
+
|
143
|
+
it "writes the second chunk of bitmap data" do
|
144
|
+
sent_bytes[263..-1].must_equal [3]
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
describe "from an IO object" do
|
149
|
+
before do
|
150
|
+
data = StringIO.new(([3]*8).map(&:chr).join)
|
151
|
+
@printer.print_bitmap(width=8, height=8, data)
|
152
|
+
end
|
153
|
+
|
154
|
+
it "writes the prefix" do
|
155
|
+
sent_bytes[0,2].must_equal [18, 42]
|
156
|
+
end
|
157
|
+
|
158
|
+
it "writes the number of rows of the bitmap" do
|
159
|
+
sent_bytes[2,1].must_equal [8]
|
160
|
+
end
|
161
|
+
|
162
|
+
it "writes the width of the bitmap in bytes" do
|
163
|
+
sent_bytes[3,1].must_equal [1]
|
164
|
+
end
|
165
|
+
|
166
|
+
it "writes the bitmap data" do
|
167
|
+
sent_bytes[4..-1].must_equal [3,3,3,3,3,3,3,3]
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
describe "where width and height aren't given" do
|
172
|
+
before do
|
173
|
+
data = StringIO.new(([8,0,8,0] + [3]*8).map(&:chr).join)
|
174
|
+
@printer.print_bitmap(data)
|
175
|
+
end
|
176
|
+
|
177
|
+
it "writes the prefix" do
|
178
|
+
sent_bytes[0,2].must_equal [18, 42]
|
179
|
+
end
|
180
|
+
|
181
|
+
it "writes the number of rows of the bitmap" do
|
182
|
+
sent_bytes[2,1].must_equal [8]
|
183
|
+
end
|
184
|
+
|
185
|
+
it "writes the width of the bitmap in bytes" do
|
186
|
+
sent_bytes[3,1].must_equal [1]
|
187
|
+
end
|
188
|
+
|
189
|
+
it "writes the bitmap data" do
|
190
|
+
sent_bytes[4..-1].must_equal [3,3,3,3,3,3,3,3]
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require "minitest/autorun"
|
2
|
+
require "rubygems"
|
3
|
+
require "bundler"
|
4
|
+
Bundler.require(:default, :test)
|
5
|
+
require "mocha"
|
6
|
+
|
7
|
+
$LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
|
8
|
+
|
9
|
+
class TestConnection
|
10
|
+
attr_reader :bytes
|
11
|
+
def initialize
|
12
|
+
@bytes = []
|
13
|
+
end
|
14
|
+
def putc(byte)
|
15
|
+
@bytes << byte
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
metadata
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: a2_printer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- James Adam
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-07-11 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: serialport
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 1.0.4
|
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: 1.0.4
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: mocha
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
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:
|
47
|
+
email: james@lazyatom.com
|
48
|
+
executables: []
|
49
|
+
extensions: []
|
50
|
+
extra_rdoc_files:
|
51
|
+
- README.md
|
52
|
+
files:
|
53
|
+
- README.md
|
54
|
+
- Gemfile
|
55
|
+
- test/a2_printer_test.rb
|
56
|
+
- test/test_helper.rb
|
57
|
+
- lib/a2_printer.rb
|
58
|
+
- lib/serial_connection.rb
|
59
|
+
homepage: http://lazyatom.com
|
60
|
+
licenses: []
|
61
|
+
post_install_message:
|
62
|
+
rdoc_options:
|
63
|
+
- --main
|
64
|
+
- README.md
|
65
|
+
require_paths:
|
66
|
+
- lib
|
67
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
68
|
+
none: false
|
69
|
+
requirements:
|
70
|
+
- - ! '>='
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: '0'
|
73
|
+
segments:
|
74
|
+
- 0
|
75
|
+
hash: 2772800540462270427
|
76
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
77
|
+
none: false
|
78
|
+
requirements:
|
79
|
+
- - ! '>='
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
segments:
|
83
|
+
- 0
|
84
|
+
hash: 2772800540462270427
|
85
|
+
requirements: []
|
86
|
+
rubyforge_project:
|
87
|
+
rubygems_version: 1.8.23
|
88
|
+
signing_key:
|
89
|
+
specification_version: 3
|
90
|
+
summary: Sending commands to a small thermal printer
|
91
|
+
test_files: []
|