@keymanapp/common-types 17.0.85-alpha → 17.0.87-alpha

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 (75) hide show
  1. package/package.json +5 -2
  2. package/build/tsconfig.tsbuildinfo +0 -1
  3. package/build.sh +0 -86
  4. package/src/consts/virtual-key-constants.ts +0 -257
  5. package/src/keyman-touch-layout/keyman-touch-layout-file-reader.ts +0 -81
  6. package/src/keyman-touch-layout/keyman-touch-layout-file-writer.ts +0 -84
  7. package/src/keyman-touch-layout/keyman-touch-layout-file.ts +0 -87
  8. package/src/kmx/element-string.ts +0 -79
  9. package/src/kmx/kmx-builder.ts +0 -287
  10. package/src/kmx/kmx-plus-builder/build-disp.ts +0 -46
  11. package/src/kmx/kmx-plus-builder/build-elem.ts +0 -103
  12. package/src/kmx/kmx-plus-builder/build-keys.ts +0 -175
  13. package/src/kmx/kmx-plus-builder/build-layr.ts +0 -154
  14. package/src/kmx/kmx-plus-builder/build-list.ts +0 -95
  15. package/src/kmx/kmx-plus-builder/build-loca.ts +0 -34
  16. package/src/kmx/kmx-plus-builder/build-meta.ts +0 -37
  17. package/src/kmx/kmx-plus-builder/build-name.ts +0 -37
  18. package/src/kmx/kmx-plus-builder/build-ordr.ts +0 -45
  19. package/src/kmx/kmx-plus-builder/build-sect.ts +0 -31
  20. package/src/kmx/kmx-plus-builder/build-strs.ts +0 -58
  21. package/src/kmx/kmx-plus-builder/build-tran.ts +0 -50
  22. package/src/kmx/kmx-plus-builder/build-vkey.ts +0 -43
  23. package/src/kmx/kmx-plus-builder/builder-section.ts +0 -6
  24. package/src/kmx/kmx-plus-builder/kmx-plus-builder.ts +0 -190
  25. package/src/kmx/kmx-plus.ts +0 -692
  26. package/src/kmx/kmx.ts +0 -360
  27. package/src/kmx/string-list.ts +0 -74
  28. package/src/kpj/keyman-developer-project.ts +0 -155
  29. package/src/kpj/kpj-file-reader.ts +0 -103
  30. package/src/kpj/kpj-file.ts +0 -52
  31. package/src/kvk/kvk-file-reader.ts +0 -34
  32. package/src/kvk/kvk-file-writer.ts +0 -72
  33. package/src/kvk/kvk-file.ts +0 -122
  34. package/src/kvk/kvks-file-reader.ts +0 -164
  35. package/src/kvk/kvks-file-writer.ts +0 -113
  36. package/src/kvk/kvks-file.ts +0 -53
  37. package/src/kvk/visual-keyboard.ts +0 -80
  38. package/src/ldml-keyboard/ldml-keyboard-testdata-xml.ts +0 -74
  39. package/src/ldml-keyboard/ldml-keyboard-xml-reader.ts +0 -387
  40. package/src/ldml-keyboard/ldml-keyboard-xml.ts +0 -177
  41. package/src/main.ts +0 -27
  42. package/src/restructure.d.ts +0 -2
  43. package/src/util/common-events.ts +0 -50
  44. package/src/util/compiler-interfaces.ts +0 -54
  45. package/src/util/util.ts +0 -68
  46. package/test/fixtures/import-minimal.xml +0 -8
  47. package/test/fixtures/import-minimal1.xml +0 -11
  48. package/test/fixtures/import-minimal2.xml +0 -11
  49. package/test/fixtures/import-symbols.xml +0 -13
  50. package/test/fixtures/invalid-conforms-to.xml +0 -19
  51. package/test/fixtures/invalid-import-base.xml +0 -16
  52. package/test/fixtures/invalid-import-path.xml +0 -16
  53. package/test/fixtures/invalid-import-readfail.xml +0 -16
  54. package/test/fixtures/invalid-import-wrongroot.xml +0 -16
  55. package/test/fixtures/invalid-structure-per-dtd.xml +0 -8
  56. package/test/fixtures/keyman-touch-layout/khmer_angkor.keyman-touch-layout +0 -1950
  57. package/test/fixtures/keyman-touch-layout/legacy.keyman-touch-layout +0 -36
  58. package/test/fixtures/kpj/khmer_angkor.kpj +0 -187
  59. package/test/fixtures/kvk/khmer_angkor.kvk +0 -0
  60. package/test/fixtures/kvk/khmer_angkor.kvks +0 -206
  61. package/test/fixtures/test-fr.xml +0 -22
  62. package/test/helpers/index.ts +0 -39
  63. package/test/helpers/reader-callback-test.ts +0 -199
  64. package/test/keyman-touch-layout/test-keyman-touch-layout-file-reader.ts +0 -71
  65. package/test/keyman-touch-layout/test-keyman-touch-layout-round-trip.ts +0 -35
  66. package/test/kpj/test-kpj-file-reader.ts +0 -123
  67. package/test/kvk/test-kvk-file.ts +0 -15
  68. package/test/kvk/test-kvk-round-trip.ts +0 -87
  69. package/test/kvk/test-kvk-utils.ts +0 -24
  70. package/test/kvk/test-kvks-file.ts +0 -45
  71. package/test/ldml-keyboard/test-ldml-keyboard-testdata-reader.ts +0 -51
  72. package/test/ldml-keyboard/test-ldml-keyboard-xml-reader.ts +0 -131
  73. package/test/tsconfig.json +0 -21
  74. package/test/util/test-unescape.ts +0 -38
  75. package/tsconfig.json +0 -17
