mirror of
https://github.com/keymanapp/keyman.git
synced 2026-09-01 05:07:40 +00:00
Merge pull request #7187 from keymanapp/feat/core/ldml-add-meta-version
feat(core): add version field to meta 🙀
This commit is contained in:
commit
423debfef7
10 changed files with 89 additions and 49 deletions
|
|
@ -21,7 +21,7 @@
|
|||
#define LDML_LENGTH_KEYS_ITEM 0x10
|
||||
#define LDML_LENGTH_LOCA 0x10
|
||||
#define LDML_LENGTH_LOCA_ITEM 0x4
|
||||
#define LDML_LENGTH_META 0x24
|
||||
#define LDML_LENGTH_META 0x28
|
||||
#define LDML_LENGTH_SECT 0x10
|
||||
#define LDML_LENGTH_SECT_ITEM 0x8
|
||||
#define LDML_LENGTH_STRS 0x10
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ export const constants: Constants = {
|
|||
/**
|
||||
* length of the 'meta' section
|
||||
*/
|
||||
length_meta: 36,
|
||||
length_meta: 40,
|
||||
/**
|
||||
* bitwise or value for fallback=omit in meta.settings
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -34,6 +34,11 @@ namespace kmx {
|
|||
#pragma warning ( disable : 4200 )
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Indicates an offset into the strs table (0 = zero length)
|
||||
*/
|
||||
typedef KMX_DWORD KMXPLUS_STR;
|
||||
|
||||
struct COMP_KMXPLUS_HEADER {
|
||||
KMX_DWORD ident; // 0000 Section name
|
||||
KMX_DWORD size; // 0004 Section length
|
||||
|
|
@ -105,12 +110,13 @@ static_assert(sizeof(struct COMP_KMXPLUS_STRS) == LDML_LENGTH_STRS, "mismatched
|
|||
struct COMP_KMXPLUS_META {
|
||||
static const KMX_DWORD IDENT = LDML_SECTIONID_META;
|
||||
COMP_KMXPLUS_HEADER header;
|
||||
KMX_DWORD name;
|
||||
KMX_DWORD author;
|
||||
KMX_DWORD conform;
|
||||
KMX_DWORD layout;
|
||||
KMX_DWORD normalization;
|
||||
KMX_DWORD indicator;
|
||||
KMXPLUS_STR name;
|
||||
KMXPLUS_STR author;
|
||||
KMXPLUS_STR conform;
|
||||
KMXPLUS_STR layout;
|
||||
KMXPLUS_STR normalization;
|
||||
KMXPLUS_STR indicator;
|
||||
KMXPLUS_STR version;
|
||||
KMX_DWORD settings;
|
||||
/**
|
||||
* @brief True if section is valid.
|
||||
|
|
@ -121,7 +127,7 @@ struct COMP_KMXPLUS_META {
|
|||
static_assert(sizeof(struct COMP_KMXPLUS_META) == LDML_LENGTH_META, "mismatched size of section meta");
|
||||
|
||||
struct COMP_KMXPLUS_LOCA_ENTRY {
|
||||
KMX_DWORD locale; // 0010+ locale string entry
|
||||
KMXPLUS_STR locale; // 0010+ locale string entry
|
||||
};
|
||||
|
||||
struct COMP_KMXPLUS_LOCA {
|
||||
|
|
@ -142,7 +148,7 @@ static_assert(sizeof(struct COMP_KMXPLUS_LOCA) == LDML_LENGTH_LOCA, "mismatched
|
|||
struct COMP_KMXPLUS_KEYS_ENTRY {
|
||||
KMX_DWORD vkey;
|
||||
KMX_DWORD mod;
|
||||
KMX_DWORD to;
|
||||
KMX_DWORD to; // to may be KMXPLUS_STR or UTF32 char
|
||||
KMX_DWORD flags;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
"commander": "^3.0.0",
|
||||
"crc-32": "^1.2.2",
|
||||
"restructure": "^3.0.0",
|
||||
"semver": "^7.3.7",
|
||||
"typescript": "^4.5.4",
|
||||
"xml2js": "^0.4.19"
|
||||
},
|
||||
|
|
@ -39,8 +40,9 @@
|
|||
},
|
||||
"mocha": {
|
||||
"spec": "build/test/**/test-*.js",
|
||||
"require": ["source-map-support/register"]
|
||||
|
||||
"require": [
|
||||
"source-map-support/register"
|
||||
]
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { KeyboardSettings, Meta, Meta_NormalizationForm } from "../kmx/kmx-plus"
|
|||
import { isValidEnumValue } from "../util/util";
|
||||
import { CompilerErrors } from "./errors";
|
||||
import { SectionCompiler } from "./section-compiler";
|
||||
import * as semver from "semver";
|
||||
|
||||
export class MetaCompiler extends SectionCompiler {
|
||||
|
||||
|
|
@ -13,17 +14,33 @@ export class MetaCompiler extends SectionCompiler {
|
|||
public validate(): boolean {
|
||||
let valid = true;
|
||||
|
||||
const normalization = this.keyboard.info?.normalization;
|
||||
if(normalization !== undefined) {
|
||||
if(!isValidEnumValue(Meta_NormalizationForm, normalization)) {
|
||||
this.callbacks.reportMessage(CompilerErrors.InvalidNormalization({form: normalization}));
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
valid &&= this.validateNormalization(this.keyboard.info?.normalization);
|
||||
valid &&= this.validateVersion(this.keyboard.version?.number);
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
private validateVersion(versionNumber?: string) {
|
||||
if(versionNumber !== undefined) {
|
||||
if(versionNumber.match(/^[=v]/i)) {
|
||||
// semver ignores a preceding '=' or 'v'
|
||||
return false;
|
||||
}
|
||||
return !!semver.parse(versionNumber, {loose: false, includePrerelease: true});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private validateNormalization(normalization?: string) {
|
||||
if (normalization !== undefined) {
|
||||
if (!isValidEnumValue(Meta_NormalizationForm, normalization)) {
|
||||
this.callbacks.reportMessage(CompilerErrors.InvalidNormalization({ form: normalization }));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public compile(): Meta {
|
||||
let result = new Meta();
|
||||
result.name = this.keyboard.names?.name?.[0]?.value;
|
||||
|
|
@ -32,6 +49,7 @@ export class MetaCompiler extends SectionCompiler {
|
|||
result.layout = this.keyboard.info?.layout;
|
||||
result.normalization = this.keyboard.info?.normalization as Meta_NormalizationForm;
|
||||
result.indicator = this.keyboard.info?.indicator;
|
||||
result.version = this.keyboard.version?.number ?? "0";
|
||||
result.settings =
|
||||
(this.keyboard.settings?.fallback == "omit" ? KeyboardSettings.fallback : 0) |
|
||||
(this.keyboard.settings?.transformFailure == "omit" ? KeyboardSettings.transformFailure : 0) |
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ interface BUILDER_META extends BUILDER_SECTION {
|
|||
layout: number; //str
|
||||
normalization: number; //str
|
||||
indicator: number; //str
|
||||
version: number; //str
|
||||
settings: number; //bitfield
|
||||
};
|
||||
|
||||
|
|
@ -100,7 +101,7 @@ export default class KMXPlusBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
let idx = this.sect_strs.items.findIndex(v => v._value == value);
|
||||
let idx = this.sect_strs.items.findIndex(v => v._value === value);
|
||||
if(idx >= 0) {
|
||||
return idx;
|
||||
}
|
||||
|
|
@ -147,6 +148,7 @@ export default class KMXPlusBuilder {
|
|||
layout: this.alloc_string(this.file.kmxplus.meta.layout),
|
||||
normalization: this.alloc_string(this.file.kmxplus.meta.normalization),
|
||||
indicator: this.alloc_string(this.file.kmxplus.meta.indicator),
|
||||
version: this.alloc_string(this.file.kmxplus.meta.version),
|
||||
settings: this.file.kmxplus.meta.settings ?? 0,
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ export class Meta extends Section {
|
|||
layout: string;
|
||||
normalization: Meta_NormalizationForm;
|
||||
indicator: string;
|
||||
version: string; // semver version string, defaults to "0"
|
||||
settings: KeyboardSettings;
|
||||
};
|
||||
|
||||
|
|
@ -133,6 +134,7 @@ export default class KMXPlusFile extends KMXFile {
|
|||
layout: r.uint32le, //str
|
||||
normalization: r.uint32le, //str
|
||||
indicator: r.uint32le, //str
|
||||
version: r.uint32le, //str
|
||||
settings: r.uint32le, //new r.Bitfield(r.uint32le, ['fallback', 'transformFailure', 'transformPartial'])
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ export interface LKKeyboard {
|
|||
conformsTo?: string;
|
||||
|
||||
locales?: LKLocales;
|
||||
version?: LKVersion;
|
||||
info?: LKInfo;
|
||||
names?: LKNames;
|
||||
settings?: LKSettings;
|
||||
|
|
@ -34,6 +35,10 @@ export interface LKLocale {
|
|||
id?: string;
|
||||
};
|
||||
|
||||
export interface LKVersion {
|
||||
number: string; // semver string
|
||||
}
|
||||
|
||||
export interface LKInfo {
|
||||
author?: string;
|
||||
indicator?: string;
|
||||
|
|
|
|||
13
developer/src/kmldmlc/test/fixtures/basic.txt
vendored
13
developer/src/kmldmlc/test/fixtures/basic.txt
vendored
|
|
@ -3,7 +3,7 @@ block(kmxheader) # struct COMP_KEYBOARD {
|
|||
|
||||
00 10 00 00 # KMX_DWORD dwFileVersion; // 0004 Version of the file - Keyman 4.0 is 0x0400
|
||||
|
||||
fc 29 af f8 # KMX_DWORD dwCheckSum; // 0008 As stored in keyboard
|
||||
13 06 7c 19 # KMX_DWORD dwCheckSum; // 0008 As stored in keyboard
|
||||
00 00 00 00 # KMX_DWORD KeyboardID; // 000C as stored in HKEY_LOCAL_MACHINE//system//currentcontrolset//control//keyboard layouts
|
||||
01 00 00 00 # KMX_DWORD IsRegistered; // 0010
|
||||
00 00 00 00 # KMX_DWORD version; // 0014 keyboard version
|
||||
|
|
@ -53,7 +53,7 @@ block(sect) # struct COMP_KMXPLUS_SECT {
|
|||
block(strs) # struct COMP_KMXPLUS_STRS {
|
||||
73 74 72 73 # KMX_DWORD header.ident; // 0000 Section name - strs
|
||||
diff(strs,endstrs) # KMX_DWORD header.size; // 0004 Section length
|
||||
09 00 00 00 # KMX_DWORD count; // 0008 count of str entries
|
||||
0A 00 00 00 # KMX_DWORD count; // 0008 count of str entries
|
||||
00 00 00 00 # KMX_DWORD reserved; // 000C padding
|
||||
|
||||
# Next sections are string entries
|
||||
|
|
@ -66,6 +66,7 @@ block(strs) # struct COMP_KMXPLUS_STRS {
|
|||
diff(strs,strLayout) sizeof(strLayout,2)
|
||||
diff(strs,strNorm) sizeof(strNorm,2)
|
||||
diff(strs,strIndicator) sizeof(strIndicator,2)
|
||||
diff(strs,strVersion) sizeof(strVersion,2)
|
||||
diff(strs,strLocale) sizeof(strLocale,2)
|
||||
diff(strs,strKey1) sizeof(strKey1,2)
|
||||
diff(strs,strKey2) sizeof(strKey2,2)
|
||||
|
|
@ -81,6 +82,7 @@ block(strConformsTo) 74 00 65 00 63 00 68 00 70 00 72 00 65 00 76 00
|
|||
block(strLayout) 71 00 77 00 65 00 72 00 74 00 79 00 block(x) 00 00 # 3:qwerty
|
||||
block(strNorm) 4e 00 46 00 43 00 block(x) 00 00 # 4:NFC
|
||||
block(strIndicator) 3d d8 40 de block(x) 00 00 # 5:🙀
|
||||
block(strVersion) 30 00 block(x) 00 00 # 6:0
|
||||
block(strLocale) 6d 00 74 00 block(x) 00 00 # 7:mt
|
||||
block(strKey1) 27 01 block(x) 00 00 # 8:ħ
|
||||
block(strKey2) 90 17 b6 17 block(x) 00 00 # 9:ថា
|
||||
|
|
@ -96,6 +98,7 @@ block(meta) # struct COMP_KMXPLUS_META {
|
|||
03 00 00 00 # KMX_DWORD layout;
|
||||
04 00 00 00 # KMX_DWORD normalization;
|
||||
05 00 00 00 # KMX_DWORD indicator;
|
||||
06 00 00 00 # KMX_DWORD version;
|
||||
00 00 00 00 # KMX_DWORD settings;
|
||||
# };
|
||||
|
||||
|
|
@ -104,7 +107,7 @@ block(loca) # struct COMP_KMXPLUS_LOCA {
|
|||
sizeof(loca) # KMX_DWORD header.size; // 0004 Section length
|
||||
01 00 00 00 # KMX_DWORD count; // 0008 number of locales
|
||||
00 00 00 00 # KMX_DWORD reserved;
|
||||
06 00 00 00 # KMX_DWORD locale; // 0010+ locale string entry = 'mt'
|
||||
07 00 00 00 # KMX_DWORD locale; // 0010+ locale string entry = 'mt'
|
||||
# };
|
||||
|
||||
block(keys) # struct COMP_KMXPLUS_KEYS {
|
||||
|
|
@ -116,7 +119,7 @@ block(keys) # struct COMP_KMXPLUS_KEYS {
|
|||
|
||||
# Keys data:
|
||||
|
||||
c0 00 00 00 00 00 00 00 07 00 00 00 01 00 00 00 # KMX_DWORD vkey, mod, to, flags;
|
||||
31 00 00 00 00 00 00 00 08 00 00 00 01 00 00 00 # KMX_DWORD vkey, mod, to, flags;
|
||||
c0 00 00 00 00 00 00 00 08 00 00 00 01 00 00 00 # KMX_DWORD vkey, mod, to, flags;
|
||||
31 00 00 00 00 00 00 00 09 00 00 00 01 00 00 00 # KMX_DWORD vkey, mod, to, flags;
|
||||
|
||||
block(eof) # end of file
|
||||
50
package-lock.json
generated
50
package-lock.json
generated
|
|
@ -477,6 +477,7 @@
|
|||
"commander": "^3.0.0",
|
||||
"crc-32": "^1.2.2",
|
||||
"restructure": "^3.0.0",
|
||||
"semver": "^7.3.7",
|
||||
"typescript": "^4.5.4",
|
||||
"xml2js": "^0.4.19"
|
||||
},
|
||||
|
|
@ -4561,12 +4562,14 @@
|
|||
"integrity": "sha1-tcg1G5Rky9dQM1p5ZQoOwOVhGN0="
|
||||
},
|
||||
"node_modules/lru-cache": {
|
||||
"version": "7.8.1",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.8.1.tgz",
|
||||
"integrity": "sha512-E1v547OCgJvbvevfjgK9sNKIVXO96NnsTsFPBlg4ZxjhsJSODoH9lk8Bm0OxvHNm6Vm5Yqkl/1fErDxhYL8Skg==",
|
||||
"devOptional": true,
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
|
||||
"dependencies": {
|
||||
"yallist": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/macos-release": {
|
||||
|
|
@ -5867,18 +5870,17 @@
|
|||
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
|
||||
},
|
||||
"node_modules/semver": {
|
||||
"version": "7.3.6",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.6.tgz",
|
||||
"integrity": "sha512-HZWqcgwLsjaX1HBD31msI/rXktuIhS+lWvdE4kN9z+8IVT4Itc7vqU2WvYsyD6/sjYCt4dEKH/m1M3dwI9CC5w==",
|
||||
"devOptional": true,
|
||||
"version": "7.3.7",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
|
||||
"integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
|
||||
"dependencies": {
|
||||
"lru-cache": "^7.4.0"
|
||||
"lru-cache": "^6.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^10.0.0 || ^12.0.0 || ^14.0.0 || >=16.0.0"
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/send": {
|
||||
|
|
@ -6884,8 +6886,7 @@
|
|||
"node_modules/yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
|
||||
"optional": true
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
|
||||
},
|
||||
"node_modules/yaml": {
|
||||
"version": "1.10.2",
|
||||
|
|
@ -7814,6 +7815,7 @@
|
|||
"crc-32": "^1.2.2",
|
||||
"mocha": "^8.4.0",
|
||||
"restructure": "^3.0.0",
|
||||
"semver": "*",
|
||||
"ts-node": "^9.1.1",
|
||||
"typescript": "^4.5.4",
|
||||
"xml2js": "^0.4.19"
|
||||
|
|
@ -11003,10 +11005,12 @@
|
|||
"integrity": "sha1-tcg1G5Rky9dQM1p5ZQoOwOVhGN0="
|
||||
},
|
||||
"lru-cache": {
|
||||
"version": "7.8.1",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.8.1.tgz",
|
||||
"integrity": "sha512-E1v547OCgJvbvevfjgK9sNKIVXO96NnsTsFPBlg4ZxjhsJSODoH9lk8Bm0OxvHNm6Vm5Yqkl/1fErDxhYL8Skg==",
|
||||
"devOptional": true
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
|
||||
"requires": {
|
||||
"yallist": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"macos-release": {
|
||||
"version": "2.5.0",
|
||||
|
|
@ -11986,12 +11990,11 @@
|
|||
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
|
||||
},
|
||||
"semver": {
|
||||
"version": "7.3.6",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.6.tgz",
|
||||
"integrity": "sha512-HZWqcgwLsjaX1HBD31msI/rXktuIhS+lWvdE4kN9z+8IVT4Itc7vqU2WvYsyD6/sjYCt4dEKH/m1M3dwI9CC5w==",
|
||||
"devOptional": true,
|
||||
"version": "7.3.7",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
|
||||
"integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
|
||||
"requires": {
|
||||
"lru-cache": "^7.4.0"
|
||||
"lru-cache": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"send": {
|
||||
|
|
@ -12756,8 +12759,7 @@
|
|||
"yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
|
||||
"optional": true
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
|
||||
},
|
||||
"yaml": {
|
||||
"version": "1.10.2",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue