@kreiseck/kasseneck-api 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/dist/cjs/pos/texte.d.ts +32 -0
  3. package/dist/cjs/pos/texte.js +16 -0
  4. package/dist/cjs/printing/code-tables.d.ts +77 -0
  5. package/dist/cjs/printing/code-tables.js +224 -0
  6. package/dist/cjs/printing/escpos.d.ts +19 -6
  7. package/dist/cjs/printing/escpos.js +27 -48
  8. package/dist/cjs/printing/index.d.ts +1 -0
  9. package/dist/cjs/printing/index.js +6 -1
  10. package/dist/cjs/printing/printable.d.ts +14 -2
  11. package/dist/cjs/printing/printable.js +36 -2
  12. package/dist/cjs/react/index.js +7 -0
  13. package/dist/cjs/receipt/blatt.d.ts +9 -0
  14. package/dist/cjs/receipt/code-table-reference-data.d.ts +6 -0
  15. package/dist/cjs/receipt/code-table-reference-data.js +11 -0
  16. package/dist/cjs/receipt/code-table-test-sheet.d.ts +52 -0
  17. package/dist/cjs/receipt/code-table-test-sheet.js +153 -0
  18. package/dist/cjs/receipt/index.d.ts +1 -0
  19. package/dist/cjs/receipt/index.js +6 -1
  20. package/dist/cjs/receipt/layout-escpos.d.ts +6 -1
  21. package/dist/cjs/receipt/layout-escpos.js +11 -7
  22. package/dist/cjs/version.d.ts +1 -1
  23. package/dist/cjs/version.js +1 -1
  24. package/dist/esm/pos/texte.d.ts +32 -0
  25. package/dist/esm/pos/texte.js +16 -0
  26. package/dist/esm/printing/code-tables.d.ts +77 -0
  27. package/dist/esm/printing/code-tables.js +215 -0
  28. package/dist/esm/printing/escpos.d.ts +19 -6
  29. package/dist/esm/printing/escpos.js +27 -48
  30. package/dist/esm/printing/index.d.ts +1 -0
  31. package/dist/esm/printing/index.js +1 -0
  32. package/dist/esm/printing/printable.d.ts +14 -2
  33. package/dist/esm/printing/printable.js +36 -2
  34. package/dist/esm/react/index.js +7 -0
  35. package/dist/esm/receipt/blatt.d.ts +9 -0
  36. package/dist/esm/receipt/code-table-reference-data.d.ts +6 -0
  37. package/dist/esm/receipt/code-table-reference-data.js +8 -0
  38. package/dist/esm/receipt/code-table-test-sheet.d.ts +52 -0
  39. package/dist/esm/receipt/code-table-test-sheet.js +147 -0
  40. package/dist/esm/receipt/index.d.ts +1 -0
  41. package/dist/esm/receipt/index.js +1 -0
  42. package/dist/esm/receipt/layout-escpos.d.ts +6 -1
  43. package/dist/esm/receipt/layout-escpos.js +11 -7
  44. package/dist/esm/version.d.ts +1 -1
  45. package/dist/esm/version.js +1 -1
  46. package/fixtures/code-table-receipts.json +84 -0
  47. package/fixtures/code-tables.json +12 -0
  48. package/fixtures/expected/code-table-receipt.long-item-name.iso8859_15.hex +27 -0
  49. package/fixtures/expected/code-table-receipt.long-item-name.pc437.hex +27 -0
  50. package/fixtures/expected/code-table-receipt.long-item-name.pc850.hex +27 -0
  51. package/fixtures/expected/code-table-receipt.long-item-name.pc858.hex +27 -0
  52. package/fixtures/expected/code-table-receipt.long-item-name.replacement.hex +27 -0
  53. package/fixtures/expected/code-table-receipt.long-item-name.wpc1252.hex +27 -0
  54. package/fixtures/expected/code-table-receipt.sale-cash.iso8859_15.hex +34 -0
  55. package/fixtures/expected/code-table-receipt.sale-cash.pc437.hex +34 -0
  56. package/fixtures/expected/code-table-receipt.sale-cash.pc850.hex +34 -0
  57. package/fixtures/expected/code-table-receipt.sale-cash.pc858.hex +34 -0
  58. package/fixtures/expected/code-table-receipt.sale-cash.replacement.hex +34 -0
  59. package/fixtures/expected/code-table-receipt.sale-cash.wpc1252.hex +34 -0
  60. package/fixtures/expected/code-table-receipt.special-characters.iso8859_15.hex +30 -0
  61. package/fixtures/expected/code-table-receipt.special-characters.pc437.hex +30 -0
  62. package/fixtures/expected/code-table-receipt.special-characters.pc850.hex +30 -0
  63. package/fixtures/expected/code-table-receipt.special-characters.pc858.hex +30 -0
  64. package/fixtures/expected/code-table-receipt.special-characters.replacement.hex +30 -0
  65. package/fixtures/expected/code-table-receipt.special-characters.wpc1252.hex +30 -0
  66. package/fixtures/expected/code-table-receipt.test-cashregister-sale.iso8859_15.hex +44 -0
  67. package/fixtures/expected/code-table-receipt.test-cashregister-sale.pc437.hex +44 -0
  68. package/fixtures/expected/code-table-receipt.test-cashregister-sale.pc850.hex +44 -0
  69. package/fixtures/expected/code-table-receipt.test-cashregister-sale.pc858.hex +44 -0
  70. package/fixtures/expected/code-table-receipt.test-cashregister-sale.replacement.hex +44 -0
  71. package/fixtures/expected/code-table-receipt.test-cashregister-sale.wpc1252.hex +44 -0
  72. package/fixtures/expected/code-table-test-sheet.lines.json +191 -0
  73. package/fixtures/expected/code-table-test-sheet.mm58.hex +59 -0
  74. package/fixtures/expected/code-table-test-sheet.mm80.hex +60 -0
  75. package/fixtures/hobex-hps-codes.json +1 -1
  76. package/fixtures/invoice-api.schema.json +1 -1
  77. package/fixtures/invoice-texts.json +1 -1
  78. package/fixtures/pos-texts.json +37 -1
  79. package/fixtures/surface.json +1 -1
  80. package/package.json +4 -2
@@ -18,6 +18,7 @@
18
18
  */
19
19
  Object.defineProperty(exports, "__esModule", { value: true });
20
20
  exports.escPosPrintableText = escPosPrintableText;
21
+ const code_tables_js_1 = require("./code-tables.js");
21
22
  /** Ersetzungen aus print_paper.dart, Schluessel sind Unicode-Codepunkte. */
