diff --git a/developer/src/kmldmlc/src/keyman/compiler/compiler.ts b/developer/src/kmldmlc/src/keyman/compiler/compiler.ts index de1b171645..e42b10409e 100644 --- a/developer/src/kmldmlc/src/keyman/compiler/compiler.ts +++ b/developer/src/kmldmlc/src/keyman/compiler/compiler.ts @@ -1,9 +1,11 @@ import KMXBuilder from '../kmx/kmx-builder'; import KMXPlusFile from '../kmx/kmx-plus'; -import LDMLKeyboardXMLSourceFile, * as LDMLKeyboard from '../ldml-keyboard/ldml-keyboard-xml'; +import LDMLKeyboardXMLSourceFile from '../ldml-keyboard/ldml-keyboard-xml'; import LDMLKeyboardXMLSourceFileReader from '../ldml-keyboard/ldml-keyboard-xml-reader'; -import { USVirtualKeyMap } from '../ldml-keyboard/us-virtual-keys'; import CompilerCallbacks from './callbacks'; +import { KeysCompiler } from './keys'; +import { LocaCompiler } from './loca'; +import { MetaCompiler } from './meta'; export default class Compiler { private callbacks: CompilerCallbacks; @@ -14,55 +16,6 @@ export default class Compiler { this.callbacks.reportMessage(0, "Instantiated compiler successfully"); } - private translateLayerIdToModifier(id: string) { - if(id == 'base') { - return 0; - } - // TODO: other modifiers - return 0; - } - - private compileHardwareLayer( - keyboard: LDMLKeyboard.LKKeyboard, - layer: LDMLKeyboard.LKLayerMap, - kmx: KMXPlusFile - ) { - const mod = this.translateLayerIdToModifier(layer.id); - - let y = -1; - for(let row of layer.row) { - y++; - if(y > USVirtualKeyMap.length) { - this.callbacks.reportMessage(0, `'hardware' layer has too many rows`); - break; - } - - const keys = row.keys.split(' '); - let x = -1; - for(let key of keys) { - x++; - if(x > USVirtualKeyMap[y].length) { - this.callbacks.reportMessage(0, `Row #${y+1} on 'hardware' layer has too many keys`); - break; - } - - let keydef = keyboard.keys?.key?.find(x => x.id == key); - if(!keydef) { - this.callbacks.reportMessage(0, - `Key ${key} in position #${x+1} on row #${y+1} of layer ${layer.id}, form 'hardware' not found in key bag`); - continue; - } - - kmx.kmxplus.keys.keys.push({ - vkey: USVirtualKeyMap[y][x], - mod: mod, - to: keydef.to, - flags: 0 // Note: 'expand' is never set here, only by the .kmx builder - }); - } - } - } - /** * Loads a LDML Keyboard xml file and compiles into in-memory kmxplus * structures. @@ -108,22 +61,9 @@ export default class Compiler { // Transform source xml structures to kmxplus - kmx.kmxplus.meta.name = source.keyboard.names?.name?.[0]?.value; - kmx.kmxplus.meta.author = source.keyboard.info?.author; - kmx.kmxplus.meta.conform = source.keyboard.conformsTo; - kmx.kmxplus.meta.layout = source.keyboard.info?.layout; - kmx.kmxplus.meta.normalization = source.keyboard.info?.normalization; - kmx.kmxplus.meta.indicator = source.keyboard.info?.indicator; - - kmx.kmxplus.loca.locales.push(source.keyboard.locale); - - // Use LayerMap + keys to generate compiled keys for hardware - - if(source.keyboard.layerMaps?.[0]?.form == 'hardware') { - for(let layer of source.keyboard.layerMaps[0].layerMap) { - this.compileHardwareLayer(source.keyboard, layer, kmx); - } - } + (new MetaCompiler(kmx, source, this.callbacks)).execute(); + (new LocaCompiler(kmx, source, this.callbacks)).execute(); + (new KeysCompiler(kmx, source, this.callbacks)).execute(); // TODO: generate vkey mapping for touch-only keys @@ -136,3 +76,4 @@ export default class Compiler { return builder.compile(); } } + diff --git a/developer/src/kmldmlc/src/keyman/compiler/keys.ts b/developer/src/kmldmlc/src/keyman/compiler/keys.ts new file mode 100644 index 0000000000..0c3b56f779 --- /dev/null +++ b/developer/src/kmldmlc/src/keyman/compiler/keys.ts @@ -0,0 +1,64 @@ +import * as LDMLKeyboard from '../ldml-keyboard/ldml-keyboard-xml'; +import { USVirtualKeyMap } from "../ldml-keyboard/us-virtual-keys"; + +import { SectionCompiler } from "./section-compiler"; + +export class KeysCompiler extends SectionCompiler { + + public execute() { + // Use LayerMap + keys to generate compiled keys for hardware + + if(this.source.keyboard.layerMaps?.[0]?.form == 'hardware') { + for(let layer of this.source.keyboard.layerMaps[0].layerMap) { + this.compileHardwareLayer(layer); + } + } + } + + private compileHardwareLayer( + layer: LDMLKeyboard.LKLayerMap + ) { + const mod = this.translateLayerIdToModifier(layer.id); + + let y = -1; + for(let row of layer.row) { + y++; + if(y > USVirtualKeyMap.length) { + this.callbacks.reportMessage(0, `'hardware' layer has too many rows`); + break; + } + + const keys = row.keys.split(' '); + let x = -1; + for(let key of keys) { + x++; + if(x > USVirtualKeyMap[y].length) { + this.callbacks.reportMessage(0, `Row #${y+1} on 'hardware' layer has too many keys`); + break; + } + + let keydef = this.source.keyboard.keys?.key?.find(x => x.id == key); + if(!keydef) { + this.callbacks.reportMessage(0, + `Key ${key} in position #${x+1} on row #${y+1} of layer ${layer.id}, form 'hardware' not found in key bag`); + continue; + } + + this.kmx.kmxplus.keys.keys.push({ + vkey: USVirtualKeyMap[y][x], + mod: mod, + to: keydef.to, + flags: 0 // Note: 'expand' is never set here, only by the .kmx builder + }); + } + } + } + + private translateLayerIdToModifier(id: string) { + if(id == 'base') { + return 0; + } + // TODO: other modifiers + return 0; + } +} \ No newline at end of file diff --git a/developer/src/kmldmlc/src/keyman/compiler/loca.ts b/developer/src/kmldmlc/src/keyman/compiler/loca.ts new file mode 100644 index 0000000000..3a9783c0b2 --- /dev/null +++ b/developer/src/kmldmlc/src/keyman/compiler/loca.ts @@ -0,0 +1,8 @@ +import { SectionCompiler } from "./section-compiler"; + +export class LocaCompiler extends SectionCompiler { + + public execute() { + this.kmx.kmxplus.loca.locales.push(this.source.keyboard.locale); + } +} diff --git a/developer/src/kmldmlc/src/keyman/compiler/meta.ts b/developer/src/kmldmlc/src/keyman/compiler/meta.ts new file mode 100644 index 0000000000..0b4c0ebe30 --- /dev/null +++ b/developer/src/kmldmlc/src/keyman/compiler/meta.ts @@ -0,0 +1,13 @@ +import { SectionCompiler } from "./section-compiler"; + +export class MetaCompiler extends SectionCompiler { + + public execute() { + this.kmx.kmxplus.meta.name = this.source.keyboard.names?.name?.[0]?.value; + this.kmx.kmxplus.meta.author = this.source.keyboard.info?.author; + this.kmx.kmxplus.meta.conform = this.source.keyboard.conformsTo; + this.kmx.kmxplus.meta.layout = this.source.keyboard.info?.layout; + this.kmx.kmxplus.meta.normalization = this.source.keyboard.info?.normalization; + this.kmx.kmxplus.meta.indicator = this.source.keyboard.info?.indicator; + } +} \ No newline at end of file diff --git a/developer/src/kmldmlc/src/keyman/compiler/section-compiler.ts b/developer/src/kmldmlc/src/keyman/compiler/section-compiler.ts new file mode 100644 index 0000000000..53b3422782 --- /dev/null +++ b/developer/src/kmldmlc/src/keyman/compiler/section-compiler.ts @@ -0,0 +1,18 @@ +import KMXPlusFile from "../kmx/kmx-plus"; +import LDMLKeyboardXMLSourceFile from "../ldml-keyboard/ldml-keyboard-xml"; +import CompilerCallbacks from "./callbacks"; + +export class SectionCompiler { + private _kmx: KMXPlusFile; + private _source: LDMLKeyboardXMLSourceFile; + private _callbacks: CompilerCallbacks; + + constructor(kmx: KMXPlusFile, source: LDMLKeyboardXMLSourceFile, callbacks: CompilerCallbacks) { + this._kmx = kmx; + this._source = source; + } + + get kmx() { return this._kmx; } + get source() { return this._source; } + get callbacks() { return this._callbacks; } +} \ No newline at end of file