@keymanapp/kmc-ldml 18.0.17-alpha → 18.0.19-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.
- package/build/src/compiler/compiler.js +309 -308
- package/build/src/compiler/compiler.js.map +1 -1
- package/build/src/compiler/disp.js +84 -83
- package/build/src/compiler/disp.js.map +1 -1
- package/build/src/compiler/empty-compiler.js +116 -115
- package/build/src/compiler/empty-compiler.js.map +1 -1
- package/build/src/compiler/keymanweb-compiler.js +97 -96
- package/build/src/compiler/keymanweb-compiler.js.map +1 -1
- package/build/src/compiler/keys.d.ts.map +1 -1
- package/build/src/compiler/keys.js +419 -415
- package/build/src/compiler/keys.js.map +1 -1
- package/build/src/compiler/layr.d.ts.map +1 -1
- package/build/src/compiler/layr.js +83 -76
- package/build/src/compiler/layr.js.map +1 -1
- package/build/src/compiler/ldml-compiler-options.js +5 -4
- package/build/src/compiler/ldml-compiler-options.js.map +1 -1
- package/build/src/compiler/loca.js +61 -60
- package/build/src/compiler/loca.js.map +1 -1
- package/build/src/compiler/messages.d.ts +11 -3
- package/build/src/compiler/messages.d.ts.map +1 -1
- package/build/src/compiler/messages.js +120 -109
- package/build/src/compiler/messages.js.map +1 -1
- package/build/src/compiler/meta.js +57 -56
- package/build/src/compiler/meta.js.map +1 -1
- package/build/src/compiler/metadata-compiler.js +49 -48
- package/build/src/compiler/metadata-compiler.js.map +1 -1
- package/build/src/compiler/section-compiler.js +42 -41
- package/build/src/compiler/section-compiler.js.map +1 -1
- package/build/src/compiler/substitution-tracker.js +105 -104
- package/build/src/compiler/substitution-tracker.js.map +1 -1
- package/build/src/compiler/touch-layout-compiler.js +93 -92
- package/build/src/compiler/touch-layout-compiler.js.map +1 -1
- package/build/src/compiler/tran.d.ts +7 -0
- package/build/src/compiler/tran.d.ts.map +1 -1
- package/build/src/compiler/tran.js +382 -353
- package/build/src/compiler/tran.js.map +1 -1
- package/build/src/compiler/vars.d.ts.map +1 -1
- package/build/src/compiler/vars.js +236 -227
- package/build/src/compiler/vars.js.map +1 -1
- package/build/src/compiler/visual-keyboard-compiler.js +70 -69
- package/build/src/compiler/visual-keyboard-compiler.js.map +1 -1
- package/build/src/main.js +5 -4
- package/build/src/main.js.map +1 -1
- package/build/src/util/util.d.ts +2 -2
- package/build/src/util/util.d.ts.map +1 -1
- package/build/src/util/util.js +185 -179
- package/build/src/util/util.js.map +1 -1
- package/package.json +6 -6
|
@@ -1,309 +1,310 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
//
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
;
|
|
38
|
-
;
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
* @
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
this.
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
* @
|
|
69
|
-
* @param
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
...
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
// to
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
const
|
|
93
|
-
const
|
|
94
|
-
const
|
|
95
|
-
const
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
-
//
|
|
99
|
-
//
|
|
100
|
-
// const
|
|
101
|
-
// const
|
|
102
|
-
//
|
|
103
|
-
//KMW17.0: const
|
|
104
|
-
//KMW17.0: const
|
|
105
|
-
//KMW17.0: const
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
*
|
|
118
|
-
*
|
|
119
|
-
*
|
|
120
|
-
* - .
|
|
121
|
-
* - .
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
* @
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
const
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
*
|
|
164
|
-
*
|
|
165
|
-
*
|
|
166
|
-
* @
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
*
|
|
197
|
-
*
|
|
198
|
-
*
|
|
199
|
-
* @
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
const
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
//
|
|
216
|
-
//
|
|
217
|
-
//
|
|
218
|
-
//
|
|
219
|
-
//
|
|
220
|
-
//
|
|
221
|
-
//
|
|
222
|
-
//
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
*
|
|
228
|
-
*
|
|
229
|
-
*
|
|
230
|
-
* @
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
*
|
|
238
|
-
*
|
|
239
|
-
*
|
|
240
|
-
* @
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
//
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
delete
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
//
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
}
|
|
308
|
-
|
|
1
|
+
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},n=(new Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="5183a68a-b994-5081-b881-0db8ef00163d")}catch(e){}}();
|
|
3
|
+
import { LDMLKeyboardXMLSourceFileReader, KMXPlus, defaultCompilerOptions, KMXBuilder, KvkFileWriter } from '@keymanapp/common-types';
|
|
4
|
+
import { CompilerMessages } from './messages.js';
|
|
5
|
+
import { BkspCompiler, TranCompiler } from './tran.js';
|
|
6
|
+
import { DispCompiler } from './disp.js';
|
|
7
|
+
import { KeysCompiler } from './keys.js';
|
|
8
|
+
import { LayrCompiler } from './layr.js';
|
|
9
|
+
import { LocaCompiler } from './loca.js';
|
|
10
|
+
import { MetaCompiler } from './meta.js';
|
|
11
|
+
import { VarsCompiler } from './vars.js';
|
|
12
|
+
import { StrsCompiler, ElemCompiler, ListCompiler, UsetCompiler } from './empty-compiler.js';
|
|
13
|
+
var KMXPlusFile = KMXPlus.KMXPlusFile;
|
|
14
|
+
import { constants } from '@keymanapp/ldml-keyboard-constants';
|
|
15
|
+
import { KmnCompiler } from '@keymanapp/kmc-kmn';
|
|
16
|
+
import { KMXPlusMetadataCompiler } from './metadata-compiler.js';
|
|
17
|
+
import { LdmlKeyboardVisualKeyboardCompiler } from './visual-keyboard-compiler.js';
|
|
18
|
+
//KMW17.0: import { LdmlKeyboardKeymanWebCompiler } from './keymanweb-compiler.js';
|
|
19
|
+
export const SECTION_COMPILERS = [
|
|
20
|
+
// These are in dependency order.
|
|
21
|
+
// First the former 'global' sections
|
|
22
|
+
StrsCompiler,
|
|
23
|
+
// meta depends on strs, but potentially needed by anything else using strs
|
|
24
|
+
MetaCompiler,
|
|
25
|
+
ListCompiler,
|
|
26
|
+
ElemCompiler,
|
|
27
|
+
UsetCompiler,
|
|
28
|
+
// Next, Vars, which depends on others
|
|
29
|
+
VarsCompiler,
|
|
30
|
+
// Now all others:
|
|
31
|
+
BkspCompiler,
|
|
32
|
+
DispCompiler,
|
|
33
|
+
KeysCompiler,
|
|
34
|
+
LayrCompiler,
|
|
35
|
+
LocaCompiler,
|
|
36
|
+
TranCompiler,
|
|
37
|
+
];
|
|
38
|
+
;
|
|
39
|
+
;
|
|
40
|
+
/**
|
|
41
|
+
* @public
|
|
42
|
+
* Compiles a LDML keyboard .xml file to a .kmx (KMXPlus), .kvk, and/or .js. The
|
|
43
|
+
* compiler does not read or write from filesystem or network directly, but
|
|
44
|
+
* relies on callbacks for all external IO.
|
|
45
|
+
*/
|
|
46
|
+
export class LdmlKeyboardCompiler {
|
|
47
|
+
callbacks;
|
|
48
|
+
options;
|
|
49
|
+
// uset parser
|
|
50
|
+
usetparser = undefined;
|
|
51
|
+
/**
|
|
52
|
+
* Initialize the compiler, including loading the WASM host for uset parsing.
|
|
53
|
+
* Copies options.
|
|
54
|
+
* @param callbacks - Callbacks for external interfaces, including message
|
|
55
|
+
* reporting and file io
|
|
56
|
+
* @param options - Compiler options
|
|
57
|
+
* @returns false if initialization fails
|
|
58
|
+
*/
|
|
59
|
+
async init(callbacks, options) {
|
|
60
|
+
this.options = { ...options };
|
|
61
|
+
this.callbacks = callbacks;
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Compiles a LDML keyboard .xml file to .kmx, .kvk, and/or .js files. Returns
|
|
66
|
+
* an object containing binary artifacts on success. The files are passed in
|
|
67
|
+
* by name, and the compiler will use callbacks as passed to the
|
|
68
|
+
* {@link LdmlKeyboardCompiler.init} function to read any input files by disk.
|
|
69
|
+
* @param infile - Path to source file.
|
|
70
|
+
* @param outfile - Path to output file. The file will not be written to, but
|
|
71
|
+
* will be included in the result for use by
|
|
72
|
+
* {@link LdmlKeyboardCompiler.write}.
|
|
73
|
+
* @returns Binary artifacts on success, null on failure.
|
|
74
|
+
*/
|
|
75
|
+
async run(inputFilename, outputFilename) {
|
|
76
|
+
let compilerOptions = {
|
|
77
|
+
...defaultCompilerOptions,
|
|
78
|
+
...this.options,
|
|
79
|
+
};
|
|
80
|
+
let source = this.load(inputFilename);
|
|
81
|
+
if (!source) {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
let kmx = await this.compile(source);
|
|
85
|
+
if (!kmx) {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
// In order for the KMX file to be loaded by non-KMXPlus components, it is helpful
|
|
89
|
+
// to duplicate some of the metadata
|
|
90
|
+
KMXPlusMetadataCompiler.addKmxMetadata(kmx.kmxplus, kmx.keyboard, compilerOptions);
|
|
91
|
+
// Use the builder to generate the binary output file
|
|
92
|
+
const builder = new KMXBuilder(kmx, compilerOptions.saveDebug);
|
|
93
|
+
const kmx_binary = builder.compile();
|
|
94
|
+
const vkcompiler = new LdmlKeyboardVisualKeyboardCompiler(this.callbacks);
|
|
95
|
+
const vk = vkcompiler.compile(source);
|
|
96
|
+
const writer = new KvkFileWriter();
|
|
97
|
+
const kvk_binary = writer.write(vk);
|
|
98
|
+
// Note: we could have a step of generating source files here
|
|
99
|
+
// KvksFileWriter()...
|
|
100
|
+
// const tlcompiler = new kmc.TouchLayoutCompiler();
|
|
101
|
+
// const tl = tlcompiler.compile(source);
|
|
102
|
+
// const tlwriter = new TouchLayoutFileWriter();
|
|
103
|
+
//KMW17.0: const kmwcompiler = new LdmlKeyboardKeymanWebCompiler(this.callbacks, compilerOptions);
|
|
104
|
+
//KMW17.0: const kmw_string = kmwcompiler.compile(inputFilename, source);
|
|
105
|
+
//KMW17.0: const encoder = new TextEncoder();
|
|
106
|
+
//KMW17.0: const kmw_binary = encoder.encode(kmw_string);
|
|
107
|
+
outputFilename = outputFilename ?? inputFilename.replace(/\.xml$/, '.kmx');
|
|
108
|
+
return {
|
|
109
|
+
artifacts: {
|
|
110
|
+
kmx: { data: kmx_binary, filename: outputFilename },
|
|
111
|
+
kvk: { data: kvk_binary, filename: outputFilename.replace(/\.kmx$/, '.kvk') },
|
|
112
|
+
//KMW17.0: js: { data: kmw_binary, filename: outputFilename.replace(/\.kmx$/, '.js') },
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Write artifacts from a successful compile to disk, via callbacks methods.
|
|
118
|
+
* The artifacts written may include:
|
|
119
|
+
*
|
|
120
|
+
* - .kmx file - binary keyboard used by Keyman on desktop platforms
|
|
121
|
+
* - .kvk file - binary on screen keyboard used by Keyman on desktop platforms
|
|
122
|
+
* - .js file - Javascript keyboard for web and touch platforms
|
|
123
|
+
*
|
|
124
|
+
* @param artifacts - object containing artifact binary data to write out
|
|
125
|
+
* @returns true on success
|
|
126
|
+
*/
|
|
127
|
+
async write(artifacts) {
|
|
128
|
+
if (artifacts.kmx) {
|
|
129
|
+
this.callbacks.fs.writeFileSync(artifacts.kmx.filename, artifacts.kmx.data);
|
|
130
|
+
}
|
|
131
|
+
if (artifacts.kvk) {
|
|
132
|
+
this.callbacks.fs.writeFileSync(artifacts.kvk.filename, artifacts.kvk.data);
|
|
133
|
+
}
|
|
134
|
+
if (artifacts.js) {
|
|
135
|
+
this.callbacks.fs.writeFileSync(artifacts.js.filename, artifacts.js.data);
|
|
136
|
+
}
|
|
137
|
+
return true;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* @internal
|
|
141
|
+
* Construct or return a UnicodeSetParser, aka KmnCompiler
|
|
142
|
+
* @returns the held UnicodeSetParser
|
|
143
|
+
*/
|
|
144
|
+
async getUsetParser() {
|
|
145
|
+
if (this.usetparser === undefined) {
|
|
146
|
+
// initialize
|
|
147
|
+
const compiler = new KmnCompiler();
|
|
148
|
+
const ok = await compiler.init(this.callbacks, null);
|
|
149
|
+
if (ok) {
|
|
150
|
+
this.usetparser = compiler;
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
/* c8 ignore next 2 */
|
|
154
|
+
this.usetparser = null; // Store null on failure
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return this.usetparser;
|
|
158
|
+
}
|
|
159
|
+
buildSections(source) {
|
|
160
|
+
return SECTION_COMPILERS.map(c => new c(source, this.callbacks));
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* @internal
|
|
164
|
+
* Loads a LDML Keyboard xml file and compiles into in-memory xml
|
|
165
|
+
* structures.
|
|
166
|
+
* @param filename - input filename, will use callback to load from disk
|
|
167
|
+
* @returns the source file, or null if invalid
|
|
168
|
+
*/
|
|
169
|
+
load(filename) {
|
|
170
|
+
const reader = new LDMLKeyboardXMLSourceFileReader(this.options.readerOptions, this.callbacks);
|
|
171
|
+
// load the file from disk into a string
|
|
172
|
+
const data = this.callbacks.loadFile(filename);
|
|
173
|
+
if (!data) {
|
|
174
|
+
this.callbacks.reportMessage(CompilerMessages.Error_InvalidFile({ errorText: 'Unable to read XML file' }));
|
|
175
|
+
return null;
|
|
176
|
+
}
|
|
177
|
+
// parse (load) the string into an object tree
|
|
178
|
+
const source = reader.load(data);
|
|
179
|
+
if (!source) {
|
|
180
|
+
this.callbacks.reportMessage(CompilerMessages.Error_InvalidFile({ errorText: 'Unable to load XML file' }));
|
|
181
|
+
return null;
|
|
182
|
+
}
|
|
183
|
+
try {
|
|
184
|
+
// validate the object tree against the .xsd schema
|
|
185
|
+
if (!reader.validate(source)) {
|
|
186
|
+
return null;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
catch (e) {
|
|
190
|
+
this.callbacks.reportMessage(CompilerMessages.Error_InvalidFile({ errorText: e.toString() }));
|
|
191
|
+
return null;
|
|
192
|
+
}
|
|
193
|
+
return source;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* @internal
|
|
197
|
+
* Loads a LDML Keyboard test data xml file and compiles into in-memory xml
|
|
198
|
+
* structures.
|
|
199
|
+
* @param filename - input filename, will use callback to load from disk
|
|
200
|
+
* @returns the source file, or null if invalid
|
|
201
|
+
*/
|
|
202
|
+
loadTestData(filename) {
|
|
203
|
+
const reader = new LDMLKeyboardXMLSourceFileReader(this.options.readerOptions, this.callbacks);
|
|
204
|
+
const data = this.callbacks.loadFile(filename);
|
|
205
|
+
if (!data) {
|
|
206
|
+
this.callbacks.reportMessage(CompilerMessages.Error_InvalidFile({ errorText: 'Unable to read XML file' }));
|
|
207
|
+
return null;
|
|
208
|
+
}
|
|
209
|
+
const source = reader.loadTestData(data);
|
|
210
|
+
/* c8 ignore next 4 */
|
|
211
|
+
if (!source) {
|
|
212
|
+
this.callbacks.reportMessage(CompilerMessages.Error_InvalidFile({ errorText: 'Unable to load XML file' }));
|
|
213
|
+
return null;
|
|
214
|
+
}
|
|
215
|
+
// TODO-LDML: The unboxed data doesn't match the schema anymore. Skipping validation, for now.
|
|
216
|
+
// try {
|
|
217
|
+
// if (!reader.validate(source)) {
|
|
218
|
+
// return null;
|
|
219
|
+
// }
|
|
220
|
+
// } catch(e) {
|
|
221
|
+
// this.callbacks.reportMessage(CompilerMessages.Error_InvalidFile({errorText: e.toString()}));
|
|
222
|
+
// return null;
|
|
223
|
+
// }
|
|
224
|
+
return source;
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* @internal
|
|
228
|
+
* Validates that the LDML keyboard source file and lints. Actually just
|
|
229
|
+
* compiles the keyboard and returns `true` if everything is good...
|
|
230
|
+
* @param source - in-memory representation of LDML keyboard xml file
|
|
231
|
+
* @returns true if the file validates
|
|
232
|
+
*/
|
|
233
|
+
async validate(source) {
|
|
234
|
+
return !!(await this.compile(source, true));
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* @internal
|
|
238
|
+
* Transforms in-memory LDML keyboard xml file to an intermediate
|
|
239
|
+
* representation of a .kmx file.
|
|
240
|
+
* @param source - in-memory representation of LDML keyboard xml file
|
|
241
|
+
* @returns KMXPlusFile intermediate file
|
|
242
|
+
*/
|
|
243
|
+
async compile(source, postValidate) {
|
|
244
|
+
const sections = this.buildSections(source);
|
|
245
|
+
let passed = true;
|
|
246
|
+
const kmx = new KMXPlusFile();
|
|
247
|
+
for (let section of sections) {
|
|
248
|
+
if (!section.validate()) {
|
|
249
|
+
// TODO-LDML: coverage
|
|
250
|
+
passed = false;
|
|
251
|
+
// We'll keep validating other sections anyway, so we get a full set of
|
|
252
|
+
// errors for the keyboard developer.
|
|
253
|
+
continue;
|
|
254
|
+
}
|
|
255
|
+
// clone
|
|
256
|
+
const globalSections = Object.assign({}, kmx.kmxplus);
|
|
257
|
+
// pre-initialize the usetparser
|
|
258
|
+
globalSections.usetparser = await this.getUsetParser();
|
|
259
|
+
const dependencies = section.dependencies;
|
|
260
|
+
let dependencyProblem = false;
|
|
261
|
+
Object.keys(constants.section).forEach((sectstr) => {
|
|
262
|
+
const sectid = constants.section[sectstr];
|
|
263
|
+
if (dependencies.has(sectid)) {
|
|
264
|
+
/* c8 ignore next 4 */
|
|
265
|
+
if (!kmx.kmxplus[sectid]) {
|
|
266
|
+
if (passed) {
|
|
267
|
+
// Internal error useful during section bring-up
|
|
268
|
+
throw new Error(`Internal error: section ${section.id} depends on uninitialized dependency ${sectid}, check ordering`);
|
|
269
|
+
}
|
|
270
|
+
else {
|
|
271
|
+
dependencyProblem = true;
|
|
272
|
+
return; // Already failed to validate, so no need for the layering message.
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
else {
|
|
277
|
+
// delete dependencies that aren't referenced
|
|
278
|
+
delete globalSections[sectid];
|
|
279
|
+
}
|
|
280
|
+
});
|
|
281
|
+
if (dependencyProblem && !passed) {
|
|
282
|
+
// Some layering problem, but we've already noted an error (!passed).
|
|
283
|
+
// Just skip this section.
|
|
284
|
+
continue;
|
|
285
|
+
}
|
|
286
|
+
const sect = section.compile(globalSections);
|
|
287
|
+
if (!sect) {
|
|
288
|
+
passed = false;
|
|
289
|
+
continue;
|
|
290
|
+
}
|
|
291
|
+
/* c8 ignore next 4 */
|
|
292
|
+
if (kmx.kmxplus[section.id]) {
|
|
293
|
+
// Internal error useful during section bring-up
|
|
294
|
+
throw new Error(`Internal error: section ${section.id} would be assigned twice`);
|
|
295
|
+
}
|
|
296
|
+
kmx.kmxplus[section.id] = sect;
|
|
297
|
+
}
|
|
298
|
+
// give all sections a chance to postValidate
|
|
299
|
+
if (postValidate) {
|
|
300
|
+
for (let section of sections) {
|
|
301
|
+
if (!section.postValidate(kmx.kmxplus[section.id])) {
|
|
302
|
+
passed = false;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
return passed ? kmx : null;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
309
|
//# sourceMappingURL=compiler.js.map
|
|
310
|
+
//# debugId=5183a68a-b994-5081-b881-0db8ef00163d
|