22
23
  const ERSETZUNGEN = new Map([
23
24
  [0x2013, '-'], // – Halbgeviertstrich
@@ -66,12 +67,34 @@ function istEmojiOderNullbreite(codepunkt) {
66
67
  * Vor `escPosText`/`escPosRow` anwenden, wenn der Text aus fremder Hand kommt
67
68
  * (Artikelstamm, ERP-Uebernahme, Kundenname). `•` wird hier zu `*`, und der
68
69
  * Erzeuger sagt dasselbe — auch wer diese Funktion weglaesst, bekommt also
69
- * dasselbe Zeichen (siehe ZEICHEN_ERSATZ in escpos.ts).
70
+ * dasselbe Zeichen (siehe ZEICHEN_ERSATZ in code-tables.ts).
71
+ *
72
+ * Mit `codeTable` wird der Text fuer genau diese Tabelle fertig gemacht:
73
+ * - eine Tabelle des Katalogs (`CodeTableId`): `€` bleibt stehen, wenn die
74
+ * Tabelle es hat (der Drucker bekommt das echte Byte), sonst `EUR`; jedes
75
+ * der zehn Zeichen, das der Tabelle fehlt (`§` auf pc437, alle Umlaute auf
76
+ * `replacement` ...), wird schon hier zu seinen Ersatzbuchstaben. Danach
77
+ * ist jedes Zeichen genau ein Byte, und Spalten, die am Text gerechnet
78
+ * werden, stimmen auch am Papier.
79
+ * - `CP437` (alter Name): wie `pc437`, also `§` -> `Par.`.
80
+ * - ohne Angabe, `null` oder `CP1252`: genau wie bisher (Bons ohne gewaehlte
81
+ * Tabelle bleiben byte-gleich).
70
82
  */
71
- function escPosPrintableText(text) {
83
+ function escPosPrintableText(text, codeTable) {
84
+ const tabelle = tabelleFuerErsatz(codeTable);
85
+ const fehlend = tabelle === null ? [] : (0, code_tables_js_1.codeTableById)(tabelle).missing;
86
+ const echtesEuro = tabelle !== null && !fehlend.includes('€');
72
87
  let ergebnis = '';
73
88
  for (const zeichen of text) {
74
89
  const codepunkt = zeichen.codePointAt(0);
90
+ if (fehlend.includes(zeichen)) {
91
+ ergebnis += (0, code_tables_js_1.ersatzBuchstaben)(zeichen);
92
+ continue;
93
+ }
94
+ if (codepunkt === 0x20ac && echtesEuro) {
95
+ ergebnis += zeichen;
96
+ continue;
97
+ }
75
98
  const ersatz = ERSETZUNGEN.get(codepunkt);
76
99
  if (ersatz !== undefined) {
77
100
  ergebnis += ersatz;
@@ -88,3 +111,14 @@ function escPosPrintableText(text) {
88
111
  }
89
112
  return ergebnis;
90
113
  }
114
+ /**
115
+ * Tabelle, deren fehlende Zeichen schon am Text ersetzt werden. `null` heisst
116
+ * alter Weg ohne Aenderung (keine Wahl, `null`, `CP1252`).
117
+ */
118
+ function tabelleFuerErsatz(codeTable) {
119
+ if (codeTable === undefined || codeTable === null || codeTable === 'CP1252')
120
+ return null;
121
+ if (codeTable === 'CP437')
122
+ return 'pc437';
123
+ return codeTable;
124
+ }
@@ -96,6 +96,13 @@ function ReceiptSheetLines({ sheet: blatt, logoUrl, renderQr, qrHidden: qrVerdec
96
96
  return ((0, jsx_runtime_1.jsx)("div", { className: klasse, "data-zeichen": z, style: blattStil, children: blatt.blocks.map((b, i) => {
97
97
  switch (b.kind) {
98
98
  case 'line':
99
+ if (b.doubleSizeLead !== undefined && b.doubleSizeLead > 0) {
100
+ // Wie am Papier (`GS !` doppelt): die Nummernzelle in doppelter
101
+ // Schrift, die Zeile zwei Zeilen hoch, der Rest auf der Grundlinie.
102
+ // `ch` im Span misst die doppelte Schrift, darum die halbe Zahl.
103
+ const n = b.doubleSizeLead;
104
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "keck-blatt-zeile keck-blatt-zeile--gross", style: { display: 'flex', alignItems: 'flex-end', whiteSpace: 'pre', height: '4ch', overflow: 'hidden', fontWeight: b.bold ? 'bold' : 'normal' }, children: [(0, jsx_runtime_1.jsx)("span", { style: { fontSize: '2em', width: `${n / 2}ch`, lineHeight: '2ch', fontWeight: 'bold', textAlign: 'center', flex: 'none' }, children: b.text.slice(0, n).trim() }), (0, jsx_runtime_1.jsx)("span", { style: { lineHeight: '2ch' }, children: b.text.slice(n) })] }, i));
105
+ }
99
106
  return ((0, jsx_runtime_1.jsx)("div", { className: "keck-blatt-zeile", style: { whiteSpace: 'pre', height: '2ch', lineHeight: '2ch', overflow: 'hidden', fontWeight: b.bold ? 'bold' : 'normal' }, children: b.text }, i));
100
107
  case 'logo':
101
108
  return ((0, jsx_runtime_1.jsx)("div", { className: "keck-blatt-logo", style: { height: `${b.heightLines * 2}ch`, display: 'flex', justifyContent: 'center' }, children: logoUrl === undefined ? null : ((0, jsx_runtime_1.jsx)("img", { src: logoUrl, alt: "", "aria-hidden": "true", style: { width: `${b.widthFraction * z}ch`, height: `${b.heightLines * 2}ch`, objectFit: 'contain' } })) }, i));
@@ -40,6 +40,15 @@ export type SheetBlock = {
40
40
  readonly text: string;
41
41
  readonly bold: boolean;
42
42
  readonly blank: boolean;
43
+ /**
44
+ * Die ersten n Spalten sind EINE Zelle, deren Inhalt (ohne Leerraum)
45
+ * doppelt breit und doppelt hoch steht -- die Zeile ist dann zwei
46
+ * Zeilen hoch. Nur das Testblatt des Zeichensatzes setzt das (Nummern
47
+ * links); fehlt es, ist alles einfach gross. Ein Zeichner, der das Feld
48
+ * nicht kennt, zeigt die Zeile in einfacher Groesse, die Spalten
49
+ * bleiben dieselben.
50
+ */
51
+ readonly doubleSizeLead?: number;
43
52
  } | {
44
53
  readonly kind: 'logo';
45
54
  readonly widthFraction: number;
@@ -0,0 +1,6 @@
1
+ /** Die Vorlage-Zeile als Rasterbild: 384 x 24 Punkte, MSB zuerst, je Zeile auf volle Bytes aufgefuellt; base64. */
2
+ export declare const CODE_TABLE_REFERENCE_RASTER: {
3
+ readonly width: number;
4
+ readonly height: number;
5
+ readonly bits: string;
6
+ };
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ // Erzeugt von scripts/zeichensatz-vorlage.py -- nicht von Hand aendern.
3
+ // Schrift: Menlo Regular 20 px (sha256 dc256e0b39c2a6fec947129d421fef41b8b429f58f9b6e5d1b148c87f775c1f6), Schwelle 160.
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.CODE_TABLE_REFERENCE_RASTER = void 0;
6
+ /** Die Vorlage-Zeile als Rasterbild: 384 x 24 Punkte, MSB zuerst, je Zeile auf volle Bytes aufgefuellt; base64. */
7
+ exports.CODE_TABLE_REFERENCE_RASTER = {
8
+ width: 384,
9
+ height: 24,
10
+ bits: "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGYAAGYAAGYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGYAAGYAAGYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGYAAGYAAGYAABgAADwAAIEAAH4AAB8AAD4AADwAAAAAAAAAAAAAAAAAAAAAAAAAAGYAAGYAAGYAADwAAH4AAcOAAOcAAD8AAH4AAH4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADwAAMMAAcOAAMMAAHAAAGAAAEIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADwAAMMAAcOAAMMAAOAAAGAAAEIAAAAAAAAAAAAAAAAAAAAAAAAAAP4AAH4AAMMAAGYAAcOAAcOAAMwAAMAAAHAAAGYAAAAAAAAAAAAAAAAAAAAAAAAAAOcAAOcAAMMAAGYAAYGAAcOAANgAAfwAAHgAADwAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAMMAAMMAAGYAAYGAAcOAANgAAfwAAM4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAcOAAMMAAGcAAYGAAcOAANwAAMAAAMcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH8AAYGAAMMAAMMAAYGAAcOAAM4AAfgAAMMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAYGAAMMAAP8AAYGAAcOAAMcAA/gAAOMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcMAAYGAAMMAAP8AAcGAAcOAAMGAAMAAAHsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYMAAcOAAMMAAcOAAcOAAcOAAMGAAOAAAB4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYMAAMMAAMMAAYGAAMMAAMMAAMGAAGAAAAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAO8AAOcAAP8AAYGAAP8AAP8AAPOAAH8AAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAH4AAH8AA4HAAH4AAH4AAP8AAD8AAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
11
+ };
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Das Testblatt fuer den Zeichensatz: welche Code-Tabelle druckt auf diesem
3
+ * Drucker die Umlaute richtig?
4
+ *
5
+ * Oben steht die Vorlage-Zeile als Rasterbild -- ein Bild druckt jeder
6
+ * Drucker gleich, egal welche Tabelle er gerade hat. Darunter je Tabelle des
7
+ * Katalogs eine Zeile mit ihrer Nummer (gross), umgeschaltet mit `ESC t n`
8
+ * und mit den Bytes dieser Tabelle. Die erste Zeile, die aussieht wie die
9
+ * Vorlage, ist die richtige; Zeile 6 (Ersatzbuchstaben) passt immer.
10
+ *
11
+ * Bildschirm und Papier zeigen dasselbe Blatt: `codeTableTestSheet` liefert
12
+ * es im Zeilenmodell des Beleg-Blatts (`ReceiptSheet`), `codeTableTestSheetBytes`
13
+ * druckt genau diese Zeilen. Das Blatt hat immer 32 Spalten (58 mm); auf
14
+ * 80 mm steht der Block ueber den linken Rand (`GS L`) mittig.
15
+ *
16
+ * Gemeinsamer Prueffall mit dem Dart-Zwilling:
17
+ * `fixtures/expected/code-table-test-sheet.{mm58,mm80}.hex` und `.lines.json`.
18
+ */
19
+ import type { ReceiptSheet } from './blatt.js';
20
+ import { type CodeTable, type CodeTableId } from '../printing/code-tables.js';
21
+ import { type PosPaperSize, type RasterImage } from '../printing/escpos.js';
22
+ /** Spalten des Testblatts -- immer 58-mm-Format. */
23
+ export declare const CODE_TABLE_TEST_SHEET_CHARS = 32;
24
+ export interface CodeTableTestSheetInput {
25
+ /** Kassen-Kennung fuer die Kopfzeile (keine Personendaten). */
26
+ cashregisterLabel: string;
27
+ /** Zeitpunkt des Drucks; die Kopfzeile zeigt ihn in Wiener Zeit. */
28
+ time: Date;
29
+ /** Papier des Druckers; das Blatt bleibt 32 Spalten, auf 80 mm mittig. */
30
+ paper: PosPaperSize;
31
+ }
32
+ /** Eine Testzeile: Nummer, Tabelle und die Zeichen, die ihr fehlen (fuer „ohne €“ am Bildschirm). */
33
+ export interface CodeTableTestSheetRow {
34
+ readonly number: CodeTable['number'];
35
+ readonly codeTable: CodeTableId;
36
+ readonly missing: readonly string[];
37
+ }
38
+ /** Das Testblatt im Zeilenmodell des Beleg-Blatts, dazu die Testzeilen. */
39
+ export interface CodeTableTestSheet extends ReceiptSheet {
40
+ readonly rows: readonly CodeTableTestSheetRow[];
41
+ }
42
+ /** Die Vorlage-Zeile als Rasterbild (384 x 24 Punkte), wie sie am Papier steht. */
43
+ export declare function codeTableReferenceImage(): RasterImage;
44
+ /** Das Testblatt im Zeilenmodell des Beleg-Blatts -- dieselben Zeilen wie am Papier. */
45
+ export declare function codeTableTestSheet(options: CodeTableTestSheetInput): CodeTableTestSheet;
46
+ /**
47
+ * Das Testblatt als ESC/POS-Bytes. Jede Testzeile schaltet nach ihrer
48
+ * Nummer einmal mit `FS .` + `ESC t n` auf ihre Tabelle und traegt deren Bytes (`encodeForCodeTable`,
49
+ * also das echte €-Byte, wo die Tabelle es hat). Die Nummer steht doppelt
50
+ * breit und hoch (`GS !`), die Vorlage als Rasterbild (`GS v 0`).
51
+ */
52
+ export declare function codeTableTestSheetBytes(options: CodeTableTestSheetInput): Uint8Array;
@@ -0,0 +1,153 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CODE_TABLE_TEST_SHEET_CHARS = void 0;
4
+ exports.codeTableReferenceImage = codeTableReferenceImage;
5
+ exports.codeTableTestSheet = codeTableTestSheet;
6
+ exports.codeTableTestSheetBytes = codeTableTestSheetBytes;
7
+ const marke_js_1 = require("./marke.js");
8
+ const vienna_time_js_1 = require("../vienna-time.js");
9
+ const texte_js_1 = require("../pos/texte.js");
10
+ const code_tables_js_1 = require("../printing/code-tables.js");
11
+ const code_table_reference_data_js_1 = require("./code-table-reference-data.js");
12
+ const escpos_js_1 = require("../printing/escpos.js");
13
+ /** Spalten des Testblatts -- immer 58-mm-Format. */
14
+ exports.CODE_TABLE_TEST_SHEET_CHARS = 32;
15
+ /** Die zehn Zeichen der Vorlage, in der Reihenfolge des Katalogs. */
16
+ const VORLAGE = ['ä', 'ö', 'ü', 'Ä', 'Ö', 'Ü', 'ß', '€', '§', '°'];
17
+ /** Spalte des ersten Zeichens; danach jede zweite. Muss zu scripts/zeichensatz-vorlage.py passen. */
18
+ const ERSTE_SPALTE = 5;
19
+ /** Breite der Nummernzelle: eine Ziffer doppelt breit. */
20
+ const NUMMER_SPALTEN = 2;
21
+ const TRENNER = ' | ';
22
+ /** Punkte je Blatt-Zeile: 32 Zeichen zu 12 Punkten. */
23
+ const BLATT_PUNKTE = exports.CODE_TABLE_TEST_SHEET_CHARS * 12;
24
+ /** Linker Rand, der den 32-Spalten-Block auf 80 mm (576 Punkte) mittig setzt. */
25
+ const RAND_80 = (576 - BLATT_PUNKTE) / 2;
26
+ const GS = 0x1d;
27
+ const ESC = 0x1b;
28
+ /** `ESC t` der Vorgabe ohne gewaehlte Tabelle (WPC1252). */
29
+ const VORGABE_ESC_T = 16;
30
+ /** Die Vorlage-Zeile als Rasterbild (384 x 24 Punkte), wie sie am Papier steht. */
31
+ function codeTableReferenceImage() {
32
+ const r = code_table_reference_data_js_1.CODE_TABLE_REFERENCE_RASTER;
33
+ return (0, marke_js_1.entpackeRasterBits)(r.bits, r.width, r.height);
34
+ }
35
+ /** Text in reines ASCII (Ersatzbuchstaben): steht auf jedem Drucker gleich, egal welche Tabelle gilt. */
36
+ function nurAscii(text) {
37
+ return String.fromCharCode(...(0, code_tables_js_1.encodeForCodeTable)(text, 'replacement'));
38
+ }
39
+ function zeile(text, bold = false, ausrichtung = 'left') {
40
+ const rest = exports.CODE_TABLE_TEST_SHEET_CHARS - text.length;
41
+ const links = ausrichtung === 'center' ? Math.floor(rest / 2) : 0;
42
+ return { kind: 'line', text: ' '.repeat(links) + text + ' '.repeat(rest - links), bold, blank: false };
43
+ }
44
+ function zeilen(text, bold = false, ausrichtung = 'left') {
45
+ return (0, escpos_js_1.wrapText)(nurAscii(text), exports.CODE_TABLE_TEST_SHEET_CHARS).map((t) => zeile(t, bold, ausrichtung));
46
+ }
47
+ /** Die Zeichen einer Tabelle an ihren Spalten; ein fehlendes Zeichen laesst seine Luecke. */
48
+ function zeichenDerTabelle(tabelle) {
49
+ return VORLAGE.map((z) => (tabelle.missing.includes(z) ? ' ' : z)).join(' ').trimEnd();
50
+ }
51
+ function nummernZeile(nummer, text) {
52
+ const kopf = String(nummer).padStart(NUMMER_SPALTEN, ' ') + TRENNER;
53
+ return { ...zeile(kopf + text), doubleSizeLead: NUMMER_SPALTEN };
54
+ }
55
+ const zweistellig = (n) => String(n).padStart(2, '0');
56
+ /** Das Testblatt im Zeilenmodell des Beleg-Blatts -- dieselben Zeilen wie am Papier. */
57
+ function codeTableTestSheet(options) {
58
+ return blattBauen(options).blatt;
59
+ }
60
+ /**
61
+ * Baut das Blatt und merkt sich dabei, welcher Block die Vorlage-Zeile ist.
62
+ * Die Bytes suchen sie nicht am Text (der ist `nurAscii` und kann sich
63
+ * aendern), sondern nehmen genau diese Stelle.
64
+ */
65
+ function blattBauen(options) {
66
+ const z = exports.CODE_TABLE_TEST_SHEET_CHARS;
67
+ const uhr = (0, vienna_time_js_1.toViennaWallClock)(options.time);
68
+ const zeit = `${zweistellig(uhr.day)}.${zweistellig(uhr.month)}. ${zweistellig(uhr.hour)}:${zweistellig(uhr.minute)}`;
69
+ const doppelt = zeile('='.repeat(z));
70
+ const einfach = zeile('-'.repeat(z));
71
+ const einzug = ' '.repeat(ERSTE_SPALTE);
72
+ const bloecke = [
73
+ doppelt,
74
+ ...zeilen((0, texte_js_1.labelText)('codetable.title'), true, 'center'),
75
+ ...zeilen(`${options.cashregisterLabel.trim()} ${zeit}`, false, 'center'),
76
+ doppelt,
77
+ ...zeilen((0, texte_js_1.labelText)('codetable.reference')),
78
+ ];
79
+ // Am Papier ein Bild (`codeTableReferenceImage`), am Bildschirm Text.
80
+ const vorlage = bloecke.length;
81
+ bloecke.push(zeile(einzug + VORLAGE.join(' ')), einfach);
82
+ const ersatz = code_tables_js_1.CODE_TABLES.find((t) => t.id === 'replacement');
83
+ for (const t of code_tables_js_1.CODE_TABLES) {
84
+ if (t === ersatz)
85
+ continue;
86
+ bloecke.push(nummernZeile(t.number, zeichenDerTabelle(t)));
87
+ }
88
+ bloecke.push(einfach);
89
+ const ersatzText = String.fromCharCode(...(0, code_tables_js_1.encodeForCodeTable)(VORLAGE.join(' '), 'replacement'));
90
+ const [ersteErsatz = '', ...restErsatz] = (0, escpos_js_1.wrapText)(ersatzText, z - ERSTE_SPALTE);
91
+ bloecke.push(nummernZeile(ersatz.number, ersteErsatz));
92
+ for (const t of restErsatz)
93
+ bloecke.push(zeile(einzug + t));
94
+ bloecke.push(zeile(einzug + nurAscii((0, texte_js_1.labelText)('codetable.replacement_note'))));
95
+ bloecke.push(doppelt);
96
+ bloecke.push(...zeilen((0, texte_js_1.messageText)('codetable.instruction')));
97
+ bloecke.push(doppelt);
98
+ return {
99
+ blatt: {
100
+ charsPerLine: z,
101
+ blocks: bloecke,
102
+ rows: code_tables_js_1.CODE_TABLES.map((t) => ({ number: t.number, codeTable: t.id, missing: t.missing })),
103
+ },
104
+ vorlage,
105
+ };
106
+ }
107
+ /**
108
+ * Das Testblatt als ESC/POS-Bytes. Jede Testzeile schaltet nach ihrer
109
+ * Nummer einmal mit `FS .` + `ESC t n` auf ihre Tabelle und traegt deren Bytes (`encodeForCodeTable`,
110
+ * also das echte €-Byte, wo die Tabelle es hat). Die Nummer steht doppelt
111
+ * breit und hoch (`GS !`), die Vorlage als Rasterbild (`GS v 0`).
112
+ */
113
+ function codeTableTestSheetBytes(options) {
114
+ const { blatt, vorlage: vorlageIndex } = blattBauen(options);
115
+ const vorlage = blatt.blocks[vorlageIndex];
116
+ if (vorlage === undefined || vorlage.kind !== 'line')
117
+ throw new Error(`Testblatt: Vorlage-Zeile fehlt (Block ${vorlageIndex})`);
118
+ // Das Dokument ist immer 58 mm: 32 Spalten, Druckbereich 384 Punkte.
119
+ const doc = (0, escpos_js_1.createEscPosDocument)({ paperSize: 'mm58', codeTable: null });
120
+ (0, escpos_js_1.escPosReset)(doc);
121
+ if (options.paper === 'mm80')
122
+ doc.bytes.push(GS, 0x4c, RAND_80 & 0xff, RAND_80 >> 8);
123
+ let tabellen = 0;
124
+ for (const block of blatt.blocks) {
125
+ if (block.kind !== 'line')
126
+ continue;
127
+ if (block === vorlage) {
128
+ (0, escpos_js_1.escPosRasterImage)(doc, codeTableReferenceImage(), { align: 'left' });
129
+ continue;
130
+ }
131
+ if (block.doubleSizeLead === undefined) {
132
+ (0, escpos_js_1.escPosText)(doc, block.text.trimEnd(), { styles: { align: 'left', bold: block.bold } });
133
+ continue;
134
+ }
135
+ const tabelle = blatt.rows[tabellen];
136
+ tabellen += 1;
137
+ const nummer = block.text.slice(0, block.doubleSizeLead).trim();
138
+ // Die Ziffer ist ASCII und steht in jeder Tabelle gleich: keine Umschaltung
139
+ // davor, die Zeile schaltet genau einmal, vor ihren eigenen Bytes.
140
+ (0, escpos_js_1.escPosSetStyles)(doc, { align: 'left', bold: true, width: 2, height: 2 });
141
+ doc.bytes.push(...(0, code_tables_js_1.encodeForCodeTable)(nummer, 'replacement'));
142
+ (0, escpos_js_1.escPosSetStyles)(doc, { align: 'left', codeTable: tabelle.codeTable });
143
+ doc.bytes.push(...(0, code_tables_js_1.encodeForCodeTable)(block.text.slice(block.doubleSizeLead).trimEnd(), tabelle.codeTable), 0x0a);
144
+ }
145
+ // Endzustand wie ohne Wahl: Tabelle 16 (WPC1252) und auf 80 mm Rand 0.
146
+ // Ein Druck danach ohne `ESC @` steht sonst in der Tabelle der letzten
147
+ // Testzeile und um den Rand verschoben.
148
+ doc.bytes.push(ESC, 0x74, VORGABE_ESC_T);
149
+ if (options.paper === 'mm80')
150
+ doc.bytes.push(GS, 0x4c, 0, 0);
151
+ (0, escpos_js_1.escPosCut)(doc, 'full');
152
+ return (0, escpos_js_1.escPosBytes)(doc);
153
+ }
@@ -6,4 +6,5 @@ export { type SheetLogoSize, type SheetLogo, type LogoDimensions, type SheetBloc
6
6
  export { rasterizeLogo } from './bild.js';
7
7
  export { type BrandMarkRaster, BRAND_MARK_RASTERS, BRAND_MARK_PATHS } from './marke-daten.js';
8
8
  export { brandMarkImage } from './marke.js';
9
+ export { type CodeTableTestSheetInput, type CodeTableTestSheetRow, type CodeTableTestSheet, CODE_TABLE_TEST_SHEET_CHARS, codeTableTestSheet, codeTableTestSheetBytes, codeTableReferenceImage, } from './code-table-test-sheet.js';
9
10
  export { type ReceiptDueTip, type ReceiptDueTipRecipient, type ReceiptDueOptions, type ReceiptDueBuckets, type ReceiptDueBreakdown, type ReceiptDueErrorReason, receiptDueCents, receiptDueBreakdown, ReceiptDueError, RECEIPT_DUE_ERROR_REASONS, isReceiptDueError, } from './due.js';
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isReceiptDueError = exports.RECEIPT_DUE_ERROR_REASONS = exports.ReceiptDueError = exports.receiptDueBreakdown = exports.receiptDueCents = exports.brandMarkImage = exports.BRAND_MARK_PATHS = exports.BRAND_MARK_RASTERS = exports.rasterizeLogo = exports.receiptSheet = exports.qrSheetWidthFraction = exports.logoRasterSize = exports.isLogoPixelSizeAllowed = exports.logoDimensions = exports.paperSizeForChars = exports.DOTS_PER_LINE = exports.DOTS_PER_CHAR = exports.LOGO_MAX_PIXELS = exports.SHEET_LOGO_SIZES = exports.eposDirectStatus = exports.eposDirectPrint = exports.eposParseResponse = exports.eposSoapEnvelope = exports.eposServiceUrl = exports.eposImageXml = exports.eposXmlEscape = exports.eposPrintXmlResult = exports.eposPrintXml = exports.EposConnectionError = exports.CHARS_PER_PAPER_SIZE = exports.gridToText = exports.gridColumnWidths = exports.renderReceiptGrid = exports.escPosLayoutResult = exports.escPosLayoutBytes = exports.assertLogoRaster = exports.formatCents = exports.SMALL_BUSINESS_NOTICE = exports.CURRENT_LAYOUT_RULESET = exports.receiptZdaText = exports.receiptIsSmallBusinessConsistent = exports.receiptAmountsAreZero = exports.receiptIsZero = exports.receiptSignatureIsTest = exports.receiptSignatureFailed = exports.buildReceiptLayout = void 0;
3
+ exports.isReceiptDueError = exports.RECEIPT_DUE_ERROR_REASONS = exports.ReceiptDueError = exports.receiptDueBreakdown = exports.receiptDueCents = exports.codeTableReferenceImage = exports.codeTableTestSheetBytes = exports.codeTableTestSheet = exports.CODE_TABLE_TEST_SHEET_CHARS = exports.brandMarkImage = exports.BRAND_MARK_PATHS = exports.BRAND_MARK_RASTERS = exports.rasterizeLogo = exports.receiptSheet = exports.qrSheetWidthFraction = exports.logoRasterSize = exports.isLogoPixelSizeAllowed = exports.logoDimensions = exports.paperSizeForChars = exports.DOTS_PER_LINE = exports.DOTS_PER_CHAR = exports.LOGO_MAX_PIXELS = exports.SHEET_LOGO_SIZES = exports.eposDirectStatus = exports.eposDirectPrint = exports.eposParseResponse = exports.eposSoapEnvelope = exports.eposServiceUrl = exports.eposImageXml = exports.eposXmlEscape = exports.eposPrintXmlResult = exports.eposPrintXml = exports.EposConnectionError = exports.CHARS_PER_PAPER_SIZE = exports.gridToText = exports.gridColumnWidths = exports.renderReceiptGrid = exports.escPosLayoutResult = exports.escPosLayoutBytes = exports.assertLogoRaster = exports.formatCents = exports.SMALL_BUSINESS_NOTICE = exports.CURRENT_LAYOUT_RULESET = exports.receiptZdaText = exports.receiptIsSmallBusinessConsistent = exports.receiptAmountsAreZero = exports.receiptIsZero = exports.receiptSignatureIsTest = exports.receiptSignatureFailed = exports.buildReceiptLayout = void 0;
4
4
  var layout_js_1 = require("./layout.js");
5
5
  Object.defineProperty(exports, "buildReceiptLayout", { enumerable: true, get: function () { return layout_js_1.buildReceiptLayout; } });
6
6
  Object.defineProperty(exports, "receiptSignatureFailed", { enumerable: true, get: function () { return layout_js_1.receiptSignatureFailed; } });
@@ -50,6 +50,11 @@ Object.defineProperty(exports, "BRAND_MARK_RASTERS", { enumerable: true, get: fu
50
50
  Object.defineProperty(exports, "BRAND_MARK_PATHS", { enumerable: true, get: function () { return marke_daten_js_1.BRAND_MARK_PATHS; } });
51
51
  var marke_js_1 = require("./marke.js");
52
52
  Object.defineProperty(exports, "brandMarkImage", { enumerable: true, get: function () { return marke_js_1.brandMarkImage; } });
53
+ var code_table_test_sheet_js_1 = require("./code-table-test-sheet.js");
54
+ Object.defineProperty(exports, "CODE_TABLE_TEST_SHEET_CHARS", { enumerable: true, get: function () { return code_table_test_sheet_js_1.CODE_TABLE_TEST_SHEET_CHARS; } });
55
+ Object.defineProperty(exports, "codeTableTestSheet", { enumerable: true, get: function () { return code_table_test_sheet_js_1.codeTableTestSheet; } });
56
+ Object.defineProperty(exports, "codeTableTestSheetBytes", { enumerable: true, get: function () { return code_table_test_sheet_js_1.codeTableTestSheetBytes; } });
57
+ Object.defineProperty(exports, "codeTableReferenceImage", { enumerable: true, get: function () { return code_table_test_sheet_js_1.codeTableReferenceImage; } });
53
58
  var due_js_1 = require("./due.js");
54
59
  Object.defineProperty(exports, "receiptDueCents", { enumerable: true, get: function () { return due_js_1.receiptDueCents; } });
55
60
  Object.defineProperty(exports, "receiptDueBreakdown", { enumerable: true, get: function () { return due_js_1.receiptDueBreakdown; } });
@@ -55,7 +55,12 @@ export declare function blattFuerDruck(layout: ReceiptLayout, optionen: {
55
55
  export interface EscPosLayoutOptions {
56
56
  /** Papierbreite; Vorgabe ist die des Layouts (dessen Spaltenbreiten daran haengen). */
57
57
  paperSize?: PosPaperSize;
58
- /** Codepage des Druckers, Vorgabe `CP1252`; `null` laesst die des Geraets stehen. */
58
+ /**
59
+ * Codepage des Druckers, Vorgabe `CP1252`; `null` laesst die des Geraets
60
+ * stehen. Eine Tabelle des Katalogs (`CodeTableId`, im Drucker-Wizard
61
+ * gewaehlt) druckt `€`, `§`, `°` als echtes Byte, wo die Tabelle sie hat,
62
+ * sonst als Ersatzbuchstaben; ohne Wahl bleibt der Bon byte-gleich.
63
+ */
59
64
  codeTable?: PosCodeTable | null;
60
65
  /** Papierschnitt am Ende: `true` (voll), `'partial'` oder `false`. Vorgabe `true`. */
61
66
  cut?: boolean | PosCutMode;
@@ -40,17 +40,21 @@ function blattFuerDruck(layout, optionen) {
40
40
  /**
41
41
  * Druckbar gemachtes Layout: Texte durch [escPosPrintableText] (Codepage,
42
42
  * "EUR" statt "€", Striche), damit das Raster mit den Zeichen rechnet, die
43
- * wirklich aufs Papier gehen. Der QR-Inhalt bleibt unveraendert.
43
+ * wirklich aufs Papier gehen. Mit gewaehlter Tabelle bleibt "€", wo die
44
+ * Tabelle es hat, und fehlende Zeichen werden schon hier zu
45
+ * Ersatzbuchstaben: jedes Zeichen ist danach genau ein Byte. Der QR-Inhalt
46
+ * bleibt unveraendert.
44
47
  */
45
- function druckbaresLayout(layout) {
48
+ function druckbaresLayout(layout, codeTable) {
49
+ const druckbar = (text) => (0, index_js_1.escPosPrintableText)(text, codeTable);
46
50
  return {
47
51
  ...layout,
48
52
  lines: layout.lines.map((z) => {
49
53
  switch (z.kind) {
50
- case 'text': return { ...z, text: (0, index_js_1.escPosPrintableText)(z.text) };
51
- case 'banner': return { ...z, text: (0, index_js_1.escPosPrintableText)(z.text) };
52
- case 'columns': return { ...z, columns: z.columns.map((c) => ({ ...c, text: (0, index_js_1.escPosPrintableText)(c.text) })) };
53
- case 'rule': return { ...z, char: (0, index_js_1.escPosPrintableText)(z.char) || '-' };
54
+ case 'text': return { ...z, text: druckbar(z.text) };
55
+ case 'banner': return { ...z, text: druckbar(z.text) };
56
+ case 'columns': return { ...z, columns: z.columns.map((c) => ({ ...c, text: druckbar(c.text) })) };
57
+ case 'rule': return { ...z, char: druckbar(z.char) || '-' };
54
58
  default: return z;
55
59
  }
56
60
  }),
@@ -140,7 +144,7 @@ function escPosLayoutResult(layout, options = {}) {
140
144
  };
141
145
  // `blattFuerDruck` prueft das Logo-Raster bereits VOR der Rueckgabe -- die
142
146
  // Schleife unten schreibt darum nie ein Byte auf ein falsch grosses Logo.
143
- const blatt = blattFuerDruck(druckbaresLayout(layout), {
147
+ const blatt = blattFuerDruck(druckbaresLayout(layout, options.codeTable), {
144
148
  zeichen: grid_js_1.CHARS_PER_PAPER_SIZE[paperSize],
145
149
  logo: options.logo,
146
150
  marke: options.brandMark,
@@ -4,4 +4,4 @@
4
4
  * Client-Version, Nachtrag §6). Ein Test haelt sie gleich mit `package.json`;
5
5
  * beim Anheben der Version beide Stellen aendern.
6
6
  */
7
- export declare const PACKAGE_VERSION = "1.0.0";
7
+ export declare const PACKAGE_VERSION = "1.1.0";
@@ -7,4 +7,4 @@ exports.PACKAGE_VERSION = void 0;
7
7
  * Client-Version, Nachtrag §6). Ein Test haelt sie gleich mit `package.json`;
8
8
  * beim Anheben der Version beide Stellen aendern.
9
9
  */
10
- exports.PACKAGE_VERSION = '1.0.0';
10
+ exports.PACKAGE_VERSION = '1.1.0';
@@ -469,6 +469,12 @@ declare const MELDUNGEN_ROH: {
469
469
  readonly 'print.wizard_cancelled': {
470
470
  readonly text: "Nichts gespeichert.";
471
471
  };
472
+ readonly 'codetable.question': {
473
+ readonly text: "Welche Zeile sieht auf dem Papier aus wie oben?";
474
+ };
475
+ readonly 'codetable.instruction': {
476
+ readonly text: "Die Nummer der ersten Zeile, die genau wie oben aussieht, in der Kasse antippen.";
477
+ };
472
478
  readonly 'bluetooth.off': {
473
479
  readonly text: "Bluetooth ist ausgeschaltet. Bitte einschalten und erneut suchen.";
474
480
  readonly only: readonly ["app"];
@@ -964,6 +970,32 @@ declare const BESCHRIFTUNGEN_ROH: {
964
970
  readonly 'cancellation.difference': {
965
971
  readonly text: "Differenz";
966
972
  };
973
+ readonly 'codetable.title': {
974
+ readonly text: "ZEICHENSATZ-TEST";
975
+ };
976
+ readonly 'codetable.reference': {
977
+ readonly text: "So muss jede Zeile aussehen:";
978
+ };
979
+ readonly 'codetable.replacement_note': {
980
+ readonly text: "(Ersatz, passt immer)";
981
+ };
982
+ readonly 'codetable.missing': {
983
+ readonly text: "ohne {chars}";
984
+ readonly placeholders: readonly ["chars"];
985
+ };
986
+ readonly 'codetable.print_again': {
987
+ readonly text: "Nochmal drucken";
988
+ };
989
+ readonly 'codetable.not_checked': {
990
+ readonly text: "Umlaute noch nicht geprüft";
991
+ };
992
+ readonly 'codetable.check': {
993
+ readonly text: "Umlaute prüfen";
994
+ };
995
+ readonly 'codetable.current': {
996
+ readonly text: "Zeichensatz: Nr. {number}";
997
+ readonly placeholders: readonly ["number"];
998
+ };
967
999
  };
968
1000
  export type LabelKey = keyof typeof BESCHRIFTUNGEN_ROH;
969
1001
  export declare const LABELS: Record<LabelKey, TextEntry>;
@@ -245,6 +245,10 @@ const MELDUNGEN_ROH = {
245
245
  // Abbrechen an jeder Stelle: nichts gespeichert. Der Satz sagt genau das,
246
246
  // damit niemand einen halb eingerichteten Drucker vermutet.
247
247
  'print.wizard_cancelled': { text: 'Nichts gespeichert.' },
248
+ // Zeichensatz-Test im Drucker-Wizard: das Testblatt nennt die Anleitung,
249
+ // der Bildschirm stellt die Frage daneben.
250
+ 'codetable.question': { text: 'Welche Zeile sieht auf dem Papier aus wie oben?' },
251
+ 'codetable.instruction': { text: 'Die Nummer der ersten Zeile, die genau wie oben aussieht, in der Kasse antippen.' },
248
252
  'bluetooth.off': { text: 'Bluetooth ist ausgeschaltet. Bitte einschalten und erneut suchen.', only: ['app'] },
249
253
  'bluetooth.permission_missing': { text: 'Bitte die Freigabe in den Geräte-Einstellungen erteilen.', only: ['app'] },
250
254
  'bluetooth.search_failed': { text: 'Die Suche ist fehlgeschlagen: {reason}', placeholders: ['reason'], only: ['app'] },
@@ -556,6 +560,18 @@ const BESCHRIFTUNGEN_ROH = {
556
560
  'cancellation.all_cash': { text: 'Alles bar' },
557
561
  'cancellation.payment_remainder': { text: 'Rest {amount}', placeholders: ['amount'] },
558
562
  'cancellation.difference': { text: 'Differenz' },
563
+ // --- Zeichensatz-Test (Testblatt und Drucker & Lade) ----------------------
564
+ // Das Testblatt druckt diese Texte; sie bleiben reines ASCII bis auf die
565
+ // Knoepfe am Bildschirm. `{chars}` sind die fehlenden Zeichen einer Zeile
566
+ // („€“ bzw. „€ §“), `{number}` die gewaehlte Zeile (1-6).
567
+ 'codetable.title': { text: 'ZEICHENSATZ-TEST' },
568
+ 'codetable.reference': { text: 'So muss jede Zeile aussehen:' },
569
+ 'codetable.replacement_note': { text: '(Ersatz, passt immer)' },
570
+ 'codetable.missing': { text: 'ohne {chars}', placeholders: ['chars'] },
571
+ 'codetable.print_again': { text: 'Nochmal drucken' },
572
+ 'codetable.not_checked': { text: 'Umlaute noch nicht geprüft' },
573
+ 'codetable.check': { text: 'Umlaute prüfen' },
574
+ 'codetable.current': { text: 'Zeichensatz: Nr. {number}', placeholders: ['number'] },
559
575
  };
560
576
  export const LABELS = BESCHRIFTUNGEN_ROH;
561
577
  /** Die Beschriftung zum Schluessel, Platzhalter ersetzt; fehlt ein Wert, wirft es wie `messageText`. */
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Katalog der Code-Tabellen fuer Bondrucker und die Umwandlung von Text in
3
+ * Bytes je Tabelle.
4
+ *
5
+ * Warum ein Katalog: `ESC t n` waehlt die Zeichentabelle, aber die Nummer n
6
+ * ist nicht einheitlich. Epson legt WPC1252 auf 16, viele guenstige Drucker
7
+ * nummerieren anders oder kennen die Tabelle gar nicht. Wer am Testblatt
8
+ * sieht, welche Nummer seine Umlaute richtig druckt, waehlt hier die
9
+ * passende Tabelle. Gemeinsamer Prueffall mit dem Dart-Zwilling:
10
+ * `fixtures/code-tables.json`.
11
+ *
12
+ * Jede Tabelle setzt die zehn deutschen Zeichen (Umlaute, ß, €, §, °) auf
13
+ * ein Byte oder, wo die Tabelle das Zeichen nicht hat, auf Ersatzbuchstaben
14
+ * (`€` -> `EUR`). Fuer diese zehn Zeichen kommt nie `?` heraus.
15
+ */
16
+ /** Kennung einer Code-Tabelle. */
17
+ export type CodeTableId = 'wpc1252' | 'pc858' | 'pc850' | 'pc437' | 'iso8859_15' | 'replacement';
18
+ /** Eine Code-Tabelle des Katalogs. */
19
+ export interface CodeTable {
20
+ /** Kennung. */
21
+ id: CodeTableId;
22
+ /** Nummer auf dem Testblatt (1-6). */
23
+ number: 1 | 2 | 3 | 4 | 5 | 6;
24
+ /** n fuer `ESC t n`. */
25
+ escT: number;
26
+ /** Zeichen der zehn, die diese Tabelle nicht hat und durch Ersatzbuchstaben druckt. */
27
+ missing: readonly string[];
28
+ }
29
+ /**
30
+ * Ersatzbuchstaben fuer eines der zehn Zeichen (paketintern, fuer
31
+ * `escPosPrintableText` mit gewaehlter Tabelle).
32
+ */
33
+ export declare function ersatzBuchstaben(zeichen: string): string;
34
+ /** Alle Code-Tabellen in der Reihenfolge des Testblatts (Nummer 1-6). */
35
+ export declare const CODE_TABLES: readonly CodeTable[];
36
+ /** Die Tabelle zu einer Kennung; eine unbekannte Kennung wird gemeldet. */
37
+ export declare function codeTableById(id: CodeTableId): CodeTable;
38
+ /**
39
+ * Tabelle aus der gespeicherten Einstellung (`cp1252`/`cp437`). Alles andere,
40
+ * auch keine Einstellung, ist die Vorgabe `wpc1252`.
41
+ */
42
+ export declare function codeTableFromSetting(setting: 'cp1252' | 'cp437' | null | undefined): CodeTableId;
43
+ /**
44
+ * Zeichen, die das Vorbild vor dem Kodieren ersetzt (generator.dart `_encode`).
45
+ *
46
+ * **Eine bewusste Abweichung:** Fuer `•` sagt generator.dart `.`,
47
+ * print_paper.dart (portiert als `escPosPrintableText`) dagegen `*`. In Darts
48
+ * eigener Kette faellt das nie auf, weil print_paper vor dem Erzeuger ersetzt
49
+ * und der Erzeuger den Punkt nie zu sehen bekommt -- die gedruckte Antwort ist
50
+ * dort also `*`. Ein Verbraucher dieses Pakets kann `escPosText` aber auch
51
+ * direkt aufrufen, und dann duerfen nicht zwei Zeichen fuer dasselbe Zeichen
52
+ * herauskommen. Deshalb gilt hier dieselbe Antwort wie dort.
53
+ */
54
+ export declare const ZEICHEN_ERSATZ: ReadonlyArray<readonly [string, string]>;
55
+ /**
56
+ * Latin-1-Byte -> CP437-Byte fuer die Zeichen, die CP437 kennt (deutsche
57
+ * Umlaute, ß, westeuropaeische Akzente, Waehrungs-/Sonderzeichen). Alles
58
+ * andere ab 0x80 hat in CP437 keinen Platz und wird zu "?".
59
+ */
60
+ export declare const CP437_AUS_LATIN1: ReadonlyMap<number, number>;
61
+ /**
62
+ * Wandelt Text in die Bytes einer Code-Tabelle: erst die vorhandenen
63
+ * Ersetzungen (`ZEICHEN_ERSATZ`), dann die zehn deutschen Zeichen je Tabelle
64
+ * (Byte oder Ersatzbuchstaben), ASCII unveraendert, alles uebrige ueber die
65
+ * Abbildung der Tabelle, sonst `?`. Ein Zeichen, das die Tabelle nicht
66
+ * kennt, ist genau ein Byte; nur die Ersatzbuchstaben machen aus einem
67
+ * Zeichen mehrere. Spalten darum immer an den fertigen Bytes messen.
68
+ */
69
+ export declare function encodeForCodeTable(text: string, table: CodeTableId): Uint8Array;
70
+ /** Wendet `ZEICHEN_ERSATZ` an (paketintern, nicht exportiert ueber den Einstieg). */
71
+ export declare function replaceKnownCharacters(text: string): string;
72
+ /**
73
+ * Wie `encodeForCodeTable`, aber fuer Text, der `ZEICHEN_ERSATZ` schon hinter
74
+ * sich hat (paketintern: der alte Pfad in `encodeEscPosText` ersetzt vor der
75
+ * Latin-1-Pruefung und soll nicht zweimal ersetzen).
76
+ */
77
+ export declare function encodeReplaced(aufbereitet: string, table: CodeTableId): Uint8Array;