diff --git a/cli.ts b/cli.ts index 38eace1..9de84ee 100644 --- a/cli.ts +++ b/cli.ts @@ -1,7 +1,8 @@ import prompts from "prompts" import fs from "fs" import path from "path" -import { generateLayout } from "./main" +import { generateKeylayout } from "./generateKeylayout" +import { generateKlc } from "./generateKlc" import { fixUnicode } from "./utils" // eslint-disable-next-line @typescript-eslint/no-var-requires @@ -25,8 +26,9 @@ const choices = filenames.map((filename) => ({ fs.readFileSync(path.join(process.cwd(), "input", response.input), "utf8") ) + // Keylayout try { - const keylayoutXml = await generateLayout(jsonInput) + const keylayoutXml = await generateKeylayout(jsonInput) const layoutName = response.input.split(".")[0] const outputFilename = `output/${layoutName}.keylayout` fs.writeFileSync(outputFilename, keylayoutXml) @@ -38,4 +40,16 @@ const choices = filenames.map((filename) => ({ console.error(e) process.exit(1) } + + // Klc + try { + const layoutName = response.input.split(".")[0] + const outputFilename = `output/${layoutName}.klc` + await generateKlc(jsonInput, outputFilename) + + console.log(`Output : ${outputFilename}`) + } catch (e) { + console.error(e) + process.exit(1) + } })() diff --git a/generateKeylayout.ts b/generateKeylayout.ts new file mode 100644 index 0000000..d2f82eb --- /dev/null +++ b/generateKeylayout.ts @@ -0,0 +1,268 @@ +import { plainToClass } from "class-transformer" +import { validate } from "class-validator" +import { js2xml } from "xml-js" +import { Layout } from "./main" + +export async function generateKeylayout( + content: Record +): Promise { + const layout = plainToClass(Layout, content) + const errors = await validate(layout) + + if (errors.length) { + throw new Error(errors.map((e) => e.toString()).join(", ")) + } + + const defaultKeyMapSelects = [ + { layerName: "Base", layerValue: "anyControl? command?" }, + { layerName: "Shift", layerValue: "anyShift anyControl? command?" }, + { + layerName: "Command", + layerValue: "command anyShift? anyControl? anyOption?", + }, + { + layerName: "Alt", + layerValue: "command anyShift? anyControl? anyOption?", + }, + { + layerName: "Option", + layerValue: "anyOption anyShift? anyControl? command?", + }, + { + layerName: "Control", + layerValue: "anyControl anyShift? anyOption? command?", + }, + { layerName: "Caps", layerValue: "caps anyControl? command?" }, + { + layerName: "Caps+Shift", + layerValue: "caps anyShift anyControl? command?", + }, + { + layerName: "Caps+Option", + layerValue: "caps anyOption anyControl? command?", + }, + { + layerName: "Caps+Shift+Option", + layerValue: "caps anyShift anyOption anyControl? command?", + }, + ] + + const defaultKeys = [ + { code: 0, output: "a" }, + { code: 1, output: "s" }, + { code: 2, output: "d" }, + { code: 3, output: "f" }, + { code: 4, output: "h" }, + { code: 5, output: "g" }, + { code: 6, output: "z" }, + { code: 7, output: "x" }, + { code: 8, output: "c" }, + { code: 9, output: "v" }, + { code: 10, output: "§" }, + { code: 11, output: "b" }, + { code: 12, output: "q" }, + { code: 13, output: "w" }, + { code: 14, output: "e" }, + { code: 15, output: "r" }, + { code: 16, output: "y" }, + { code: 17, output: "t" }, + { code: 18, output: "1" }, + { code: 19, output: "2" }, + { code: 20, output: "3" }, + { code: 21, output: "4" }, + { code: 22, output: "6" }, + { code: 23, output: "5" }, + { code: 24, output: "=" }, + { code: 25, output: "9" }, + { code: 26, output: "7" }, + { code: 27, output: "-" }, + { code: 28, output: "8" }, + { code: 29, output: "0" }, + { code: 30, output: "]" }, + { code: 31, output: "o" }, + { code: 32, output: "u" }, + { code: 33, output: "[" }, + { code: 34, output: "i" }, + { code: 35, output: "p" }, + { code: 36, output: " ", unicode: true }, + { code: 37, output: "l" }, + { code: 38, output: "j" }, + { code: 39, output: "'" }, + { code: 40, output: "k" }, + { code: 41, output: ";" }, + { code: 42, output: "\\" }, + { code: 43, output: "," }, + { code: 44, output: "/" }, + { code: 45, output: "n" }, + { code: 46, output: "m" }, + { code: 47, output: "." }, + { code: 48, output: " ", unicode: true }, + { code: 49, output: " " }, + { code: 50, output: "`" }, + { code: 51, output: "", unicode: true }, + { code: 52, output: "", unicode: true }, + { code: 53, output: "", unicode: true }, + { code: 65, output: "." }, + { code: 66, output: "", unicode: true }, + { code: 67, output: "*" }, + { code: 69, output: "+" }, + { code: 70, output: "", unicode: true }, + { code: 71, output: "", unicode: true }, + { code: 72, output: "", unicode: true }, + { code: 75, output: "/" }, + { code: 76, output: "", unicode: true }, + { code: 77, output: "", unicode: true }, + { code: 78, output: "-" }, + { code: 81, output: "=" }, + { code: 82, output: "0" }, + { code: 83, output: "1" }, + { code: 84, output: "2" }, + { code: 85, output: "3" }, + { code: 86, output: "4" }, + { code: 87, output: "5" }, + { code: 88, output: "6" }, + { code: 89, output: "7" }, + { code: 91, output: "8" }, + { code: 92, output: "9" }, + { code: 96, output: "", unicode: true }, + { code: 97, output: "", unicode: true }, + { code: 98, output: "", unicode: true }, + { code: 99, output: "", unicode: true }, + { code: 100, output: "", unicode: true }, + { code: 101, output: "", unicode: true }, + { code: 102, output: "", unicode: true }, + { code: 103, output: "", unicode: true }, + { code: 104, output: "", unicode: true }, + { code: 105, output: "", unicode: true }, + { code: 106, output: "", unicode: true }, + { code: 107, output: "", unicode: true }, + { code: 108, output: "", unicode: true }, + { code: 109, output: "", unicode: true }, + { code: 110, output: "", unicode: true }, + { code: 111, output: "", unicode: true }, + { code: 112, output: "", unicode: true }, + { code: 113, output: "", unicode: true }, + { code: 114, output: "", unicode: true }, + { code: 115, output: "", unicode: true }, + { code: 116, output: " ", unicode: true }, + { code: 117, output: "", unicode: true }, + { code: 118, output: "", unicode: true }, + { code: 119, output: "", unicode: true }, + { code: 120, output: "", unicode: true }, + { code: 121, output: " ", unicode: true }, + { code: 122, output: "", unicode: true }, + { code: 123, output: "", unicode: true }, + { code: 124, output: "", unicode: true }, + { code: 125, output: "", unicode: true }, + { code: 126, output: "", unicode: true }, + ] + + const layoutLayers = layout.layers + const layoutKeyMapSelects = layoutLayers.map((layoutLayerName) => { + const keyMapSelect = defaultKeyMapSelects.find( + (defaultKeyMapSelect) => defaultKeyMapSelect.layerName === layoutLayerName + ) + + if (!keyMapSelect) { + throw new Error(`Invalid layer : ${layoutLayerName}`) + } + + return keyMapSelect.layerValue + }) + + const document = { + declaration: { attributes: { version: "1.1", encoding: "UTF-8" } }, + elements: [ + { + doctype: + 'keyboard SYSTEM "file://localhost/System/Library/DTDs/KeyboardLayout.dtd"', + type: "doctype", + }, + { + type: "element", + name: "keyboard", + attributes: { + group: "0", + id: "12345", + name: layout.name, + maxout: "1", + }, + elements: [ + { + type: "element", + name: "layouts", + elements: [ + { + type: "element", + name: "layout", + attributes: { + first: "0", + last: "0", + mapSet: "defaultKeyMapSet", + modifiers: "defaultModifierMap", + }, + }, + ], + }, + { + type: "element", + name: "modifierMap", + attributes: { id: "defaultModifierMap", defaultIndex: "0" }, + elements: layoutKeyMapSelects.map((keyMapSelect, idx) => ({ + type: "element", + name: "keyMapSelect", + attributes: { + mapIndex: `${idx}`, + }, + elements: [ + { + type: "element", + name: "modifier", + attributes: { + keys: keyMapSelect, + }, + }, + ], + })), + }, + { + type: "element", + name: "keyMapSet", + attributes: { id: "defaultKeyMapSet" }, + elements: layout.layers.map((_, idx) => ({ + type: "element", + name: "keyMap", + attributes: { index: idx }, + elements: defaultKeys.map(({ code, output, unicode }) => { + let overrideKey + + // Override only index 0-50 + // Since some symbols are the same in numpad's position and should not be overridden + if (code <= 50) { + overrideKey = layout.keys[output]?.[idx] || output + } else { + overrideKey = output + } + + if (overrideKey == "&") { + overrideKey = escape("&") + } + + if (unicode) { + overrideKey = encodeURIComponent(output) + } + return { + type: "element", + name: "key", + attributes: { code, output: overrideKey }, + } + }), + })), + }, + ], + }, + ], + } + + return js2xml(document, { spaces: 2 }) +} diff --git a/generateKlc.ts b/generateKlc.ts new file mode 100644 index 0000000..66ca2f0 --- /dev/null +++ b/generateKlc.ts @@ -0,0 +1,134 @@ +import { plainToClass } from "class-transformer" +import { validate } from "class-validator" +import fs from "fs" +import { Layout, WindowsAttributes } from "./main" + +export async function generateKlc( + content: Record, + outputPath: string +): Promise { + const layout = plainToClass(Layout, content) + const errors = await validate(layout) + + if (errors.length) { + throw new Error(errors.map((e) => e.toString()).join(", ")) + } + + const windowsErrors = await validate( + plainToClass(WindowsAttributes, layout.os.windows) + ) + + if (windowsErrors.length) { + throw new Error(windowsErrors.map((e) => e.toString()).join(", ")) + } + + const klcLocales = { + Thai: "th-TH", + } + + const klcShiftStates = { + Base: 0, + Shift: 1, + Ctrl: 2, + "Shift+Ctrl": 3, + Alt: 4, + "Shift+Alt": 5, + "Alt+Ctrl": 6, + "Shift+Alt+Ctrl": 7, + // From macOS config + Command: 4, + AltGr: 7, + Option: 7, + Control: 2, + } + + const klfDefaultLayout = { + "1": "02\t1", + "2": "03\t2", + "3": "04\t3", + "4": "05\t4", + "5": "06\t5", + "6": "07\t6", + "7": "08\t7", + "8": "09\t8", + "9": "0a\t9", + "0": "0b\t0", + "-": "0c\tOEM_MINUS", + "=": "0d\tOEM_PLUS", + q: "10\tQ", + w: "11\tW", + e: "12\tE", + r: "13\tR", + t: "14\tT", + y: "15\tY", + u: "16\tU", + i: "17\tI", + o: "18\tO", + p: "19\tP", + "[": "1a\tOEM_4", + "]": "1b\tOEM_6", + a: "1e\tA", + s: "1f\tS", + d: "20\tD", + f: "21\tF", + g: "22\tG", + h: "23\tH", + j: "24\tJ", + k: "25\tK", + l: "26\tL", + ";": "27\tOEM_1", + "'": "28\tOEM_7", + "`": "29\tOEM_3", + "\\": "2b\tOEM_5", + z: "2c\tZ", + x: "2d\tX", + c: "2e\tC", + v: "2f\tV", + b: "30\tB", + n: "31\tN", + m: "32\tM", + ",": "33\tOEM_COMMA", + ".": "34\tOEM_PERIOD", + "/": "35\tOEM_2", + } + + const lines = [ + `KBD\t${layout.os.windows.installerName}\t"${layout.language} ${layout.name} v${layout.version}"`, + `COPYRIGHT\t"MIT"`, + `COMPANY\t"${layout.os.windows.company}"`, + `LOCALENAME\t"${klcLocales[layout.language]}"`, + `LOCALEID\t"${layout.os.windows.localeId}"`, + `VERSION\t${layout.version}`, + ] + + const shiftStateLines: Array = layout.layers.map((layer, idx) => { + if (layer in klcShiftStates) { + return `${klcShiftStates[layer]}\t// Column ${idx + 4} : ${layer}` + } else { + throw new Error("Layer not valid") + } + }) + + shiftStateLines.unshift("SHIFTSTATE", "") + + const layoutLines = ["LAYOUT"] + + Object.entries(klfDefaultLayout).forEach(([key, value]) => { + const extensions = layout.layers.map((_, idx) => layout.keys[key][idx]) + layoutLines.push([value, "0", ...extensions].join("\t")) + }) + + fs.writeFileSync( + outputPath, + "\ufeff" + + [ + lines.join("\r\n\r\n"), + shiftStateLines.join("\r\n"), + layoutLines.join("\r\n"), + "ENDKBD", + ].join("\r\n\r\n"), + { + encoding: "utf16le", + } + ) +} diff --git a/input/Manoonchai-ColemakDH-Mod.json b/input/Manoonchai-ColemakDH-Mod.json index c30fc1e..bf40a92 100644 --- a/input/Manoonchai-ColemakDH-Mod.json +++ b/input/Manoonchai-ColemakDH-Mod.json @@ -5,6 +5,7 @@ "layers": ["Base", "Shift", "Command", "Option", "Control"], "os": { "windows": { + "installerName": "Mnc-DH", "company": "Manoonchai", "localeId": "0000041e" } diff --git a/main.ts b/main.ts index 28803fb..f961240 100644 --- a/main.ts +++ b/main.ts @@ -9,8 +9,6 @@ import { MaxLength, validate, } from "class-validator" -import { js2xml } from "xml-js" -import fs from "fs" export async function validateLayout( content: Record @@ -25,399 +23,6 @@ export async function validateLayout( return !errors.length } -export async function generateKlc( - content: Record -): Promise { - const layout = plainToClass(Layout, content) - const errors = await validate(layout) - - if (errors.length) { - throw new Error(errors.map((e) => e.toString()).join(", ")) - } - - const windowsErrors = await validate( - plainToClass(WindowsAttributes, layout.os.windows) - ) - - if (windowsErrors.length) { - throw new Error(windowsErrors.map((e) => e.toString()).join(", ")) - } - - const klcLocales = { - Thai: "th-TH", - } - - const klcShiftStates = { - Base: 0, - Shift: 1, - Ctrl: 2, - "Shift+Ctrl": 3, - Alt: 4, - "Shift+Alt": 5, - "Alt+Ctrl": 6, - "Shift+Alt+Ctrl": 7, - // From macOS config - Command: 4, - AltGr: 7, - Option: 7, - Control: 2, - } - - const klfDefaultLayout = { - "1": "02\t1", - "2": "03\t2", - "3": "04\t3", - "4": "05\t4", - "5": "06\t5", - "6": "07\t6", - "7": "08\t7", - "8": "09\t8", - "9": "0a\t9", - "0": "0b\t0", - "-": "0c\tOEM_MINUS", - "=": "0d\tOEM_PLUS", - q: "10\tQ", - w: "11\tW", - e: "12\tE", - r: "13\tR", - t: "14\tT", - y: "15\tY", - u: "16\tU", - i: "17\tI", - o: "18\tO", - p: "19\tP", - "[": "1a\tOEM_4", - "]": "1b\tOEM_6", - a: "1e\tA", - s: "1f\tS", - d: "20\tD", - f: "21\tF", - g: "22\tG", - h: "23\tH", - j: "24\tJ", - k: "25\tK", - l: "26\tL", - ";": "27\tOEM_1", - "'": "28\tOEM_7", - "`": "29\tOEM_3", - "\\": "2b\tOEM_5", - z: "2c\tZ", - x: "2d\tX", - c: "2e\tC", - v: "2f\tV", - b: "30\tB", - n: "31\tN", - m: "32\tM", - ",": "33\tOEM_COMMA", - ".": "34\tOEM_PERIOD", - "/": "35\tOEM_2", - } - - const lines = [ - `KBD\t${layout.os.windows.installerName}\t"${layout.language} ${layout.name} v${layout.version}"`, - `COPYRIGHT\t"MIT"`, - `COMPANY\t"${layout.os.windows.company}"`, - `LOCALENAME\t"${klcLocales[layout.language]}"`, - `LOCALEID\t"${layout.os.windows.localeId}"`, - `VERSION\t${layout.version}`, - ] - - const shiftStateLines: Array = layout.layers.map((layer, idx) => { - if (layer in klcShiftStates) { - return `${klcShiftStates[layer]}\t// Column ${idx + 4} : ${layer}` - } else { - throw new Error("Layer not valid") - } - }) - - shiftStateLines.unshift("SHIFTSTATE", "") - - const layoutLines = ["LAYOUT"] - - Object.entries(klfDefaultLayout).forEach(([key, value]) => { - const extensions = layout.layers.map((_, idx) => layout.keys[key][idx]) - layoutLines.push([value, "0", ...extensions].join("\t")) - }) - - fs.writeFileSync( - "./output/test.klc", - "\ufeff" + - [ - lines.join("\r\n\r\n"), - shiftStateLines.join("\r\n"), - layoutLines.join("\r\n"), - "ENDKBD", - ].join("\r\n\r\n"), - { - encoding: "utf16le", - } - ) -} - -export async function generateLayout( - content: Record -): Promise { - const layout = plainToClass(Layout, content) - const errors = await validate(layout) - - if (errors.length) { - throw new Error(errors.map((e) => e.toString()).join(", ")) - } - - const defaultKeyMapSelects = [ - { layerName: "Base", layerValue: "anyControl? command?" }, - { layerName: "Shift", layerValue: "anyShift anyControl? command?" }, - { - layerName: "Command", - layerValue: "command anyShift? anyControl? anyOption?", - }, - { - layerName: "Alt", - layerValue: "command anyShift? anyControl? anyOption?", - }, - { - layerName: "Option", - layerValue: "anyOption anyShift? anyControl? command?", - }, - { - layerName: "Control", - layerValue: "anyControl anyShift? anyOption? command?", - }, - { layerName: "Caps", layerValue: "caps anyControl? command?" }, - { - layerName: "Caps+Shift", - layerValue: "caps anyShift anyControl? command?", - }, - { - layerName: "Caps+Option", - layerValue: "caps anyOption anyControl? command?", - }, - { - layerName: "Caps+Shift+Option", - layerValue: "caps anyShift anyOption anyControl? command?", - }, - ] - - const defaultKeys = [ - { code: 0, output: "a" }, - { code: 1, output: "s" }, - { code: 2, output: "d" }, - { code: 3, output: "f" }, - { code: 4, output: "h" }, - { code: 5, output: "g" }, - { code: 6, output: "z" }, - { code: 7, output: "x" }, - { code: 8, output: "c" }, - { code: 9, output: "v" }, - { code: 10, output: "§" }, - { code: 11, output: "b" }, - { code: 12, output: "q" }, - { code: 13, output: "w" }, - { code: 14, output: "e" }, - { code: 15, output: "r" }, - { code: 16, output: "y" }, - { code: 17, output: "t" }, - { code: 18, output: "1" }, - { code: 19, output: "2" }, - { code: 20, output: "3" }, - { code: 21, output: "4" }, - { code: 22, output: "6" }, - { code: 23, output: "5" }, - { code: 24, output: "=" }, - { code: 25, output: "9" }, - { code: 26, output: "7" }, - { code: 27, output: "-" }, - { code: 28, output: "8" }, - { code: 29, output: "0" }, - { code: 30, output: "]" }, - { code: 31, output: "o" }, - { code: 32, output: "u" }, - { code: 33, output: "[" }, - { code: 34, output: "i" }, - { code: 35, output: "p" }, - { code: 36, output: " ", unicode: true }, - { code: 37, output: "l" }, - { code: 38, output: "j" }, - { code: 39, output: "'" }, - { code: 40, output: "k" }, - { code: 41, output: ";" }, - { code: 42, output: "\\" }, - { code: 43, output: "," }, - { code: 44, output: "/" }, - { code: 45, output: "n" }, - { code: 46, output: "m" }, - { code: 47, output: "." }, - { code: 48, output: " ", unicode: true }, - { code: 49, output: " " }, - { code: 50, output: "`" }, - { code: 51, output: "", unicode: true }, - { code: 52, output: "", unicode: true }, - { code: 53, output: "", unicode: true }, - { code: 65, output: "." }, - { code: 66, output: "", unicode: true }, - { code: 67, output: "*" }, - { code: 69, output: "+" }, - { code: 70, output: "", unicode: true }, - { code: 71, output: "", unicode: true }, - { code: 72, output: "", unicode: true }, - { code: 75, output: "/" }, - { code: 76, output: "", unicode: true }, - { code: 77, output: "", unicode: true }, - { code: 78, output: "-" }, - { code: 81, output: "=" }, - { code: 82, output: "0" }, - { code: 83, output: "1" }, - { code: 84, output: "2" }, - { code: 85, output: "3" }, - { code: 86, output: "4" }, - { code: 87, output: "5" }, - { code: 88, output: "6" }, - { code: 89, output: "7" }, - { code: 91, output: "8" }, - { code: 92, output: "9" }, - { code: 96, output: "", unicode: true }, - { code: 97, output: "", unicode: true }, - { code: 98, output: "", unicode: true }, - { code: 99, output: "", unicode: true }, - { code: 100, output: "", unicode: true }, - { code: 101, output: "", unicode: true }, - { code: 102, output: "", unicode: true }, - { code: 103, output: "", unicode: true }, - { code: 104, output: "", unicode: true }, - { code: 105, output: "", unicode: true }, - { code: 106, output: "", unicode: true }, - { code: 107, output: "", unicode: true }, - { code: 108, output: "", unicode: true }, - { code: 109, output: "", unicode: true }, - { code: 110, output: "", unicode: true }, - { code: 111, output: "", unicode: true }, - { code: 112, output: "", unicode: true }, - { code: 113, output: "", unicode: true }, - { code: 114, output: "", unicode: true }, - { code: 115, output: "", unicode: true }, - { code: 116, output: " ", unicode: true }, - { code: 117, output: "", unicode: true }, - { code: 118, output: "", unicode: true }, - { code: 119, output: "", unicode: true }, - { code: 120, output: "", unicode: true }, - { code: 121, output: " ", unicode: true }, - { code: 122, output: "", unicode: true }, - { code: 123, output: "", unicode: true }, - { code: 124, output: "", unicode: true }, - { code: 125, output: "", unicode: true }, - { code: 126, output: "", unicode: true }, - ] - - const layoutLayers = layout.layers - const layoutKeyMapSelects = layoutLayers.map((layoutLayerName) => { - const keyMapSelect = defaultKeyMapSelects.find( - (defaultKeyMapSelect) => defaultKeyMapSelect.layerName === layoutLayerName - ) - - if (!keyMapSelect) { - throw new Error(`Invalid layer : ${layoutLayerName}`) - } - - return keyMapSelect.layerValue - }) - - const document = { - declaration: { attributes: { version: "1.1", encoding: "UTF-8" } }, - elements: [ - { - doctype: - 'keyboard SYSTEM "file://localhost/System/Library/DTDs/KeyboardLayout.dtd"', - type: "doctype", - }, - { - type: "element", - name: "keyboard", - attributes: { - group: "0", - id: "12345", - name: layout.name, - maxout: "1", - }, - elements: [ - { - type: "element", - name: "layouts", - elements: [ - { - type: "element", - name: "layout", - attributes: { - first: "0", - last: "0", - mapSet: "defaultKeyMapSet", - modifiers: "defaultModifierMap", - }, - }, - ], - }, - { - type: "element", - name: "modifierMap", - attributes: { id: "defaultModifierMap", defaultIndex: "0" }, - elements: layoutKeyMapSelects.map((keyMapSelect, idx) => ({ - type: "element", - name: "keyMapSelect", - attributes: { - mapIndex: `${idx}`, - }, - elements: [ - { - type: "element", - name: "modifier", - attributes: { - keys: keyMapSelect, - }, - }, - ], - })), - }, - { - type: "element", - name: "keyMapSet", - attributes: { id: "defaultKeyMapSet" }, - elements: layout.layers.map((_, idx) => ({ - type: "element", - name: "keyMap", - attributes: { index: idx }, - elements: defaultKeys.map(({ code, output, unicode }) => { - let overrideKey - - // Override only index 0-50 - // Since some symbols are the same in numpad's position and should not be overridden - if (code <= 50) { - overrideKey = layout.keys[output]?.[idx] || output - } else { - overrideKey = output - } - - if (overrideKey == "&") { - overrideKey = escape("&") - } - - if (unicode) { - overrideKey = encodeURIComponent(output) - } - return { - type: "element", - name: "key", - attributes: { code, output: overrideKey }, - } - }), - })), - }, - ], - }, - ], - } - - return js2xml(document, { spaces: 2 }) -} - export class Layout { @IsString() name: string @@ -447,7 +52,7 @@ interface OSAttributes { windows: WindowsAttributes } -class WindowsAttributes { +export class WindowsAttributes { @IsString() company: string diff --git a/output/Manoonchai-ColemakDH-Mod.klc b/output/Manoonchai-ColemakDH-Mod.klc new file mode 100644 index 0000000..4a93fcb Binary files /dev/null and b/output/Manoonchai-ColemakDH-Mod.klc differ diff --git a/output/Manoonchai.klc b/output/Manoonchai.klc new file mode 100644 index 0000000..7a0a642 Binary files /dev/null and b/output/Manoonchai.klc differ diff --git a/test/main.test.ts b/test/main.test.ts index bb42eb5..fdf37b0 100644 --- a/test/main.test.ts +++ b/test/main.test.ts @@ -1,7 +1,9 @@ import fs from "fs" import path from "path" import { js2xml, xml2js } from "xml-js" -import { generateKlc, generateLayout, validateLayout } from "../main" +import { validateLayout } from "../main" +import { generateKeylayout } from "../generateKeylayout" +import { generateKlc } from "../generateKlc" import { fixUnicode } from "../utils" describe("validateLayout", () => { @@ -43,7 +45,7 @@ describe("generateLayout", () => { ) ) - const manoonchaiXml = await generateLayout(manoonchaiJson) + const manoonchaiXml = await generateKeylayout(manoonchaiJson) expect(manoonchaiXml).toBeDefined() @@ -423,12 +425,13 @@ describe("generateKlc", () => { ) ) - await generateKlc(inputJson) + const filepath = "output/test.klc" + await generateKlc(inputJson, filepath) - expect(fs.existsSync("output/test.klc")).toBeTruthy() + expect(fs.existsSync(filepath)).toBeTruthy() const lines = fs - .readFileSync("output/test.klc", "utf16le") + .readFileSync(filepath, "utf16le") .split("\r\n") .filter(Boolean)