diff --git a/developer/src/kmc-convert/src/keylayout-to-kmn/keylayout-to-kmn-converter.ts b/developer/src/kmc-convert/src/keylayout-to-kmn/keylayout-to-kmn-converter.ts
index fff0a3da05..44d3552b88 100644
--- a/developer/src/kmc-convert/src/keylayout-to-kmn/keylayout-to-kmn-converter.ts
+++ b/developer/src/kmc-convert/src/keylayout-to-kmn/keylayout-to-kmn-converter.ts
@@ -46,7 +46,7 @@ import boxXmlArray = util.boxXmlArray;*/
// OK no added NCAPS when first modifier in modifierMap does not contain "caps" or"caps?"
// use length to clear array instead of defining evetry time new (modifierMap_ONE_InKeymapSelect.length=0
// naming of for-loop var i,j,k?...
- // warning if contrADICTING RULES E:G: [ 'modifier_C0', 'SHIFT NCAPS', 'K_C', 'c', '0', '1' ], vs [ 'modifier_C0', 'SHIFT NCAPS', 'K_C', 'C', '1', '0' ],
+ // warning if contrADICTING RULES E:G: [ 'modifier_C0', 'SHIFT NCAPS', 'K_C', 'c'], vs [ 'modifier_C0', 'SHIFT NCAPS', 'K_C', 'C' ],
// print NCAPS as the first of the modifiers in create_kmn_modifier
// use boxXmlArray from codebase instead of my own
// where are rules for action+none ( a, e, u, etc)
@@ -185,13 +185,12 @@ export class KeylayoutToKmnConverter {
*/
public read(filename: string): convert_object {
- const modifierMap_ALL_KeyMapSelects: string[][] = [] // modifier for each keymapselect
+ const modifierBehaviors: string[][] = [] // modifier for each keymapselect
const kmn_Rules_AllLayers: Uint8Array[][] = []
- // TODO remove unneccassary elements
const DataObject: convert_object = {
name: "Ukelele-kmn", // needed?? remove
- ArrayOf_Element_ModifierMaps_ALLKeyMapSelect: modifierMap_ALL_KeyMapSelects, // 18 modifiers in 8 KeyMapSelect(behaviors)
+ ArrayOf_Element_ModifierMaps_ALLKeyMapSelect: modifierBehaviors, // 18 modifiers in 8 KeyMapSelect(behaviors)
ArrayOf_processed_RuleData: kmn_Rules_AllLayers,
};
@@ -214,29 +213,23 @@ export class KeylayoutToKmnConverter {
const parser = new XMLParser(options);
const jsonObj = parser.parse(xmlFile); // get plain Object
- // const duplicate_layouts_array: string[] = [] // array holding the layouts e.g. ANSI or JIS // needed?? I think no
-
// jsonObj now contains only arrays; no single fields
boxArrays_S(jsonObj.keyboard);
- // in case there always ANSI which is always keyMapSet[0]
- // const keyMapSet_ANSI_count = 0
-
// .........................................................
// MODIFIER MAP: get behaviours(=MapIndex) and modifiers (shift? leftShift caps? )
// .........................................................
for (let j = 0; j < jsonObj.keyboard.modifierMap.keyMapSelect.length; j++) {
- const modifierMap_ONE_InKeymapSelect: string[] = []
+ const singleModifierSet: string[] = []
for (let k = 0; k < jsonObj.keyboard.modifierMap.keyMapSelect[j].modifier.length; k++) {
- modifierMap_ONE_InKeymapSelect.push(jsonObj.keyboard.modifierMap.keyMapSelect[j].modifier[k]['@_keys'])
+ singleModifierSet.push(jsonObj.keyboard.modifierMap.keyMapSelect[j].modifier[k]['@_keys'])
}
- modifierMap_ALL_KeyMapSelects.push(modifierMap_ONE_InKeymapSelect)
+ modifierBehaviors.push(singleModifierSet)
}
// Todo ? move to convert?
// TODO review condition
- // start to read other data
return this.createRuleData(DataObject, jsonObj)
}
@@ -260,41 +253,10 @@ export class KeylayoutToKmnConverter {
//TODO need to use export const USVirtualKeyCodes here
public write(data_ukelele: convert_object): boolean {
- // *************************************************************
- // **** write stores *******************************************
- // *************************************************************
let data = "\n"
- data += "c\n"
- data += "c Keyman keyboard generated by kmn-convert\n"
- data += "c\n"
+ data += this.createDataToWrite(data_ukelele)
data += "\n"
- data += '\########## OK #################################################################\n'
- data += "store(&VERSION) \'...\'\n"
- data += "store(&TARGETS) \'any\'\n"
- data += "store(&KEYBOARDVERSION) \'...\'\n"
- data += "store(©RIGHT) '© 2024 SIL International\n"
- // TODO what else ??
-
- data += '\########## OK #################################################################\n'
- data += "\n"
- data += "begin Unicode > use(main)\n\n"
- data += "group(main) using keys\n\n"
-
- data += '\########## OK #################################################################\n'
- data += "Tipp: if K_? is replaced by undefined-> no enry in kmn_Key_Name=> add K_? there and it will be shown here\n"
- data += "Tipp: keys that are marked with sction do not aoear in ukelele_Array_output->do not appear in kmn\n"
- data += "\n"
-
- // *************************************************************
- // **** write rules ********************************************
- // *************************************************************
-
- // if caps is used in .keylayout-file we need to add NCAPS in the kmn-file
-
-
- data += this.writeLastPart(data_ukelele) + '\n'
-
/*writeFileSync("data/MyResult.kmn", data, { flag: "w" })*/
this.callbacks.fs.writeFileSync("data/MyResult.kmn", new TextEncoder().encode(data)) // not usable here since it takes UInt8array data
@@ -307,13 +269,9 @@ export class KeylayoutToKmnConverter {
data += '\n'
}
-
- //... helpers .............................................................................................
-
// TODO move outside of class?
// ToDo keep only uint8array-version
- // for more info about mapping and cases C0-C4
- // see https://docs.google.com/document/d/1ISjACTA9aUBueTo1AoKnOsI6QR5kXeeD_maI0XUyXqg/edit?tab=t.0
+ // for more info about mapping and cases C0-C4 see https://docs.google.com/document/d/1ISjACTA9aUBueTo1AoKnOsI6QR5kXeeD_maI0XUyXqg/edit?tab=t.0
public createRuleData(data_ukelele: convert_object, jsonObj: any): convert_object {
const DataArray_U8: Uint8Array[][] = []
@@ -323,16 +281,15 @@ export class KeylayoutToKmnConverter {
const used_Keys_count = 51
const isCapsused = this.checkIfCapsUsed(data_ukelele.ArrayOf_Element_ModifierMaps_ALLKeyMapSelect)
- // loop keys 0-50 (= all that we use)
- //for (let j = 0; j < jsonObj.keyboard.keyMapSet[0].keyMap[i].key.length; j++) {
+ // loop keys 0-50 (= all keys we use)
for (let j = 0; j < used_Keys_count; j++) {
- // loop behaviors
+ // loop behaviors ( in ukelele it is possible to define multiple modifier combinations that behave the same)
for (let i = 0; i < jsonObj.keyboard.keyMapSet[0].keyMap.length; i++) {
// ......................................................................................................
// case C0: output ......................................................................................
- // a key is mapped to a character ( code-> output) ......................................................
+ // a key is mapped to a character directly ( code-> output) .............................................
// ...............e. g. ......................................................
// ......................................................................................................
// in keys at top for code 1 (K_S) take output ("s") [italian copy]
@@ -343,7 +300,7 @@ export class KeylayoutToKmnConverter {
if (jsonObj.keyboard.keyMapSet[0].keyMap[i].key[j]['@_output'] !== undefined) {
output_id = jsonObj.keyboard.keyMapSet[0].keyMap[i].key[j]['@_output']
- // loop modifiers
+ // loop modifier combinations
for (let l = 0; l < data_ukelele.ArrayOf_Element_ModifierMaps_ALLKeyMapSelect[i].length; l++) {
const DataArraySingleStateC0_U8: Uint8Array[] = []
@@ -363,29 +320,26 @@ export class KeylayoutToKmnConverter {
}
// ......................................................................................................
- // actions ...............................................................................
+ // case C1: action + state none + output ................................................................
+ // a key is mapped to an action and then to an output ...................................................
+ // code->action->action(none)->action(output) ...........................................................
+ // ...............e. g. a
// ......................................................................................................
-
else if (jsonObj.keyboard.keyMapSet[0].keyMap[i].key[j]['@_action'] !== undefined) {
- // ......................................................................................................
- // case C1: action + state none + output ..............................................................
- // a key is mapped to an action and then to an output ...................................................
- // code->action->action(none)->action(output) ...........................................................
- // ...............e. g. a
- // ......................................................................................................
+
action_id = jsonObj.keyboard.keyMapSet[0].keyMap[i].key[j]['@_action']
const result_C1 = this.lookup_6_ActionNone__To__ActionOutput(jsonObj, action_id)
const result_C1_U8 = new TextEncoder().encode(this.lookup_6_ActionNone__To__ActionOutput(jsonObj, action_id))
- // modifiers
+ // loop modifiers
for (let l = 0; l < data_ukelele.ArrayOf_Element_ModifierMaps_ALLKeyMapSelect[i].length; l++) {
const DataArraySingleStateC1_U8: Uint8Array[] = []
@@ -547,7 +501,7 @@ export class KeylayoutToKmnConverter {
}
}
// ......................................................................................................
- // case C4: action + state none + Next ............................................................DONE .
+ // case C4: action + state none + Next ..................................................................
// ...............e. g. ...................................................
// a key is mapped to an action and then to a terminator ................................................
// code->action->action(none)->action(next)->terminator(output) .........................................
@@ -596,8 +550,6 @@ export class KeylayoutToKmnConverter {
return data_ukelele
}
-
- // public lookup_2_KeyMapAction__To__ActionAction() { }
public lookup_3_ActionNone__To__ActionNext(data: any, search: string): string {
for (let jj = 0; jj < data.keyboard.actions.action.length; jj++) {
if (data.keyboard.actions.action[jj]['@_id'] === search) {
@@ -609,7 +561,6 @@ export class KeylayoutToKmnConverter {
}
return ""
}
- //public lookup_4_ActionNext__To__ActionState() { }
public lookup_5_ActionState__To__ActionNext(data: any, action_idName: string): string[] {
const returnarray: string[] = []
// e.g. action_idName = 3
@@ -658,17 +609,6 @@ export class KeylayoutToKmnConverter {
}
return OutputValue
}
- //public lookup_7_ActionState__To__ActionOutput() { }
- //public lookup_8_ActionNext__To__TerminatorState() { }
-
- public lookup_9_TerminatorState__To__TerminatorOutput_ui8(data: any, search: string): Uint8Array {
- for (let jj = 0; jj < data.keyboard.terminators.when.length; jj++) {
- if (data.keyboard.terminators.when[jj]['@_state'] === search) {
- return new TextEncoder().encode(data.keyboard.terminators.when[jj]['@_output']);
- }
- }
- return new TextEncoder().encode("")
- }
public lookup_9_TerminatorState__To__TerminatorOutput_str(data: any, search: string): string {
let OutputValue = ""
for (let jj = 0; jj < data.keyboard.terminators.when.length; jj++) {
@@ -695,31 +635,6 @@ export class KeylayoutToKmnConverter {
}
return 999
}
- public lookup_11_KeyMapAction__To__KeyIndex(data: any, search: string): number {
- for (let kk = 0; kk < data.keyboard.keyMapSet[0].keyMap.length; kk++) {
- for (let jj = 0; jj < data.keyboard.keyMapSet[0].keyMap[kk].key.length; jj++) {
- if (data.keyboard.keyMapSet[0].keyMap[kk].key[jj]['@_action'] === search) {
- return data.keyboard.keyMapSet[0].keyMap[kk]['@_index']
- }
- }
- }
- return 999
- }
- // get all entries that result in state 3
- public lookup_12_ActionNext__from__ActionState(data: any, search: string): string {
- // loop all action
- for (let jj = 0; jj < data.keyboard.actions.action.length; jj++) {
- // loop all when
- for (let kk = 0; kk < data.keyboard.actions.action[jj].when.length; kk++) {
- // if next === a´search
- if (data.keyboard.actions.action[jj].when[kk]['@_next'] === search) {
- // return actionIDName
- return data.keyboard.actions.action[jj]['@_id']
- }
- }
- }
- return ""
- }
public lookup_13_ActionNext__To__ActionID(data: any, search: string) {
for (let ll = 0; ll < data.keyboard.actions.action.length; ll++) {
for (let mm = 0; mm < data.keyboard.actions.action[ll].when.length; mm++) {
@@ -747,7 +662,6 @@ export class KeylayoutToKmnConverter {
return mapIndexArray_max
}
-
/**
* @brief member function to return the unicode value of a character
* @param character the value that will converted
@@ -905,85 +819,19 @@ export class KeylayoutToKmnConverter {
else return ""
}
- public useElementAsString(u18ArrayElemnent: Uint8Array): string {
- return new TextDecoder().decode(u18ArrayElemnent)
- }
- public useAsString(u18ArrayElemnent: Uint8Array[]): string {
- let str = ""
- for (let i = 0; i < u18ArrayElemnent.length; i++) {
- str = str + " " + new TextDecoder().decode(u18ArrayElemnent[i])
- }
- return str
- }
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
- public writeLastPart(data_ukelele: convert_object): string {
- // create a string array .......................................................
- const workArray2D: string[][] = []
- for (let k = 0; k < data_ukelele.ArrayOf_processed_RuleData.length; k++) {
- const array1D: string[] = []
- for (let l = 0; l < data_ukelele.ArrayOf_processed_RuleData[k].length; l++) {
- const u8data = data_ukelele.ArrayOf_processed_RuleData[k][l]
- array1D.push(this.useElementAsString(u8data))
- }
- workArray2D.push(array1D)
- }
- console.log("workArray2D ", workArray2D)
+ public createData_Deadkeys(data_ukelele: convert_object, workArray2D: string[][]): string {
- //°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
- // FIRST PART RULES °° ( + [NCAPS K_S] > 's') °°°°°°°°°°°°°°°°°°°°°
- //°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
let data: string = ""
-
- // select only lines that contain C0 or C1 and no empty fields. Also remove duplicates
- const [uniqueDeadkeys_first] = workArray2D.reduce((acc, curr) => {
- if ((curr[3] !== "") && ((curr[0] === "first_modifier_C0") || (curr[0] === "first_modifier_C1"))) {
- const [uniq, set] = acc;
- if (!set.has(curr.join(','))) {
- set.add(curr.join(','));
- uniq.push(curr);
- }
- }
- return acc;
- }, [[], new Set()],
- );
-
-
- let keymarker = ""
- for (let kkk = 0; kkk < uniqueDeadkeys_first.length; kkk++) {
-
- // find key nr
- let keyNr = 0;
- for (let pp = 0; pp < 50; pp++) {
- if (this.map_UkeleleKC_To_VK(pp) === uniqueDeadkeys_first[kkk][2])
- keyNr = pp
- }
-
- // skip keyNr 48 ( TAB )
- if (keyNr === 48)
- continue
-
- if (keymarker !== uniqueDeadkeys_first[kkk][2])
- data += '\n'
-
- data += keyNr + "-(modif:" + "ii" + "-" + "i" + `) + [` + (uniqueDeadkeys_first[kkk][1] + ' ' + uniqueDeadkeys_first[kkk][2]).trim() + `] > \'` + uniqueDeadkeys_first[kkk][3] + '\'\n'
- keymarker = uniqueDeadkeys_first[kkk][2]
- }
- data += '\n'
- console.log("data ", data)
-
- //°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
- // DEADKEY RULES °° ([RALT K_8] > dk(00B4) °°°°°°°°°°°°°°°°°°°°°°°°
- //°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
-
// filter for dk values
data += '\########## OK #################################################################\n'
data += '\nNOW MY C4 RULES **ccc ********* (only to get 02C6 ect) *********************\n\n'
- // select only lines that contain isTerminator and remove duplicates
+ // select only lines that contain "isTerminator" and remove duplicates
const [uniqueDeadkeys] = workArray2D.reduce((acc, curr) => {
if (curr[4] === "isTerminator") {
const [uniq, set] = acc;
@@ -1002,43 +850,42 @@ export class KeylayoutToKmnConverter {
data += line + '\n'
}
- //°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
- // DEADKEYABLE/DEADKEYED LIST (a,A,e,E) - (â,Â,ê,ê) °°°°°°°°°°°°°°°
- //°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
- // we have 5 different types:
- /*
- C0: size: 4 ['first_modifier_C0', 'RIGHTSHIFT ', 'K_S', 'S' ]
- C1: size: 4 ['first_modifier_C1', 'CAPS', 'K_N', 'N' ],
- C2: size: 5 ['first_modifier_C2', 'CAPS', 'K_E', 'K_9', 'È' ], use 2.(K_E) and 4.('È') to get Name and DEADKEYED
- C3: size: 6 ['first_modifier_C3', 'NCAPS RALT', 'K_8', 'NCAPS RALT', 'K_U', 'ˆ' ],
- C4: size: 4 ['first_modifier_C4', 'NCAPS 0', 'K_SPACE', '' ],
- C4: size: 7 ['first_modifier_C4', 'NCAPS RALT', 'K_N', '˜', 'isTerminator', '˜', '02DC '], use 2.(K_N) , 5. (isTerminator) and 6.('02DC') to get Name and DEADKEY in hex
+
+ /*
+ How to create rules from keylayout data ffrom data_ukelele.ArrayOf_processed_RuleData:
+
+ There are 6 different types of data entries (C0-C4) in data_ukelele.ArrayOf_processed_RuleData e.g. that contain all data to retrieve deadkeys, deadkeyables and deadkeyed characters:
+
+ C0: (size: 4) ['first_modifier_C0', 'RIGHTSHIFT ', 'K_S', 'S' ]
+ C1: (size: 4) ['first_modifier_C1', 'CAPS', 'K_A', 'A' ],
+ C2: (size: 5) ['first_modifier_C2', 'CAPS', 'K_A', 'K_N', 'Ã' ], use 2.(K_A) and 4.('Ã') to get name and DEADKEYED
+ C3: (size: 6) ['first_modifier_C3', 'NCAPS RALT', 'K_8', 'NCAPS RALT', 'K_U', 'ˆ' ],
+ C4: (size: 4) ['first_modifier_C4', 'NCAPS 0', 'K_SPACE', '' ],
+ C4: (size: 7) ['first_modifier_C4', 'NCAPS RALT', 'K_N', '˜', 'isTerminator', '˜', '02DC '], use 2.(K_N) , 5. (isTerminator) and 6.('02DC') to get key name and DEADKEY in hex
- Find DEADKEYABLE
- 1) first_modifier_C1 CAPS K_A A
- 2) first_modifier_C2 CAPS K_A K_EQUAL Â
- 3) first_modifier_C2 CAPS K_A K_9 À
- - Find C2 rule with Deadkeyed ( n = 5)
- - get C1 rule with same second and third entries -> (first_modifier_C1 CAPS K_A)
- - get 4th entry ===> DEADKEYABLE (e.g. A)
+ To Find a DEADKEY e.g. ^
+ 1) look in modifier_C4 with 'isTerminator' included (n = 7)
+ 2) get 7th entry ===> DEADKEY (e.g. 02DC)
+
+ To Find a DEADKEYABLE ( a character that can be converted to a deadkey e.g. A (-> Ã) ):
+ 1) first_modifier_C1 CAPS K_A A
+ 2) first_modifier_C2 CAPS K_A K_N Ã
+ - Find C2 rule with 5 entries (Deadkeyed) (e.g. first_modifier_C2 CAPS K_A K_N Ã)
+ - get C1 rule with same second and third entries -> (e.g. first_modifier_C1 CAPS K_A)
+ - get 2nd entry of C1 rule ===> DEADKEYABLE (e.g. A)
- Find DEADKEY
- 1) look in modifier_C4 (n = 7)
- 2) get 7th entry ===> DEADKEY (e.g. 02DC)
-
- Find DEADKEYED
- 1) look in modifier_C2
- 2) get 3rd entry (='K_A')
- 3) get 5th entry ===> DEADKEYED (='Â')
+ To Find a DEADKEYED ( a character that has been converted from another character e.g. Ã ):
+ 1) look in modifier_C2 CAPS K_A K_N Ã
+ 2) get 3rd entry (='K_A')
+ 3) get 5th entry ===> DEADKEYED (='Ã')
*/
- // create deadkeyables_raw, deadkeyed_raw array
let deadkeyables_raw: string[][] = []
let deadkeyed_raw: string[][] = []
- // find deadkeyable [ 'first_modifier_C1', 'CAPS', 'K_A', 'A', '', '', '' ]
- deadkeyables_raw = workArray2D.filter(function ([A, B, C, D, E, F, G]) {
+ // find C1 line for deadkeyable [ 'first_modifier_C1', 'CAPS', 'K_A', 'A' ]
+ deadkeyables_raw = workArray2D.filter(function ([A, B, C, D]) {
return ((A === "first_modifier_C1") /*&& (B === shiftstate) && (C === key_name)*/
&& ((C !== "K_SPACE") && (D !== ""))
)
@@ -1046,8 +893,8 @@ export class KeylayoutToKmnConverter {
console.log("deadkeyables_raw", deadkeyables_raw.length, deadkeyables_raw)
- // find deadkeyed [ 'first_modifier_C2', 'CAPS', 'K_A', 'K_N', 'Ã' ]
- deadkeyed_raw = workArray2D.filter(function ([A, B, C, D, E, F, G]) {
+ // find C2 line for deadkeyed [ 'first_modifier_C2', 'CAPS', 'K_A', 'K_N', 'Ã' ]
+ deadkeyed_raw = workArray2D.filter(function ([A, B, C]) {
return ((A === "first_modifier_C2")/* && (B === shiftstate) && (C === key_name)*/
&& ((C !== "K_SPACE"))
)
@@ -1055,27 +902,29 @@ export class KeylayoutToKmnConverter {
console.log("deadkeyed_raw", deadkeyed_raw.length, deadkeyed_raw)
- const join_dkable_dked: any[][] = []
- // loop dedkeyables, take Keyname
+ const dk_array_comlpete: any[][] = []
+
+ // create 2D array with data of both deadkeyables_raw, deadkeyed_raw and remove possible duplicates
+
+
for (let rr = 0; rr < deadkeyables_raw.length; rr++) {
- // loop dedkeyed, take Keyname
+ // loop deadkeyed_raw, take Keyname
for (let ss = 0; ss < deadkeyed_raw.length; ss++) {
- const dkable_dked_array: any[] = []
- //if available ( shiftstate the same, keyname the same)
- if ((deadkeyables_raw[rr][1] === deadkeyed_raw[ss][1])
- && ((deadkeyables_raw[rr][2] === deadkeyed_raw[ss][2]))) {
- dkable_dked_array.push(deadkeyables_raw[rr][3]) // deadkeyable e.g. a
- dkable_dked_array.push(deadkeyed_raw[ss][3]) // Keyname dk e.g. K_EQUAL
- dkable_dked_array.push(deadkeyed_raw[ss][4]) // deadkeyed e.g. â
+ const dk_array: any[] = []
+ //if available ( if both have the same shiftstate and keyname)
+ if ((deadkeyables_raw[rr][1] === deadkeyed_raw[ss][1]) && ((deadkeyables_raw[rr][2] === deadkeyed_raw[ss][2]))) {
+ dk_array.push(deadkeyables_raw[rr][3]) // deadkeyable e.g. A
+ dk_array.push(deadkeyed_raw[ss][3]) // Keyname dk e.g. K_N
+ dk_array.push(deadkeyed_raw[ss][4]) // deadkeyed e.g. Ã
}
- if (dkable_dked_array.length > 0)
- join_dkable_dked.push(dkable_dked_array)
+ if (dk_array.length > 0)
+ dk_array_comlpete.push(dk_array)
}
}
- console.log("join_dkable_dked", join_dkable_dked.length, join_dkable_dked)
+ console.log("dk_array_comlpete", dk_array_comlpete.length, dk_array_comlpete)
// remove duplicates
- const [unique_join_dkable_dked] = join_dkable_dked.reduce((acc, curr) => {
+ const [unique_dk_array_comlpete] = dk_array_comlpete.reduce((acc, curr) => {
const [uniq, set] = acc;
if (!set.has(curr.join(','))) {
set.add(curr.join(','));
@@ -1084,21 +933,22 @@ export class KeylayoutToKmnConverter {
return acc;
}, [[], new Set()],
);
- console.log("unique_join_dkable_dked", unique_join_dkable_dked.length, unique_join_dkable_dked);
+ console.log("unique_join_dkable_dked", unique_dk_array_comlpete.length, unique_dk_array_comlpete);
- // create 2dArray uniqueDeadkeys.length*unique_join_dkable_dked
- const deadkeyedArray: string[][] = Array.from({ length: uniqueDeadkeys.length }, () => new Array(2).fill(''));
- const deadkeyablesArray: string[][] = Array.from({ length: uniqueDeadkeys.length }, () => new Array(1).fill(''));
+ // deadkeyablesArray'a' 'A' 'e' 'E' 'y' 'Y' 'o' 'O' 'u' 'U' 'i' 'I'
+ // deadkeyedArray 'ä' 'Ä' 'ë' 'Ë' 'ÿ' 'Ÿ' 'ö' 'Ö' 'ü' 'Ü' 'ï' 'Ï'
+ const deadkeyedElement: string[][] = Array.from({ length: uniqueDeadkeys.length }, () => new Array(2).fill(''));
+ const deadkeyablesElement: string[][] = Array.from({ length: uniqueDeadkeys.length }, () => new Array(1).fill(''));
for (let i = 0; i < uniqueDeadkeys.length; i++) {
- for (let j = 0; j < unique_join_dkable_dked.length; j++) {
+ for (let j = 0; j < unique_dk_array_comlpete.length; j++) {
- if (uniqueDeadkeys[i][2] === unique_join_dkable_dked[j][1]) {
- deadkeyablesArray[i][0] = deadkeyablesArray[i][0] + "\'" + unique_join_dkable_dked[j][0] + "\' "
- deadkeyedArray[i][0] = deadkeyedArray[i][0] + "\'" + unique_join_dkable_dked[j][2] + "\' "
+ if (uniqueDeadkeys[i][2] === unique_dk_array_comlpete[j][1]) {
+ deadkeyablesElement[i][0] = deadkeyablesElement[i][0] + "\'" + unique_dk_array_comlpete[j][0] + "\' "
+ deadkeyedElement[i][0] = deadkeyedElement[i][0] + "\'" + unique_dk_array_comlpete[j][2] + "\' "
}
}
- deadkeyedArray[i][1] = (uniqueDeadkeys[i][6])
+ deadkeyedElement[i][1] = (uniqueDeadkeys[i][6])
}
data += "\n"
@@ -1106,15 +956,153 @@ export class KeylayoutToKmnConverter {
data += '\nmatch > use(deadkeys)\n\n'
data += '\ngroup(deadkeys)\n\n'
- // finally write out
- for (let i = 0; i < deadkeyablesArray.length; i++) {
- data += "\n\ndk: " + deadkeyedArray[i][1]
- data += "\ndeadkeyablesArray" + deadkeyablesArray[i][0]
- data += "\ndeadkeyedArray " + deadkeyedArray[i][0]
+ for (let i = 0; i < deadkeyablesElement.length; i++) {
+ data += "\n\ndk: " + deadkeyedElement[i][1]
+ data += "\ndeadkeyablesArray" + deadkeyablesElement[i][0]
+ data += "\ndeadkeyedArray " + deadkeyedElement[i][0]
}
return data
}
+ public createData_Rules(data_ukelele: convert_object, workArray2D: string[][]): string {
+ const maxkey = 50
+ let data: string = ""
+ let keymarker = ""
+
+ // select only lines that contain C0 or C1 and create an output. Also remove duplicates
+ const [uniqueDeadkeys] = workArray2D.reduce((acc, curr) => {
+ if ((curr[3] !== "") && ((curr[0] === "first_modifier_C0") || (curr[0] === "first_modifier_C1"))) {
+ const [uniq, set] = acc;
+ if (!set.has(curr.join(','))) {
+ set.add(curr.join(','));
+ uniq.push(curr);
+ }
+ }
+ return acc;
+ }, [[], new Set()],
+ );
+
+ for (let kkk = 0; kkk < uniqueDeadkeys.length; kkk++) {
+ // lookup key nr of the key that is being processed
+ let keyNr = 0;
+ for (let pp = 0; pp < maxkey; pp++) {
+ if (this.map_UkeleleKC_To_VK(pp) === uniqueDeadkeys[kkk][2])
+ keyNr = pp
+ }
+
+ // skip keyNr 48 ( TAB )
+ if (keyNr === 48)
+ continue
+
+ // add a line after rules of each key
+ if (uniqueDeadkeys[kkk][2] !== keymarker)
+ data += '\n'
+
+ data += keyNr + "-(modif:" + "ii" + "-" + "i" + `) + [` + (uniqueDeadkeys[kkk][1] + ' ' + uniqueDeadkeys[kkk][2]).trim() + `] > \'` + uniqueDeadkeys[kkk][3] + '\'\n'
+ keymarker = uniqueDeadkeys[kkk][2]
+ }
+
+ data += '\n'
+ console.log("data ", data)
+
+ return data
+ }
+
+ public createData_Stores(data_ukelele: convert_object): string {
+ let data: string = ""
+
+ data += "c\n"
+ data += "c Keyman keyboard generated by kmn-convert\n"
+ data += "c\n"
+ data += "\n"
+
+ data += '\########## OK #################################################################\n'
+ data += "store(&VERSION) \'...\'\n"
+ data += "store(&TARGETS) \'any\'\n"
+ data += "store(&KEYBOARDVERSION) \'...\'\n"
+ data += "store(©RIGHT) '© 2024 SIL International\n"
+ // TODO what else ??
+
+ data += '\########## OK #################################################################\n'
+ data += "\n"
+ data += "begin Unicode > use(main)\n\n"
+ data += "group(main) using keys\n\n"
+
+ data += '\########## OK #################################################################\n'
+ data += "Tipp: if K_? is replaced by undefined-> no enry in kmn_Key_Name=> add K_? there and it will be shown here\n"
+ data += "Tipp: keys that are marked with sction do not aoear in ukelele_Array_output->do not appear in kmn\n"
+ data += "\n"
+
+ return data
+ }
+
+ public createDataToWrite(data_ukelele: convert_object): string {
+
+ // create a string array to work with ................................................
+ const workArray2D: string[][] = []
+ for (let k = 0; k < data_ukelele.ArrayOf_processed_RuleData.length; k++) {
+ const array1D: string[] = []
+ for (let l = 0; l < data_ukelele.ArrayOf_processed_RuleData[k].length; l++) {
+ const u8data = data_ukelele.ArrayOf_processed_RuleData[k][l]
+ array1D.push(new TextDecoder().decode(u8data))
+ }
+ workArray2D.push(array1D)
+ }
+ console.log("workArray2D ", workArray2D)
+
+
+ let data: string = ""
+ data += this.createData_Stores(data_ukelele)
+ data += this.createData_Rules(data_ukelele, workArray2D)
+ data += this.createData_Deadkeys(data_ukelele, workArray2D)
+ return data
+ }
+
+ // public lookup_2_KeyMapAction__To__ActionAction() { }
+ //public lookup_4_ActionNext__To__ActionState() { }
+ //public lookup_7_ActionState__To__ActionOutput() { }
+ //public lookup_8_ActionNext__To__TerminatorState() { }
+ /* public lookup_9_TerminatorState__To__TerminatorOutput_ui8(data: any, search: string): Uint8Array {
+ for (let jj = 0; jj < data.keyboard.terminators.when.length; jj++) {
+ if (data.keyboard.terminators.when[jj]['@_state'] === search) {
+ return new TextEncoder().encode(data.keyboard.terminators.when[jj]['@_output']);
+ }
+ }
+ return new TextEncoder().encode("")
+ }*/
+ /*public lookup_11_KeyMapAction__To__KeyIndex(data: any, search: string): number {
+ for (let kk = 0; kk < data.keyboard.keyMapSet[0].keyMap.length; kk++) {
+ for (let jj = 0; jj < data.keyboard.keyMapSet[0].keyMap[kk].key.length; jj++) {
+ if (data.keyboard.keyMapSet[0].keyMap[kk].key[jj]['@_action'] === search) {
+ return data.keyboard.keyMapSet[0].keyMap[kk]['@_index']
+ }
+ }
+ }
+ return 999
+ }*/
+ // get all entries that result in state 3
+ /*public lookup_12_ActionNext__from__ActionState(data: any, search: string): string {
+ // loop all action
+ for (let jj = 0; jj < data.keyboard.actions.action.length; jj++) {
+ // loop all when
+ for (let kk = 0; kk < data.keyboard.actions.action[jj].when.length; kk++) {
+ // if next === a´search
+ if (data.keyboard.actions.action[jj].when[kk]['@_next'] === search) {
+ // return actionIDName
+ return data.keyboard.actions.action[jj]['@_id']
+ }
+ }
+ }
+ return ""
+ }*/
+ /*
+ public useAsString(u18ArrayElemnent: Uint8Array[]): string {
+ let str = ""
+ for (let i = 0; i < u18ArrayElemnent.length; i++) {
+ str = str + " " + new TextDecoder().decode(u18ArrayElemnent[i])
+ }
+ return str
+ }*/
}