@thermal-print/escpos 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.
- package/LICENSE +21 -0
- package/README.md +193 -0
- package/dist/command-adapters/escbematech-adapter.d.ts +30 -0
- package/dist/command-adapters/escbematech-adapter.d.ts.map +1 -0
- package/dist/command-adapters/escbematech-adapter.js +175 -0
- package/dist/command-adapters/escpos-adapter.d.ts +25 -0
- package/dist/command-adapters/escpos-adapter.d.ts.map +1 -0
- package/dist/command-adapters/escpos-adapter.js +144 -0
- package/dist/command-adapters/index.d.ts +11 -0
- package/dist/command-adapters/index.d.ts.map +1 -0
- package/dist/command-adapters/index.js +14 -0
- package/dist/command-adapters/types.d.ts +78 -0
- package/dist/command-adapters/types.d.ts.map +1 -0
- package/dist/command-adapters/types.js +8 -0
- package/dist/commands/escbematech.d.ts +867 -0
- package/dist/commands/escbematech.d.ts.map +1 -0
- package/dist/commands/escbematech.js +1387 -0
- package/dist/commands/escpos.d.ts +582 -0
- package/dist/commands/escpos.d.ts.map +1 -0
- package/dist/commands/escpos.js +1048 -0
- package/dist/converter.d.ts +47 -0
- package/dist/converter.d.ts.map +1 -0
- package/dist/converter.js +92 -0
- package/dist/encodings/cp860.d.ts +25 -0
- package/dist/encodings/cp860.d.ts.map +1 -0
- package/dist/encodings/cp860.js +187 -0
- package/dist/generator.d.ts +118 -0
- package/dist/generator.d.ts.map +1 -0
- package/dist/generator.js +383 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +55 -0
- package/dist/styles.d.ts +72 -0
- package/dist/styles.d.ts.map +1 -0
- package/dist/styles.js +210 -0
- package/dist/traverser.d.ts +60 -0
- package/dist/traverser.d.ts.map +1 -0
- package/dist/traverser.js +285 -0
- package/dist/types.d.ts +21 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/package.json +31 -0
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.ESCPOSGenerator = void 0;
|
|
37
|
+
const escpos_1 = require("./commands/escpos");
|
|
38
|
+
const styles_1 = require("./styles");
|
|
39
|
+
const command_adapters_1 = require("./command-adapters");
|
|
40
|
+
/**
|
|
41
|
+
* Simple buffer implementation for accumulating ESC/POS commands
|
|
42
|
+
*/
|
|
43
|
+
class ESCPOSBuffer {
|
|
44
|
+
constructor() {
|
|
45
|
+
this.buffer = [];
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Add raw bytes to buffer
|
|
49
|
+
*/
|
|
50
|
+
push(...bytes) {
|
|
51
|
+
this.buffer.push(...bytes);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Add array of bytes to buffer
|
|
55
|
+
*/
|
|
56
|
+
pushArray(bytes) {
|
|
57
|
+
this.buffer.push(...bytes);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Get the buffer as a Node.js Buffer
|
|
61
|
+
*/
|
|
62
|
+
toBuffer() {
|
|
63
|
+
return Buffer.from(this.buffer);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Get buffer size
|
|
67
|
+
*/
|
|
68
|
+
get size() {
|
|
69
|
+
return this.buffer.length;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* ESC/POS Command Generator
|
|
74
|
+
* Manages the buffer and context for generating ESC/POS commands
|
|
75
|
+
* Pure JavaScript implementation - no Node.js dependencies
|
|
76
|
+
*/
|
|
77
|
+
class ESCPOSGenerator {
|
|
78
|
+
constructor(paperWidth = 48, encoding = "cp860", debug = false, commandAdapter) {
|
|
79
|
+
this.buffer = new ESCPOSBuffer();
|
|
80
|
+
// Use provided adapter or default to ESC/POS
|
|
81
|
+
this.commandAdapter = commandAdapter || new command_adapters_1.ESCPOSCommandAdapter();
|
|
82
|
+
this.context = {
|
|
83
|
+
paperWidth,
|
|
84
|
+
currentAlign: "left",
|
|
85
|
+
currentSize: { width: 1, height: 1 },
|
|
86
|
+
currentBold: false,
|
|
87
|
+
encoding,
|
|
88
|
+
debug,
|
|
89
|
+
buffer: [],
|
|
90
|
+
};
|
|
91
|
+
// Initialize printer using command adapter
|
|
92
|
+
this.buffer.pushArray(this.commandAdapter.getInitCommand());
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Initialize printer
|
|
96
|
+
* Sets up the printer with default settings and comfortable line spacing
|
|
97
|
+
*/
|
|
98
|
+
initialize() {
|
|
99
|
+
// Initialize with comfortable line spacing (30 dots ≈ default 1/6 inch)
|
|
100
|
+
// Common values: 10 (tight), 20 (moderate), 30 (default), 40 (spacious)
|
|
101
|
+
this.setLineSpacing(5);
|
|
102
|
+
// Apply initial print mode to set Font B explicitly
|
|
103
|
+
// This ensures the narrower font (9×17) is used from the start
|
|
104
|
+
this.applyPrintMode();
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Set line spacing using command adapter
|
|
108
|
+
* @param dots - Line spacing in dots (0-255). Use 0 for minimal spacing, undefined for default (1/6 inch)
|
|
109
|
+
*/
|
|
110
|
+
setLineSpacing(dots) {
|
|
111
|
+
const command = this.commandAdapter.getLineSpacingCommand(dots);
|
|
112
|
+
this.buffer.pushArray(command);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Set text alignment using command adapter
|
|
116
|
+
*/
|
|
117
|
+
setAlign(align) {
|
|
118
|
+
if (this.context.currentAlign !== align) {
|
|
119
|
+
const command = this.commandAdapter.getAlignCommand(align);
|
|
120
|
+
this.buffer.pushArray(command);
|
|
121
|
+
this.context.currentAlign = align;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Set text bold
|
|
126
|
+
* Uses ESC ! command which combines size and emphasis
|
|
127
|
+
*/
|
|
128
|
+
setBold(bold) {
|
|
129
|
+
if (this.context.currentBold !== bold) {
|
|
130
|
+
this.context.currentBold = bold;
|
|
131
|
+
this.applyPrintMode();
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Set text size using width and height multipliers
|
|
136
|
+
* Uses ESC ! command which combines size and emphasis
|
|
137
|
+
* @param size - Character size as {width, height} multipliers (max 2x2 for ESC !)
|
|
138
|
+
*/
|
|
139
|
+
setSize(size) {
|
|
140
|
+
// Only update if size actually changed
|
|
141
|
+
if (this.context.currentSize.width !== size.width ||
|
|
142
|
+
this.context.currentSize.height !== size.height) {
|
|
143
|
+
this.context.currentSize = size;
|
|
144
|
+
this.applyPrintMode();
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Apply current print mode (size + bold) using command adapter
|
|
149
|
+
* This combines character size and emphasis into a single command
|
|
150
|
+
*/
|
|
151
|
+
applyPrintMode() {
|
|
152
|
+
const command = this.commandAdapter.getCharacterSizeCommand(this.context.currentSize.width, this.context.currentSize.height, this.context.currentBold);
|
|
153
|
+
this.buffer.pushArray(command);
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Reset text formatting to defaults
|
|
157
|
+
* Note: Alignment is NOT reset here because it should persist for the entire line
|
|
158
|
+
*/
|
|
159
|
+
resetFormatting() {
|
|
160
|
+
this.setAlign("left");
|
|
161
|
+
this.setBold(false);
|
|
162
|
+
this.setSize({ width: 1, height: 1 });
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Add text with current formatting
|
|
166
|
+
*/
|
|
167
|
+
addText(text) {
|
|
168
|
+
if (text) {
|
|
169
|
+
// Encode text to CP860 for Portuguese support
|
|
170
|
+
const encodedBytes = (0, escpos_1.encodeText)(text);
|
|
171
|
+
this.buffer.pushArray(encodedBytes);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Add newline using command adapter
|
|
176
|
+
*/
|
|
177
|
+
addNewline(count = 1) {
|
|
178
|
+
const command = this.commandAdapter.getLineFeedCommand(count);
|
|
179
|
+
this.buffer.pushArray(command);
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Add line feed using command adapter
|
|
183
|
+
*/
|
|
184
|
+
addLineFeed(lines = 1) {
|
|
185
|
+
const command = this.commandAdapter.getLineFeedCommand(lines);
|
|
186
|
+
this.buffer.pushArray(command);
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Add divider line
|
|
190
|
+
*/
|
|
191
|
+
addDivider(dashed = false) {
|
|
192
|
+
this.setAlign("left");
|
|
193
|
+
const line = (0, styles_1.generateDividerLine)(this.context.paperWidth, dashed);
|
|
194
|
+
this.addText(line);
|
|
195
|
+
this.addNewline();
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Add QR code using command adapter
|
|
199
|
+
*/
|
|
200
|
+
addQRCode(data, size = 6) {
|
|
201
|
+
try {
|
|
202
|
+
const command = this.commandAdapter.getQRCodeCommand(data, size);
|
|
203
|
+
if (command.length > 0) {
|
|
204
|
+
this.buffer.pushArray(command);
|
|
205
|
+
this.addNewline();
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
catch (error) {
|
|
209
|
+
// QR code generation failed - silently ignore
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Add image from base64 or data URI
|
|
214
|
+
* Converts image to monochrome bitmap and prints using ESC/POS raster graphics
|
|
215
|
+
* @param source - Base64 string, data URI, or object with uri property
|
|
216
|
+
*/
|
|
217
|
+
async addImage(source) {
|
|
218
|
+
try {
|
|
219
|
+
// Import Jimp dynamically to avoid loading if not needed
|
|
220
|
+
const { Jimp } = await Promise.resolve().then(() => __importStar(require("jimp")));
|
|
221
|
+
// Extract the actual data URI or base64 string
|
|
222
|
+
let imageSource;
|
|
223
|
+
if (typeof source === "string") {
|
|
224
|
+
imageSource = source;
|
|
225
|
+
}
|
|
226
|
+
else if (source && typeof source === "object" && "uri" in source) {
|
|
227
|
+
imageSource = source.uri;
|
|
228
|
+
}
|
|
229
|
+
else {
|
|
230
|
+
console.warn("Invalid image source format");
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
// Handle base64 strings (with or without data URI prefix)
|
|
234
|
+
let base64Data = imageSource;
|
|
235
|
+
if (imageSource.startsWith("data:")) {
|
|
236
|
+
// Extract base64 from data URI (e.g., "data:image/png;base64,...")
|
|
237
|
+
const base64Match = imageSource.match(/^data:image\/\w+;base64,(.+)$/);
|
|
238
|
+
if (base64Match) {
|
|
239
|
+
base64Data = base64Match[1];
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
// Convert base64 to buffer
|
|
243
|
+
const imageBuffer = Buffer.from(base64Data, "base64");
|
|
244
|
+
// Load image with Jimp (v1.x API)
|
|
245
|
+
const image = await Jimp.read(imageBuffer);
|
|
246
|
+
// Get paper width in pixels (assuming 8 dots per mm for 80mm thermal printer)
|
|
247
|
+
// Standard 80mm paper = ~576 pixels at 8 dots/mm (72 dpi)
|
|
248
|
+
// We'll use 384 pixels as max width (48 chars * 8 pixels per char)
|
|
249
|
+
const maxWidth = this.context.paperWidth * 8;
|
|
250
|
+
// Resize image to fit paper width while maintaining aspect ratio
|
|
251
|
+
if (image.width > maxWidth) {
|
|
252
|
+
await image.resize({ w: maxWidth });
|
|
253
|
+
}
|
|
254
|
+
// Convert to grayscale and apply threshold to create monochrome bitmap
|
|
255
|
+
await image
|
|
256
|
+
.greyscale()
|
|
257
|
+
.contrast(0.2) // Increase contrast for better print quality
|
|
258
|
+
.posterize(2); // Convert to 2-color (black and white)
|
|
259
|
+
const width = image.width;
|
|
260
|
+
const height = image.height;
|
|
261
|
+
// Convert image to monochrome bitmap data (1 bit per pixel)
|
|
262
|
+
const bytesPerLine = Math.ceil(width / 8);
|
|
263
|
+
const bitmapData = [];
|
|
264
|
+
for (let y = 0; y < height; y++) {
|
|
265
|
+
for (let x = 0; x < bytesPerLine; x++) {
|
|
266
|
+
let byte = 0;
|
|
267
|
+
for (let bit = 0; bit < 8; bit++) {
|
|
268
|
+
const pixelX = x * 8 + bit;
|
|
269
|
+
if (pixelX < width) {
|
|
270
|
+
const pixelIndex = (y * width + pixelX) * 4;
|
|
271
|
+
const pixel = image.bitmap.data[pixelIndex]; // Red channel (same for grayscale)
|
|
272
|
+
// If pixel is dark (< 128), set bit to 1 (black)
|
|
273
|
+
if (pixel < 128) {
|
|
274
|
+
byte |= 1 << (7 - bit);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
bitmapData.push(byte);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
// Generate and add raster image command using command adapter
|
|
282
|
+
const imageCommand = this.commandAdapter.getRasterImageCommand(bitmapData, width, height);
|
|
283
|
+
if (imageCommand.length > 0) {
|
|
284
|
+
this.buffer.pushArray(imageCommand);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
catch (error) {
|
|
288
|
+
console.warn("Failed to process image:", error);
|
|
289
|
+
// Silently fail - don't crash if image processing fails
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Apply text styles from style object
|
|
294
|
+
*/
|
|
295
|
+
applyTextStyle(style) {
|
|
296
|
+
const textStyle = (0, styles_1.extractTextStyle)(style);
|
|
297
|
+
// Set alignment
|
|
298
|
+
const align = (0, styles_1.mapTextAlign)(textStyle.textAlign);
|
|
299
|
+
this.setAlign(align);
|
|
300
|
+
// Set bold
|
|
301
|
+
const bold = (0, styles_1.isBold)(textStyle);
|
|
302
|
+
this.setBold(bold);
|
|
303
|
+
// Set size
|
|
304
|
+
const size = (0, styles_1.mapFontSizeToESCPOS)(textStyle.fontSize);
|
|
305
|
+
this.setSize(size);
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Apply spacing from view style
|
|
309
|
+
*/
|
|
310
|
+
applyViewSpacing(style, type) {
|
|
311
|
+
const viewStyle = (0, styles_1.extractViewStyle)(style);
|
|
312
|
+
if (type === "before") {
|
|
313
|
+
// Apply top border
|
|
314
|
+
if (viewStyle.borderTop) {
|
|
315
|
+
this.addDivider((0, styles_1.isDashedBorder)(viewStyle.borderTop));
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
else {
|
|
319
|
+
// Apply bottom border
|
|
320
|
+
if (viewStyle.borderBottom) {
|
|
321
|
+
this.addDivider((0, styles_1.isDashedBorder)(viewStyle.borderBottom));
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Cut paper with full cut using command adapter
|
|
327
|
+
*/
|
|
328
|
+
cutFull() {
|
|
329
|
+
const command = this.commandAdapter.getCutCommand("full");
|
|
330
|
+
this.buffer.pushArray(command);
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Cut paper with partial cut using command adapter
|
|
334
|
+
*/
|
|
335
|
+
cutPartial() {
|
|
336
|
+
const command = this.commandAdapter.getCutCommand("partial");
|
|
337
|
+
this.buffer.pushArray(command);
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Cut paper with feed then full cut using command adapter
|
|
341
|
+
* @param lines - Number of lines to feed before cutting (1-255)
|
|
342
|
+
*/
|
|
343
|
+
cutFullWithFeed(lines = 3) {
|
|
344
|
+
const feedCount = Math.max(1, Math.min(255, lines));
|
|
345
|
+
const command = this.commandAdapter.getCutCommand("full", feedCount);
|
|
346
|
+
this.buffer.pushArray(command);
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* Cut paper with feed then partial cut using command adapter
|
|
350
|
+
* @param lines - Number of lines to feed before cutting (1-255)
|
|
351
|
+
*/
|
|
352
|
+
cutPartialWithFeed(lines = 3) {
|
|
353
|
+
const feedCount = Math.max(1, Math.min(255, lines));
|
|
354
|
+
const command = this.commandAdapter.getCutCommand("partial", feedCount);
|
|
355
|
+
this.buffer.pushArray(command);
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Add raw ESC/POS command
|
|
359
|
+
* @param data - Raw buffer data to send to printer
|
|
360
|
+
*/
|
|
361
|
+
addRawCommand(data) {
|
|
362
|
+
this.buffer.pushArray(Array.from(data));
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* Get the final buffer
|
|
366
|
+
*/
|
|
367
|
+
getBuffer() {
|
|
368
|
+
const buffer = this.buffer.toBuffer();
|
|
369
|
+
// Remove leading line feeds (0x0A)
|
|
370
|
+
let start = 0;
|
|
371
|
+
while (start < buffer.length && buffer[start] === 0x0a) {
|
|
372
|
+
start++;
|
|
373
|
+
}
|
|
374
|
+
return buffer.slice(start);
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Get paper width
|
|
378
|
+
*/
|
|
379
|
+
getPaperWidth() {
|
|
380
|
+
return this.context.paperWidth;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
exports.ESCPOSGenerator = ESCPOSGenerator;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @thermal-print/escpos
|
|
3
|
+
*
|
|
4
|
+
* ESC/POS command generation and thermal printer control
|
|
5
|
+
*
|
|
6
|
+
* Main API: printNodesToESCPOS(printNode, options) -> Buffer
|
|
7
|
+
*/
|
|
8
|
+
export { printNodesToESCPOS, PrintNodeToESCPOSOptions } from './converter';
|
|
9
|
+
export { ESCPOSGenerator } from './generator';
|
|
10
|
+
export { TreeTraverser } from './traverser';
|
|
11
|
+
export { CommandAdapter, CharacterSize } from './command-adapters/types';
|
|
12
|
+
export { ESCPOSCommandAdapter } from './command-adapters/escpos-adapter';
|
|
13
|
+
export { ESCBematechCommandAdapter } from './command-adapters/escbematech-adapter';
|
|
14
|
+
export { extractTextStyle, extractViewStyle, isBold, mapFontSizeToESCPOS, mapTextAlign, calculateSpacing, isDashedBorder, generateDividerLine, mergeStyles, parseWidth, alignTextInColumn, wrapText, } from './styles';
|
|
15
|
+
export { encodeCP860 } from './encodings/cp860';
|
|
16
|
+
export * from './types';
|
|
17
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,kBAAkB,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAG3E,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG5C,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzE,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AACzE,OAAO,EAAE,yBAAyB,EAAE,MAAM,wCAAwC,CAAC;AAGnF,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,MAAM,EACN,mBAAmB,EACnB,YAAY,EACZ,gBAAgB,EAChB,cAAc,EACd,mBAAmB,EACnB,WAAW,EACX,UAAU,EACV,iBAAiB,EACjB,QAAQ,GACT,MAAM,UAAU,CAAC;AAGlB,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGhD,cAAc,SAAS,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @thermal-print/escpos
|
|
4
|
+
*
|
|
5
|
+
* ESC/POS command generation and thermal printer control
|
|
6
|
+
*
|
|
7
|
+
* Main API: printNodesToESCPOS(printNode, options) -> Buffer
|
|
8
|
+
*/
|
|
9
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
12
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
13
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
14
|
+
}
|
|
15
|
+
Object.defineProperty(o, k2, desc);
|
|
16
|
+
}) : (function(o, m, k, k2) {
|
|
17
|
+
if (k2 === undefined) k2 = k;
|
|
18
|
+
o[k2] = m[k];
|
|
19
|
+
}));
|
|
20
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
21
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
22
|
+
};
|
|
23
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
+
exports.encodeCP860 = exports.wrapText = exports.alignTextInColumn = exports.parseWidth = exports.mergeStyles = exports.generateDividerLine = exports.isDashedBorder = exports.calculateSpacing = exports.mapTextAlign = exports.mapFontSizeToESCPOS = exports.isBold = exports.extractViewStyle = exports.extractTextStyle = exports.ESCBematechCommandAdapter = exports.ESCPOSCommandAdapter = exports.TreeTraverser = exports.ESCPOSGenerator = exports.printNodesToESCPOS = void 0;
|
|
25
|
+
// Main conversion function
|
|
26
|
+
var converter_1 = require("./converter");
|
|
27
|
+
Object.defineProperty(exports, "printNodesToESCPOS", { enumerable: true, get: function () { return converter_1.printNodesToESCPOS; } });
|
|
28
|
+
// Core classes (for advanced usage)
|
|
29
|
+
var generator_1 = require("./generator");
|
|
30
|
+
Object.defineProperty(exports, "ESCPOSGenerator", { enumerable: true, get: function () { return generator_1.ESCPOSGenerator; } });
|
|
31
|
+
var traverser_1 = require("./traverser");
|
|
32
|
+
Object.defineProperty(exports, "TreeTraverser", { enumerable: true, get: function () { return traverser_1.TreeTraverser; } });
|
|
33
|
+
var escpos_adapter_1 = require("./command-adapters/escpos-adapter");
|
|
34
|
+
Object.defineProperty(exports, "ESCPOSCommandAdapter", { enumerable: true, get: function () { return escpos_adapter_1.ESCPOSCommandAdapter; } });
|
|
35
|
+
var escbematech_adapter_1 = require("./command-adapters/escbematech-adapter");
|
|
36
|
+
Object.defineProperty(exports, "ESCBematechCommandAdapter", { enumerable: true, get: function () { return escbematech_adapter_1.ESCBematechCommandAdapter; } });
|
|
37
|
+
// Style utilities
|
|
38
|
+
var styles_1 = require("./styles");
|
|
39
|
+
Object.defineProperty(exports, "extractTextStyle", { enumerable: true, get: function () { return styles_1.extractTextStyle; } });
|
|
40
|
+
Object.defineProperty(exports, "extractViewStyle", { enumerable: true, get: function () { return styles_1.extractViewStyle; } });
|
|
41
|
+
Object.defineProperty(exports, "isBold", { enumerable: true, get: function () { return styles_1.isBold; } });
|
|
42
|
+
Object.defineProperty(exports, "mapFontSizeToESCPOS", { enumerable: true, get: function () { return styles_1.mapFontSizeToESCPOS; } });
|
|
43
|
+
Object.defineProperty(exports, "mapTextAlign", { enumerable: true, get: function () { return styles_1.mapTextAlign; } });
|
|
44
|
+
Object.defineProperty(exports, "calculateSpacing", { enumerable: true, get: function () { return styles_1.calculateSpacing; } });
|
|
45
|
+
Object.defineProperty(exports, "isDashedBorder", { enumerable: true, get: function () { return styles_1.isDashedBorder; } });
|
|
46
|
+
Object.defineProperty(exports, "generateDividerLine", { enumerable: true, get: function () { return styles_1.generateDividerLine; } });
|
|
47
|
+
Object.defineProperty(exports, "mergeStyles", { enumerable: true, get: function () { return styles_1.mergeStyles; } });
|
|
48
|
+
Object.defineProperty(exports, "parseWidth", { enumerable: true, get: function () { return styles_1.parseWidth; } });
|
|
49
|
+
Object.defineProperty(exports, "alignTextInColumn", { enumerable: true, get: function () { return styles_1.alignTextInColumn; } });
|
|
50
|
+
Object.defineProperty(exports, "wrapText", { enumerable: true, get: function () { return styles_1.wrapText; } });
|
|
51
|
+
// Encodings
|
|
52
|
+
var cp860_1 = require("./encodings/cp860");
|
|
53
|
+
Object.defineProperty(exports, "encodeCP860", { enumerable: true, get: function () { return cp860_1.encodeCP860; } });
|
|
54
|
+
// Types
|
|
55
|
+
__exportStar(require("./types"), exports);
|
package/dist/styles.d.ts
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { TextStyle, ViewStyle } from "@thermal-print/core";
|
|
2
|
+
/**
|
|
3
|
+
* Extracts text style from a style object
|
|
4
|
+
*/
|
|
5
|
+
export declare function extractTextStyle(style: any): TextStyle;
|
|
6
|
+
/**
|
|
7
|
+
* Extracts view/layout style from a style object
|
|
8
|
+
*/
|
|
9
|
+
export declare function extractViewStyle(style: any): ViewStyle;
|
|
10
|
+
/**
|
|
11
|
+
* Determines if text should be bold
|
|
12
|
+
*/
|
|
13
|
+
export declare function isBold(style: TextStyle): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Maps fontSize to ESC/POS character size (width x height multipliers)
|
|
16
|
+
*
|
|
17
|
+
* Font size mapping using ESC ! command (limited to 2x2 maximum):
|
|
18
|
+
* - 8-12px → 1x1 (normal)
|
|
19
|
+
* - 13-18px → 1x2 (normal width, double height)
|
|
20
|
+
* - 19-24px → 2x1 (double width, normal height)
|
|
21
|
+
* - 25+px → 2x2 (double width, double height)
|
|
22
|
+
*
|
|
23
|
+
* Note: ESC ! command only supports up to 2x2 character size.
|
|
24
|
+
* Larger sizes (3x, 4x, etc.) would require GS ! command which may not
|
|
25
|
+
* be supported on all thermal printers (e.g., Bematech MP-4200 TH).
|
|
26
|
+
*
|
|
27
|
+
* PDF uses zoom factor (default 0.46), so actual sizes are smaller:
|
|
28
|
+
* - 16 * 0.46 = 7.36 (normal text)
|
|
29
|
+
* - 18 * 0.46 = 8.28 (medium text)
|
|
30
|
+
* - 20 * 0.46 = 9.2 (title text)
|
|
31
|
+
*
|
|
32
|
+
* We use raw fontSize values (ignoring zoom) for better differentiation
|
|
33
|
+
*/
|
|
34
|
+
export declare function mapFontSizeToESCPOS(fontSize?: number | string): {
|
|
35
|
+
width: number;
|
|
36
|
+
height: number;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Maps textAlign to ESC/POS alignment
|
|
40
|
+
*/
|
|
41
|
+
export declare function mapTextAlign(textAlign?: string): "left" | "center" | "right";
|
|
42
|
+
/**
|
|
43
|
+
* Calculates spacing (margin/padding) in lines
|
|
44
|
+
* Approximates pixels to line feeds
|
|
45
|
+
*/
|
|
46
|
+
export declare function calculateSpacing(value?: number): number;
|
|
47
|
+
/**
|
|
48
|
+
* Determines if a border is dashed
|
|
49
|
+
*/
|
|
50
|
+
export declare function isDashedBorder(border?: string): boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Generates a divider line based on border style
|
|
53
|
+
*/
|
|
54
|
+
export declare function generateDividerLine(width: number, dashed?: boolean): string;
|
|
55
|
+
/**
|
|
56
|
+
* Merges multiple style objects (handles spread syntax)
|
|
57
|
+
*/
|
|
58
|
+
export declare function mergeStyles(...styles: any[]): any;
|
|
59
|
+
/**
|
|
60
|
+
* Parses width percentage to column width in characters
|
|
61
|
+
* Uses Math.round() to minimize rounding errors
|
|
62
|
+
*/
|
|
63
|
+
export declare function parseWidth(width: string | number | undefined, totalWidth: number): number;
|
|
64
|
+
/**
|
|
65
|
+
* Aligns text within a column width (using CP860 byte length for accurate padding)
|
|
66
|
+
*/
|
|
67
|
+
export declare function alignTextInColumn(text: string, width: number, align: "left" | "center" | "right"): string;
|
|
68
|
+
/**
|
|
69
|
+
* Splits text into multiple lines if it exceeds width
|
|
70
|
+
*/
|
|
71
|
+
export declare function wrapText(text: string, width: number): string[];
|
|
72
|
+
//# sourceMappingURL=styles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../src/styles.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAE3D;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,GAAG,GAAG,SAAS,CAOtD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,GAAG,GAAG,SAAS,CAoBtD;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAOhD;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG;IAC/D,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB,CAcA;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,CAI5E;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAIvD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,UAAQ,GAAG,MAAM,CAGzE;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,MAAM,EAAE,GAAG,EAAE,GAAG,GAAG,CAEjD;AAED;;;GAGG;AACH,wBAAgB,UAAU,CACxB,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,EAClC,UAAU,EAAE,MAAM,GACjB,MAAM,CAaR;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,GACjC,MAAM,CA8BR;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAyB9D"}
|