@@ -1,84 +0,0 @@
1
- import { TouchLayoutFile, TouchLayoutPlatform, TouchLayoutKey, TouchLayoutSubKey } from "./keyman-touch-layout-file.js";
2
-
3
- export interface TouchLayoutFileWriterOptions {
4
- formatted?: boolean;
5
- };
6
-
7
- export class TouchLayoutFileWriter {
8
-
9
- options: TouchLayoutFileWriterOptions;
10
-
11
- constructor(options?: TouchLayoutFileWriterOptions) {
12
- this.options = {...options};
13
- }
14
-
15
- /**
16
- * Writes the touch layout to a .keyman-touch-layout JSON file
17
- * @param source TouchLayoutFile
18
- * @returns Uint8Array, the .keyman-touch-layout file
19
- */
20
- write(source: TouchLayoutFile): Uint8Array {
21
- const output = JSON.stringify(source, null, this.options?.formatted ? 2 : undefined);
22
- const encoder = new TextEncoder();
23
- return encoder.encode(output);
24
- }
25
-
26
- /**
27
- * Compiles the touch layout file into a KeymanWeb-compatible JSON-style
28
- * object string. In the future, this may be optimized to remove unnecessary
29
- * quoting of property names, and remove unused properties, as this string
30
- * is embedded into .js code.
31
- * @param source
32
- * @returns string
33
- */
34
- compile(source: TouchLayoutFile): string {
35
- // Deep copy the source
36
- source = JSON.parse(JSON.stringify(source));
37
-
38
- // Fixup pad, width and sp to string types, as that's what KeymanWeb
39
- // currently expects
40
-
41
- const fixupKey = (key: TouchLayoutKey | TouchLayoutSubKey) => {
42
- if(Object.hasOwn(key, 'pad')) (key.pad as any) = key.pad.toString();
43
- if(Object.hasOwn(key, 'sp')) (key.sp as any) = key.sp.toString();
44
- if(Object.hasOwn(key, 'width')) (key.width as any) = key.width.toString();
45
- };
46
-
47
- const fixupPlatform = (platform: TouchLayoutPlatform) => {
48
- for(let layer of platform.layer) {
49
- for(let row of layer.row) {
50
- for(let key of row.key) {
51
- fixupKey(key);
52
- if(key.sk) {
53
- for(let sk of key.sk) {
54
- fixupKey(sk);
55
- }
56
- }
57
- if(key.multitap) {
58
- for(let sk of key.multitap) {
59
- fixupKey(sk);
60
- }
61
- }
62
- if(key.flick) {
63
- for(let id of Object.keys(key.flick)) {
64
- fixupKey((key.flick as any)[id] as TouchLayoutSubKey);
65
- }
66
- }
67
- }
68
- }
69
- }
70
- };
71
-
72
- if(source.desktop) {
73
- fixupPlatform(source.desktop);
74
- }
75
- if(source.phone) {
76
- fixupPlatform(source.phone);
77
- }
78
- if(source.tablet) {
79
- fixupPlatform(source.tablet);
80
- }
81
-
82
- return JSON.stringify(source, null, this.options?.formatted ? 2 : undefined);
83
- }
84
- };
@@ -1,87 +0,0 @@
1
- //
2
- // .keyman-touch-layout JSON format
3
- //
4
- // Follows /common/schemas/keyman-touch-layout/keyman-touch-layout.spec.json for
5
- // reading and
6
- // /common/schemas/keyman-touch-layout/keyman-touch-layout.clean.spec.json for
7
- // writing
8
- //
9
-
10
- export interface TouchLayoutFile {
11
- tablet?: TouchLayoutPlatform;
12
- phone?: TouchLayoutPlatform;
13
- desktop?: TouchLayoutPlatform;
14
- };
15
-
16
- export type TouchLayoutFont = string;
17
- export type TouchLayoutFontSize = string;
18
- export type TouchLayoutDefaultHint = "none"|"dot"|"longpress"|"multitap"|"flick"|"flick-n"|"flick-ne"|"flick-e"|"flick-se"|"flick-s"|"flick-sw"|"flick-w"|"flick-nw";
19
-
20
- export interface TouchLayoutPlatform {
21
- font?: TouchLayoutFont;
22
- fontsize?: TouchLayoutFontSize;
23
- layer: TouchLayoutLayer[];
24
- displayUnderlying?: boolean;
25
- defaultHint: TouchLayoutDefaultHint;
26
- };
27
-
28
- export type TouchLayoutLayerId = string; // pattern = /^[a-zA-Z0-9_-]+$/
29
-
30
- export interface TouchLayoutLayer {
31
- id: TouchLayoutLayerId;
32
- row: TouchLayoutRow[];
33
- };
34
-
35
- export type TouchLayoutRowId = number;
36
-
37
- export interface TouchLayoutRow {
38
- id: TouchLayoutRowId;
39
- key: TouchLayoutKey[];
40
- };
41
-
42
- type Key_Type = 'T'|'K'|'U'|'t'|'k'|'u';
43
- type Key_Id = string;
44
- export type TouchLayoutKeyId = `${Key_Type}_${Key_Id}`; // pattern = /^[TKUtku]_[a-zA-Z0-9_]+$/
45
-
46
- export interface TouchLayoutKey {
47
- id?: TouchLayoutKeyId;
48
- text?: string;
49
- layer?: TouchLayoutLayerId;
50
- nextlayer?: TouchLayoutLayerId;
51
- font?: TouchLayoutFont;
52
- fontsize?: TouchLayoutFontSize;
53
- sp?: TouchLayoutKeySp;
54
- pad?: TouchLayoutKeyPad;
55
- width?: TouchLayoutKeyWidth;
56
- sk?: TouchLayoutSubKey[];
57
- flick?: TouchLayoutFlick;
58
- multitap?: TouchLayoutSubKey[];
59
- hint?: string;
60
- };
61
-
62
- export enum TouchLayoutKeySp { normal=0, special=1, specialActive=2, deadkey=8, blank=9, spacer=10 };
63
- export type TouchLayoutKeyPad = number; // 0-100000
64
- export type TouchLayoutKeyWidth = number; // 0-100000
65
-
66
- export interface TouchLayoutSubKey {
67
- id: TouchLayoutKeyId;
68
- text?: string;
69
- layer?: TouchLayoutLayerId;
70
- nextlayer?: TouchLayoutLayerId;
71
- font?: TouchLayoutFont;
72
- fontsize?: TouchLayoutFontSize;
73
- sp?: TouchLayoutKeySp;
74
- pad?: TouchLayoutKeyPad;
75
- width?: TouchLayoutKeyWidth;
76
- };
77
-
78
- export interface TouchLayoutFlick {
79
- n?: TouchLayoutSubKey;
80
- s?: TouchLayoutSubKey;
81
- e?: TouchLayoutSubKey;
82
- w?: TouchLayoutSubKey;
83
- ne?: TouchLayoutSubKey;
84
- nw?: TouchLayoutSubKey;
85
- se?: TouchLayoutSubKey;
86
- sw?: TouchLayoutSubKey;
87
- };
@@ -1,79 +0,0 @@
1
- import { constants } from '@keymanapp/ldml-keyboard-constants';
2
- import { Strs, StrsItem } from './kmx-plus.js';
3
-
4
- export enum ElemElementFlags {
5
- none = 0,
6
- unicode_set = constants.elem_flags_unicode_set,
7
- tertiary_base = constants.elem_flags_tertiary_base,
8
- prebase = constants.elem_flags_prebase
9
- }
10
- ;
11
-
12
- export class ElemElement {
13
- value: StrsItem; // UnicodeSet or UCS32LE character
14
- order: number; // -128 to +127; used only by reorder element values
15
- tertiary: number; // -128 to +127; used only by reorder element values
16
- flags: ElemElementFlags;
17
- isEqual(a: ElemElement) {
18
- return a.value === this.value &&
19
- a.order === this.order &&
20
- a.tertiary === this.tertiary &&
21
- a.flags === this.flags;
22
- }
23
- }
24
- ;
25
-
26
- export class ElementString extends Array<ElemElement> {
27
- constructor(strs: Strs, source: string, order?: string, tertiary?: string, tertiary_base?: string, prebase?: string) {
28
- super();
29
- //TODO-LDML: full UnicodeSet and parsing
30
- if(!source) {
31
- return;
32
- }
33
-
34
- let items = source.split("");
35
-
36
- let orders: Array<string> = order ? order.split(" ") : [];
37
- if(orders.length == 1) {
38
- orders = Array<string>(items.length).fill(orders[0]);
39
- }
40
-
41
- let tertiaries: Array<string> = tertiary ? tertiary.split(" ") : [];
42
- if(tertiaries.length == 1) {
43
- tertiaries = Array<string>(items.length).fill(tertiaries[0]);
44
- }
45
-
46
- let tertiary_bases: Array<string> = tertiary_base ? tertiary_base.split(" ") : [];
47
- if(tertiary_bases.length == 1) {
48
- tertiary_bases = Array<string>(items.length).fill(tertiary_bases[0]);
49
- }
50
-
51
- let prebases: Array<string> = prebase ? prebase.split(" ") : [];
52
- if(prebases.length == 1) {
53
- prebases = Array<string>(items.length).fill(prebases[0]);
54
- }
55
-
56
- for(let i = 0; i < items.length; i++) {
57
- let elem = new ElemElement();
58
- elem.value = strs.allocString(items[i]);
59
- elem.order = orders.length ? parseInt(orders[i], 10) : 0;
60
- elem.tertiary = tertiaries.length ? parseInt(tertiaries[i], 10) : 0;
61
- elem.flags = ElemElementFlags.none |
62
- (tertiary_bases?.[i] == '1' /* TODO-LDML: or 'true'? */ ? ElemElementFlags.tertiary_base : 0) |
63
- (prebases?.[i] == '1' /* TODO-LDML: or 'true'? */ ? ElemElementFlags.prebase : 0);
64
- this.push(elem);
65
- };
66
- }
67
- isEqual(a: ElementString): boolean {
68
- if (a.length != this.length) {
69
- return false;
70
- }
71
- for (let i = 0; i < a.length; i++) {
72
- if (!this[i].isEqual(a[i])) {
73
- return false;
74
- }
75
- }
76
- return true;
77
- }
78
- }
79
- ;
@@ -1,287 +0,0 @@
1
- import * as r from 'restructure';
2
- import { KMXFile, GROUP, KEY, STORE } from './kmx.js';
3
- import { KMXPlusFile } from './kmx-plus.js';
4
- import KMXPlusBuilder from './kmx-plus-builder/kmx-plus-builder.js';
5
-
6
- // These type-checking structures are here to ensure that
7
- // we match the structures from kmx.ts in the generator
8
- //
9
- // They are used internally when building a .kmx file
10
-
11
- interface BUILDER_COMP_KEYBOARD {
12
- dwIdentifier: number;
13
- dwFileVersion: number;
14
- dwCheckSum: number;
15
- KeyboardID: number;
16
- IsRegistered: number;
17
- version: number;
18
-
19
- cxStoreArray: number;
20
- cxGroupArray: number;
21
-
22
- dpStoreArray: number;
23
- dpGroupArray: number;
24
-
25
- StartGroup_ANSI: number;
26
- StartGroup_Unicode: number;
27
-
28
- dwFlags: number;
29
-
30
- dwHotKey: number;
31
-
32
- dpBitmapOffset: number;
33
- dwBitmapSize: number;
34
- };
35
-
36
- interface BUILDER_COMP_KEYBOARD_KMXPLUSINFO {
37
- dpKMXPlus: number;
38
- dwKMXPlusSize: number;
39
- };
40
-
41
- interface BUILDER_COMP_STORE {
42
- dwSystemID: number;
43
- dpName: number;
44
- dpString: number;
45
- };
46
-
47
- interface BUILDER_COMP_KEY {
48
- Key: number;
49
- _padding: number;
50
- Line: number;
51
- ShiftFlags: number;
52
- dpOutput: number;
53
- dpContext: number;
54
- };
55
-
56
- interface BUILDER_COMP_GROUP {
57
- dpName: number;
58
- dpKeyArray: number;
59
- dpMatch: number;
60
- dpNoMatch: number;
61
- cxKeyArray: number;
62
- fUsingKeys: number;
63
- };
64
-
65
-
66
- export default class KMXBuilder {
67
- file: KMXFile;
68
- base_keyboard: number = 0;
69
- base_kmxplus: number = 0;
70
- comp_header: BUILDER_COMP_KEYBOARD;
71
- comp_kmxplus: BUILDER_COMP_KEYBOARD_KMXPLUSINFO;
72
- comp_stores: {base: number, store: STORE, obj: BUILDER_COMP_STORE}[] = [];
73
- comp_groups: {base: number, group: GROUP, obj: BUILDER_COMP_GROUP, keys: {base: number, key: KEY, obj: BUILDER_COMP_KEY}[]}[] = [];
74
- comp_kmxplus_data: Uint8Array;
75
- writeDebug: boolean = false;
76
-
77
- constructor(file: KMXFile, writeDebug: boolean) {
78
- this.file = file;
79
- this.writeDebug = writeDebug;
80
- }
81
-
82
- calculateStringOffsetAndSize(string: string, base: number, requireString: boolean = false) {
83
- if(string.length == 0 && !requireString) {
84
- // Zero length strings take up no space in the file, and
85
- // are treated as a 'null string'
86
- return [0, base];
87
- }
88
- return [base, base + string.length * 2 + 2]; // include trailing zero
89
- }
90
-
91
- private build() {
92
- this.base_keyboard = 0;
93
- this.base_kmxplus = 0;
94
-
95
- // Header
96
-
97
- this.comp_header = {
98
- dwIdentifier: KMXFile.FILEID_COMPILED,
99
- dwFileVersion: KMXFile.VERSION_160,
100
- dwCheckSum: 0, // Deprecated in Keyman 16.0
101
- KeyboardID: 0,
102
- IsRegistered: 1,
103
- version: 0,
104
- cxStoreArray: 0,
105
- cxGroupArray: 0,
106
- dpStoreArray: 0,
107
- dpGroupArray: 0,
108
- StartGroup_ANSI: 0xFFFFFFFF,
109
- StartGroup_Unicode: 0xFFFFFFFF,
110
- dwFlags: 0,
111
- dwHotKey: 0,
112
- dpBitmapOffset: 0,
113
- dwBitmapSize: 0
114
- };
115
-
116
- let size = KMXFile.COMP_KEYBOARD_SIZE;
117
-
118
- if(this.file instanceof KMXPlusFile) {
119
- // Reserve space for KMXPlus header; we'll come back and fill in details
120
- // once we know base kmx file size.
121
- this.comp_header.dwFlags |= KMXFile.KF_KMXPLUS;
122
- this.base_kmxplus = size;
123
- size += KMXFile.COMP_KEYBOARD_KMXPLUSINFO_SIZE;
124
- }
125
-
126
- // Stores
127
-
128
- this.comp_header.cxStoreArray = this.file.keyboard.stores.length;
129
- this.comp_header.dpStoreArray = this.comp_header.cxStoreArray ? size : 0;
130
- let storeBase = size;
131
- size += this.file.keyboard.stores.length * KMXFile.COMP_STORE_SIZE;
132
- for(let store of this.file.keyboard.stores) {
133
- let comp_store: BUILDER_COMP_STORE = {
134
- dwSystemID: store.dwSystemID,
135
- dpName: 0,
136
- dpString: 0
137
- };
138
- this.comp_stores.push({base: storeBase, store: store, obj: comp_store});
139
- if(this.writeDebug /*TODO: || store.isOption*/) {
140
- [comp_store.dpName, size] = this.calculateStringOffsetAndSize(store.dpName, size);
141
- }
142
-
143
- [comp_store.dpString, size] = this.calculateStringOffsetAndSize(store.dpString, size);
144
- storeBase += KMXFile.COMP_STORE_SIZE;
145
- }
146
-
147
- // Groups
148
-
149
- this.comp_header.cxGroupArray = this.file.keyboard.groups.length;
150
- this.comp_header.dpGroupArray = this.comp_header.cxGroupArray ? size : 0;
151
- let groupBase = size;
152
- size += this.file.keyboard.groups.length * KMXFile.COMP_GROUP_SIZE;
153
- for(let group of this.file.keyboard.groups) {
154
- let comp_group: BUILDER_COMP_GROUP = {
155
- dpName: 0,
156
- dpKeyArray: 0,
157
- dpMatch: 0,
158
- dpNoMatch: 0,
159
- cxKeyArray: group.keys.length,
160
- fUsingKeys: group.fUsingKeys ? 1 : 0
161
- };
162
-
163
- let comp_keys: {base: number, key: KEY, obj: BUILDER_COMP_KEY}[] = [];
164
-
165
- this.comp_groups.push({base: groupBase, group: group, obj: comp_group, keys: comp_keys});
166
-
167
- if(this.writeDebug) {
168
- [comp_group.dpName, size] = this.calculateStringOffsetAndSize(group.dpName, size);
169
- }
170
- [comp_group.dpMatch, size] = this.calculateStringOffsetAndSize(group.dpMatch, size);
171
- [comp_group.dpNoMatch, size] = this.calculateStringOffsetAndSize(group.dpNoMatch, size);
172
-
173
- // Keys within a group
174
-
175
- comp_group.dpKeyArray = group.keys.length ? size : 0;
176
-
177
- let keyBase = size;
178
- size += group.keys.length * KMXFile.COMP_KEY_SIZE;
179
- for(let key of group.keys) {
180
- let comp_key: BUILDER_COMP_KEY = {
181
- Key: key.Key,
182
- _padding: 0,
183
- Line: key.Line,
184
- ShiftFlags: key.ShiftFlags,
185
- dpOutput: 0,
186
- dpContext: 0
187
- };
188
- comp_keys.push({base: keyBase, key: key, obj: comp_key});
189
- [comp_key.dpOutput, size] = this.calculateStringOffsetAndSize(key.dpOutput, size, true);
190
- [comp_key.dpContext, size] = this.calculateStringOffsetAndSize(key.dpContext, size, true);
191
- keyBase += KMXFile.COMP_KEY_SIZE;
192
- }
193
-
194
- groupBase += KMXFile.COMP_GROUP_SIZE;
195
- }
196
-
197
- size += this.buildBitmap();
198
- size += this.buildKMXPlus(size);
199
-
200
- return size;
201
- }
202
-
203
- buildBitmap() {
204
- // TODO
205
- return 0;
206
- }
207
-
208
- buildKMXPlus(base: number) {
209
- if(!(this.file instanceof KMXPlusFile)) {
210
- return 0;
211
- }
212
-
213
- const plusbuilder: KMXPlusBuilder = new KMXPlusBuilder(this.file, this.writeDebug);
214
- this.comp_kmxplus_data = plusbuilder.compile();
215
- this.comp_kmxplus = {
216
- dpKMXPlus: base,
217
- dwKMXPlusSize: this.comp_kmxplus_data.length
218
- };
219
-
220
- return this.comp_kmxplus.dwKMXPlusSize;
221
- }
222
-
223
- setString(file: Uint8Array, pos: number, str: string, requireString: boolean = false): void {
224
- if(requireString && !str.length) {
225
- // Just write zero terminator, as r.String for a zero-length string
226
- // seems to fail.
227
- let sbuf = r.uint16le;
228
- file.set(sbuf.toBuffer(0), pos);
229
- }
230
- else if(pos && str.length) {
231
- let sbuf = new r.String(null, 'utf16le'); // null-terminated string
232
- file.set(sbuf.toBuffer(str), pos);
233
- }
234
- }
235
-
236
- compile(): Uint8Array {
237
- const fileSize = this.build();
238
-
239
- let file: Uint8Array = new Uint8Array(fileSize);
240
-
241
- // Write headers
242
-
243
- const header = this.file.COMP_KEYBOARD.toBuffer(this.comp_header);
244
- file.set(header, this.base_keyboard);
245
-
246
- if(this.file instanceof KMXPlusFile) {
247
- const kmxplus: Uint8Array = this.file.COMP_KEYBOARD_KMXPLUSINFO.toBuffer(this.comp_kmxplus);
248
- file.set(kmxplus, this.base_kmxplus);
249
- }
250
-
251
- // Write store array and data
252
-
253
- for(let store of this.comp_stores) {
254
- file.set(this.file.COMP_STORE.toBuffer(store.obj), store.base);
255
- if(this.writeDebug) {
256
- this.setString(file, store.obj.dpName, store.store.dpName);
257
- }
258
- this.setString(file, store.obj.dpString, store.store.dpString);
259
- }
260
-
261
- // Write group array and data
262
-
263
- for(let group of this.comp_groups) {
264
- file.set(this.file.COMP_GROUP.toBuffer(group.obj), group.base);
265
- if(this.writeDebug) {
266
- this.setString(file, group.obj.dpName, group.group.dpName);
267
- }
268
- this.setString(file, group.obj.dpMatch, group.group.dpMatch);
269
- this.setString(file, group.obj.dpNoMatch, group.group.dpNoMatch);
270
-
271
- for(let key of group.keys) {
272
- file.set(this.file.COMP_KEY.toBuffer(key.obj), key.base);
273
- // for back-compat reasons, these are never NULL strings
274
- this.setString(file, key.obj.dpContext, key.key.dpContext, true);
275
- this.setString(file, key.obj.dpOutput, key.key.dpOutput, true);
276
- }
277
- }
278
-
279
- // Write KMXPlus data stream
280
-
281
- if(this.file instanceof KMXPlusFile) {
282
- file.set(this.comp_kmxplus_data, this.comp_kmxplus.dpKMXPlus);
283
- }
284
-
285
- return file;
286
- }
287
- }
@@ -1,46 +0,0 @@
1
- import { constants } from '@keymanapp/ldml-keyboard-constants';
2
- import { KMXPlusData } from "../kmx-plus.js";
3
- import { build_strs_index, BUILDER_STRS } from "./build-strs.js";
4
- import { BUILDER_SECTION } from './builder-section.js';
5
-
6
- /* ------------------------------------------------------------------
7
- * disp section
8
- ------------------------------------------------------------------ */
9
-
10
- /**
11
- * Builder for the 'disp' section
12
- */
13
- interface BUILDER_DISP_ITEM {
14
- to: number;
15
- display: number;
16
- };
17
-
18
- export interface BUILDER_DISP extends BUILDER_SECTION {
19
- count: number;
20
- baseCharacter: number;
21
- items: BUILDER_DISP_ITEM[];
22
- };
23
-
24
- export function build_disp(kmxplus: KMXPlusData, sect_strs: BUILDER_STRS): BUILDER_DISP {
25
- if(!kmxplus.disp.disps.length && !kmxplus.disp.baseCharacter.value) {
26
- return null;
27
- }
28
-
29
- let disp: BUILDER_DISP = {
30
- ident: constants.hex_section_id(constants.section.disp),
31
- size: constants.length_disp + constants.length_disp_item * kmxplus.disp.disps.length,
32
- _offset: 0,
33
- count: kmxplus.disp.disps.length,
34
- baseCharacter: build_strs_index(sect_strs, kmxplus.disp.baseCharacter),
35
- items: []
36
- };
37
-
38
- for(let item of kmxplus.disp.disps) {
39
- disp.items.push({
40
- to: build_strs_index(sect_strs, item.to),
41
- display: build_strs_index(sect_strs, item.display),
42
- });
43
- }
44
-
45
- return disp;
46
- }
@@ -1,103 +0,0 @@
1
- import { constants } from "@keymanapp/ldml-keyboard-constants";
2
- import { ElementString } from "../element-string.js";
3
- import { Elem } from "../kmx-plus.js";
4
- import { build_strs_index, BUILDER_STRS } from "./build-strs.js";
5
- import { BUILDER_SECTION } from "./builder-section.js";
6
-
7
- /* ------------------------------------------------------------------
8
- * elem section
9
- ------------------------------------------------------------------ */
10
-
11
- interface BUILDER_ELEM_ELEMENT {
12
- element: number; // str | UTF-32 char
13
- flags: number;
14
- _value: string;
15
- };
16
-
17
- interface BUILDER_ELEM_STRING {
18
- offset: number;
19
- length: number;
20
- items: BUILDER_ELEM_ELEMENT[];
21
- _value: ElementString;
22
- };
23
-
24
- /**
25
- * Builder for the 'elem' section
26
- */
27
- export interface BUILDER_ELEM extends BUILDER_SECTION {
28
- count: number;
29
- strings: BUILDER_ELEM_STRING[];
30
- };
31
-
32
- function binaryElemCompare(a: BUILDER_ELEM_STRING, b: BUILDER_ELEM_STRING): number {
33
- for(let i = 0; i < a.items.length && i < b.items.length; i++) {
34
- if(a.items[i]._value < b.items[i]._value) return -1;
35
- if(a.items[i]._value > b.items[i]._value) return 1;
36
- if(a.items[i].flags < b.items[i].flags) return -1;
37
- if(a.items[i].flags > b.items[i].flags) return 1;
38
- }
39
- if(a.items.length < b.items.length) return -1;
40
- if(a.items.length > b.items.length) return 1;
41
- return 0;
42
- }
43
-
44
- export function build_elem(source_elem: Elem, sect_strs: BUILDER_STRS): BUILDER_ELEM {
45
- let result: BUILDER_ELEM = {
46
- ident: constants.hex_section_id(constants.section.elem),
47
- size: 0, // finalized below
48
- _offset: 0,
49
- count: source_elem.strings.length,
50
- strings: [], // finalized below
51
- };
52
-
53
- // TODO: consider padding
54
- result.strings = source_elem.strings.map(item => {
55
- let res: BUILDER_ELEM_STRING = {
56
- offset: 0, // finalized below
57
- length: item.length,
58
- items: [],
59
- _value: item
60
- };
61
-
62
- res.items = item.map(v => {
63
- return {
64
- element: build_strs_index(sect_strs, v.value),
65
- flags: constants.elem_flags_unicode_set |
66
- v.flags | //
67
- ((v.order ?? 0) << constants.elem_flags_order_bitshift) | // -128 to +127; used only by reorder element values
68
- ((v.tertiary ?? 0) << constants.elem_flags_tertiary_bitshift), // -128 to +127; used only by reorder element values
69
- _value: v.value.value
70
- };
71
- });
72
- return res;
73
- });
74
- result.strings.sort((a,b) => binaryElemCompare(a, b));
75
-
76
- /* Calculate offsets and total size */
77
-
78
- let offset = constants.length_elem + constants.length_elem_item * result.count;
79
- for(let item of result.strings) {
80
- if (item.length === 0) {
81
- // no length gets a zero offset
82
- item.offset = 0;
83
- } else {
84
- item.offset = offset;
85
- offset += item.length * constants.length_elem_item_element;
86
- }
87
- }
88
-
89
- result.size = offset;
90
- return result;
91
- }
92
-
93
- export function build_elem_index(sect_elem: BUILDER_ELEM, value: ElementString) {
94
- if(!(value instanceof ElementString)) {
95
- throw new Error('unexpected value '+value);
96
- }
97
-
98
- const result = sect_elem.strings.findIndex(v => value.isEqual(v._value));
99
- if(result < 0) {
100
- throw new Error('unexpectedly missing StrsItem '+value);
101
- }
102
- return result;
103
- }