diff --git a/cli.ts b/cli.ts index 9de84ee..23b991e 100644 --- a/cli.ts +++ b/cli.ts @@ -3,6 +3,7 @@ import fs from "fs" import path from "path" import { generateKeylayout } from "./generateKeylayout" import { generateKlc } from "./generateKlc" +import { generateXkb } from "./generateXkb" import { fixUnicode } from "./utils" // eslint-disable-next-line @typescript-eslint/no-var-requires @@ -47,6 +48,18 @@ const choices = filenames.map((filename) => ({ const outputFilename = `output/${layoutName}.klc` await generateKlc(jsonInput, outputFilename) + console.log(`Output : ${outputFilename}`) + } catch (e) { + console.error(e) + process.exit(1) + } + + // Xkb + try { + const layoutName = response.input.split(".")[0] + const outputFilename = `output/${layoutName}_xkb` + await generateXkb(jsonInput, outputFilename) + console.log(`Output : ${outputFilename}`) } catch (e) { console.error(e) diff --git a/generateXkb.ts b/generateXkb.ts new file mode 100644 index 0000000..3fa252d --- /dev/null +++ b/generateXkb.ts @@ -0,0 +1,121 @@ +import { plainToClass } from "class-transformer" +import { validate } from "class-validator" +import fs from "fs" +import { Layout, WindowsAttributes } from "./main" + +export async function generateXkb( + 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(", ")) + } + + function toHex(str: string) { + var hex, i; + var result = ""; + for (i=0; i { [", + "2": "key { [", + "3": "key { [", + "4": "key { [", + "5": "key { [", + "6": "key { [", + "7": "key { [", + "8": "key { [", + "9": "key { [", + "0": "key { [", + "-": "key { [", + "=": "key { [", + "`": "key { [", + q: "key { [", + w: "key { [", + e: "key { [", + r: "key { [", + t: "key { [", + y: "key { [", + u: "key { [", + i: "key { [", + o: "key { [", + p: "key { [", + "[": "key { [", + "]": "key { [", + a: "key { [", + s: "key { [", + d: "key { [", + f: "key { [", + g: "key { [", + h: "key { [", + j: "key { [", + k: "key { [", + l: "key { [", + ";": "key { [", + "'": "key { [", + "\\": "key { [", + z: "key { [", + x: "key { [", + c: "key { [", + v: "key { [", + b: "key { [", + n: "key { [", + m: "key { [", + ",": "key { [", + ".": "key { [", + "/": "key { [", + } + + const lines = [ + `partial alphanumeric_keys`, + `xkb_symbols "${layout.os.windows.installerName}" {`, + `\n // COPYRIGHT "MIT"`, + `\n name[Group1]= "${layout.name} v${layout.version}";`, + ] + + const layoutLines = [""] + Object.entries(klfDefaultLayout).forEach(([key, value]) => + { + const extensions = layout.layers.map + ( + (_, idx) => + { + return (toHex(layout.keys[key][idx]) || "voidsymbol")+((idx<3)?",":"") + } + ) + + extensions.push("] };") + layoutLines.push([value,...extensions].join(" ")) + }) + + fs.writeFileSync( + outputPath, + "\ufeff" + + [ + lines.join("\n"), + layoutLines.join("\n "), + " include \"level3(ralt_switch)\"\n};", + ].join("\n\n"), + { + encoding: "utf8", + } + ) +} diff --git a/output/Manoonchai_xkb b/output/Manoonchai_xkb new file mode 100644 index 0000000..c73deee --- /dev/null +++ b/output/Manoonchai_xkb @@ -0,0 +1,58 @@ +partial alphanumeric_keys +xkb_symbols "ThaiMnc" { + + // COPYRIGHT "MIT" + + name[Group1]= "Manoonchai v1.0"; + + + key { [ 0x1000030, 0x1000029, 0x1000e50, voidsymbol ] }; + key { [ 0x1000031, 0x1000021, 0x1000e51, voidsymbol ] }; + key { [ 0x1000032, 0x1000040, 0x1000e52, voidsymbol ] }; + key { [ 0x1000033, 0x1000023, 0x1000e53, voidsymbol ] }; + key { [ 0x1000034, 0x1000024, 0x1000e54, voidsymbol ] }; + key { [ 0x1000035, 0x1000025, 0x1000e55, voidsymbol ] }; + key { [ 0x1000036, 0x100005e, 0x1000e56, voidsymbol ] }; + key { [ 0x1000037, 0x1000026, 0x1000e57, voidsymbol ] }; + key { [ 0x1000038, 0x100002a, 0x1000e58, voidsymbol ] }; + key { [ 0x1000039, 0x1000028, 0x1000e59, voidsymbol ] }; + key { [ 0x100002d, 0x100005f, 0x10000f7, voidsymbol ] }; + key { [ 0x100003d, 0x100002b, 0x10000d7, voidsymbol ] }; + key { [ 0x1000060, 0x100007e, 0x1000060, voidsymbol ] }; + key { [ 0x1000e43, 0x1000e12, voidsymbol, voidsymbol ] }; + key { [ 0x1000e15, 0x1000e0f, voidsymbol, voidsymbol ] }; + key { [ 0x1000e2b, 0x1000e0b, voidsymbol, voidsymbol ] }; + key { [ 0x1000e25, 0x1000e0d, voidsymbol, voidsymbol ] }; + key { [ 0x1000e2a, 0x1000e1f, voidsymbol, voidsymbol ] }; + key { [ 0x1000e1b, 0x1000e09, voidsymbol, voidsymbol ] }; + key { [ 0x1000e31, 0x1000e36, 0x1000e3a, voidsymbol ] }; + key { [ 0x1000e01, 0x1000e18, voidsymbol, voidsymbol ] }; + key { [ 0x1000e34, 0x1000e10, voidsymbol, voidsymbol ] }; + key { [ 0x1000e1a, 0x1000e0e, voidsymbol, voidsymbol ] }; + key { [ 0x1000e47, 0x1000e06, 0x100005b, 0x100007b ] }; + key { [ 0x1000e2c, 0x1000e11, 0x100005d, 0x100007d ] }; + key { [ 0x1000e07, 0x1000e29, 0x10025cc, voidsymbol ] }; + key { [ 0x1000e40, 0x1000e16, 0x1000e4f, voidsymbol ] }; + key { [ 0x1000e23, 0x1000e41, 0x1000e5b, voidsymbol ] }; + key { [ 0x1000e19, 0x1000e0a, 0x1000e3f, voidsymbol ] }; + key { [ 0x1000e21, 0x1000e1e, voidsymbol, voidsymbol ] }; + key { [ 0x1000e2d, 0x1000e1c, 0x1000e4d, voidsymbol ] }; + key { [ 0x1000e32, 0x1000e33, 0x1000e45, voidsymbol ] }; + key { [ 0x1000e48, 0x1000e02, 0x1000e03, voidsymbol ] }; + key { [ 0x1000e49, 0x1000e42, voidsymbol, voidsymbol ] }; + key { [ 0x1000e27, 0x1000e20, 0x100003b, 0x100003a ] }; + key { [ 0x1000e37, 0x1000022, 0x1000027, 0x1000022 ] }; + key { [ 0x1000e2f, 0x1000e0c, 0x100005c, 0x100007c ] }; + key { [ 0x1000e38, 0x1000e24, 0x1000e26, voidsymbol ] }; + key { [ 0x1000e44, 0x1000e1d, voidsymbol, voidsymbol ] }; + key { [ 0x1000e17, 0x1000e46, 0x1000e5a, voidsymbol ] }; + key { [ 0x1000e22, 0x1000e13, voidsymbol, voidsymbol ] }; + key { [ 0x1000e08, 0x1000e4a, voidsymbol, voidsymbol ] }; + key { [ 0x1000e04, 0x1000e4b, 0x1000e05, voidsymbol ] }; + key { [ 0x1000e35, 0x1000e4c, 0x1000e4e, voidsymbol ] }; + key { [ 0x1000e14, 0x1000e28, 0x100002c, 0x100003c ] }; + key { [ 0x1000e30, 0x1000e2e, 0x100002e, 0x100003e ] }; + key { [ 0x1000e39, 0x100003f, 0x100002f, 0x100003f ] }; + + include "level3(ralt_switch)" +}; \ No newline at end of file