-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit e21ebde
Showing
17 changed files
with
2,014 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
/bin/style.min.css | ||
/bin/VialToKeymapDrawer.js | ||
/bin/VialToKeymapDrawer.js.map |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# Vial layout to Keymap Drawer converter | ||
|
||
Takes your Vial `.vil` layouts and converts them to YAML that you can pass to | ||
[keymap-drawer](https://github.com/caksoylar/keymap-drawer) | ||
to render your layout to SVG/PNG images that you can show to people instead | ||
of taking screenshots of Vial configurator. | ||
|
||
## Inevitable caveats | ||
|
||
Apparently the order in which Vial stores keys in `.vil` files does not necessarily match up | ||
with how keys are defined in QMK, therefore the keys may appear out of order, depending on the keyboard. | ||
|
||
For this I am giving you a couple checkboxes for common oddities and ability to move a key based on row-column. | ||
|
||
Please accept my condolences in advance, but good news - you'll only need to do this once per keyboard. | ||
|
||
## License and credits | ||
|
||
Tool by YellowAfterlife | ||
|
||
Written in [Haxe](https://haxe.org). | ||
|
||
The displayed key names are based on parsing a file from | ||
[Vial GUI](https://github.com/vial-kb/vial-gui), | ||
so I guess this is now GPLv2, huh? Ah well |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<project version="2"> | ||
<!-- Output SWF options --> | ||
<output> | ||
<movie outputType="Application" /> | ||
<movie input="" /> | ||
<movie path="bin\VialToKeymapDrawer.js" /> | ||
<movie fps="0" /> | ||
<movie width="0" /> | ||
<movie height="0" /> | ||
<movie version="1" /> | ||
<movie minorVersion="0" /> | ||
<movie platform="JavaScript" /> | ||
<movie background="#FFFFFF" /> | ||
</output> | ||
<!-- Other classes to be compiled into your SWF --> | ||
<classpaths> | ||
<class path="src" /> | ||
</classpaths> | ||
<!-- Build options --> | ||
<build> | ||
<option directives="" /> | ||
<option flashStrict="False" /> | ||
<option noInlineOnDebug="False" /> | ||
<option mainClass="Main" /> | ||
<option enabledebug="False" /> | ||
<option additional="" /> | ||
</build> | ||
<!-- haxelib libraries --> | ||
<haxelib> | ||
<!-- example: <library name="..." /> --> | ||
</haxelib> | ||
<!-- Class files to compile (other referenced classes will automatically be included) --> | ||
<compileTargets> | ||
<compile path="src\Main.hx" /> | ||
</compileTargets> | ||
<!-- Paths to exclude from the Project Explorer tree --> | ||
<hiddenPaths> | ||
<hidden path="obj" /> | ||
</hiddenPaths> | ||
<!-- Executed before build --> | ||
<preBuildCommand /> | ||
<!-- Executed after build --> | ||
<postBuildCommand alwaysRun="False" /> | ||
<!-- Other project options --> | ||
<options> | ||
<option showHiddenPaths="False" /> | ||
<option testMovie="Webserver" /> | ||
<option testMovieCommand="bin/index.html" /> | ||
</options> | ||
<!-- Plugin storage --> | ||
<storage /> | ||
</project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="utf-8"/> | ||
<title>Vial To Keymap Drawer</title> | ||
<meta name="description" content="" /> | ||
<link rel="stylesheet" href="style.css" /> | ||
</head> | ||
<body> | ||
<main> | ||
What kind of keyboard? (find it in <a href="https://config.qmk.fm/">Configurator</a>) | ||
<input type="text" id="keyboard" value="splitkb/aurora/sofle_v2/rev1" placeholder="splitkb/aurora/sofle_v2/rev1" /><br/> | ||
<details> | ||
<summary>Quirks</summary> | ||
Layout name (optional): | ||
<input type="text" id="layout" value="" placeholder="e.g. LAYOUT_split_3x5_3" /><br/> | ||
<input type="checkbox" checked id="half-after-half" /> One half after another (instead of row by row)<br/> | ||
<input type="checkbox" checked id="mirror-right-half" /> Mirrored keys on right half<br/> | ||
Key move definitions (1,0 => 0,5 to move first key from second row to be fifth key in first row):<br/> | ||
<textarea id="move-defs" rows="4">4,5 => 3,6 | ||
9,5 => 8,6</textarea> | ||
</details> | ||
Layer names:<br/> | ||
<textarea id="layer-names" rows="4">DEF | ||
DIGITS (reverts digits to normal configuration) | ||
NAV | ||
MISC: F-keys and numpad</textarea> | ||
Pick (or paste) your VIL layout: | ||
<form id="vil-form"> | ||
<input type="file" id="vil-picker" accept=".vil" /> | ||
</form> | ||
<textarea id="vil">{"version": 1, "uid": 12888985424971681029, "layout": [[["KC_GRAVE", "RSFT(KC_1)", "RSFT(KC_9)", "RSFT(KC_0)", "RSFT(KC_BSLASH)", "RSFT(KC_7)"], ["KC_TAB", "KC_Q", "KC_W", "KC_E", "KC_R", "KC_T"], ["KC_LSHIFT", "KC_A", "KC_S", "KC_D", "KC_F", "KC_G"], ["KC_LCTRL", "KC_Z", "KC_X", "KC_C", "KC_V", "KC_B"], ["KC_LGUI", "KC_LALT", "KC_SPACE", "MO(2)", "KC_ENTER", "KC_CAPSLOCK"], ["KC_BSPACE", "KC_EQUAL", "KC_MINUS", "KC_END", "KC_HOME", "RSFT(KC_8)"], ["KC_LBRACKET", "KC_P", "KC_O", "KC_I", "KC_U", "KC_Y"], ["KC_QUOTE", "KC_SCOLON", "KC_L", "KC_K", "KC_J", "KC_H"], ["RSFT_T(KC_RBRACKET)", "KC_SLASH", "KC_DOT", "KC_COMMA", "KC_M", "KC_N"], ["KC_DOWN", "KC_UP", "KC_RIGHT", "KC_LEFT", "LT3(KC_ESCAPE)", "KC_MUTE"]], [["KC_TRNS", "KC_1", "KC_2", "KC_3", "KC_4", "KC_5"], ["KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS"], ["KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS"], ["KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS"], ["LGUI_T(KC_ESCAPE)", "LALT_T(KC_BSLASH)", "KC_TRNS", "LT2(KC_MINUS)", "KC_TRNS", "KC_TRNS"], ["KC_TRNS", "KC_0", "KC_9", "KC_8", "KC_7", "KC_6"], ["KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS"], ["KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS"], ["KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS"], ["KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "LT3(KC_EQUAL)", "KC_TRNS"]], [["KC_ESCAPE", "KC_1", "KC_2", "KC_3", "KC_4", "KC_5"], ["KC_TRNS", "LCTL(KC_Z)", "LCTL(KC_X)", "LCTL(KC_C)", "LCTL(KC_V)", "TG(1)"], ["KC_TRNS", "KC_LGUI", "KC_LALT", "KC_LCTRL", "KC_LSHIFT", "KC_F22"], ["KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_CAPSLOCK"], ["KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_MPLY"], ["KC_TRNS", "KC_0", "KC_9", "KC_8", "KC_7", "KC_6"], ["KC_PSCREEN", "KC_ENTER", "KC_END", "KC_UP", "KC_HOME", "KC_DELETE"], ["KC_TRNS", "KC_SPACE", "KC_RIGHT", "KC_DOWN", "KC_LEFT", "KC_BSPACE"], ["KC_TRNS", "KC_BSLASH", "LCTL(KC_V)", "LCTL(KC_C)", "LCTL(KC_X)", "LCTL(KC_Z)"], ["KC_PGDOWN", "KC_PGUP", "KC_END", "KC_HOME", "KC_DELETE", "KC_TRNS"]], [["KC_F1", "KC_F2", "KC_F3", "KC_F4", "KC_F5", "KC_F6"], ["KC_KP_DOT", "KC_KP_7", "KC_KP_8", "KC_KP_9", "KC_TRNS", "KC_TRNS"], ["KC_TRNS", "KC_KP_4", "KC_KP_5", "KC_KP_6", "KC_TRNS", "KC_TRNS"], ["KC_TRNS", "KC_KP_1", "KC_KP_2", "KC_KP_3", "KC_TRNS", "KC_TRNS"], ["KC_KP_0", "KC_TRNS", "KC_TRNS", "KC_TRNS", "LALT(KC_F4)", "KC_TRNS"], ["KC_TRNS", "KC_F11", "KC_F10", "KC_F9", "KC_F8", "KC_F7"], ["KC_PSCREEN", "KC_F12", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS"], ["KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS"], ["KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS"], ["KC_PGDOWN", "KC_PGUP", "KC_END", "KC_HOME", "KC_TRNS", "KC_TRNS"]]], "encoder_layout": [[["KC_VOLD", "KC_VOLU"], ["KC_PGDOWN", "KC_PGUP"]], [["KC_TRNS", "KC_TRNS"], ["KC_TRNS", "KC_TRNS"]], [["KC_MNXT", "KC_MPRV"], ["KC_TRNS", "KC_TRNS"]], [["KC_TRNS", "KC_TRNS"], ["KC_TRNS", "KC_TRNS"]]], "layout_options": -1, "macro": [[["tap", "KC_F19", "TG(1)"]], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []], "vial_protocol": 5, "via_protocol": 9, "tap_dance": [["LSFT(KC_9)", "LSFT(KC_2)", "KC_NO", "KC_NO", 200], ["LSFT(KC_0)", "LSFT(KC_3)", "KC_NO", "KC_NO", 200], ["LSFT(KC_BSLASH)", "KC_BSLASH", "KC_NO", "KC_NO", 160], ["LSFT(KC_7)", "LSFT(KC_5)", "KC_NO", "KC_NO", 160], ["LSFT(KC_8)", "LSFT(KC_6)", "KC_NO", "KC_NO", 160], ["LSFT(KC_8)", "LSFT(KC_3)", "KC_NO", "KC_NO", 160], ["KC_NO", "KC_NO", "KC_NO", "KC_NO", 160], ["KC_NO", "KC_NO", "KC_NO", "KC_NO", 160]], "combo": [["KC_9", "KC_0", "KC_NO", "KC_NO", "KC_EQUAL"], ["KC_8", "KC_9", "KC_NO", "KC_NO", "KC_MINUS"], ["KC_NO", "KC_NO", "KC_NO", "KC_NO", "KC_NO"], ["KC_NO", "KC_NO", "KC_NO", "KC_NO", "KC_NO"], ["KC_NO", "KC_NO", "KC_NO", "KC_NO", "KC_NO"], ["KC_NO", "KC_NO", "KC_NO", "KC_NO", "KC_NO"], ["KC_NO", "KC_NO", "KC_NO", "KC_NO", "KC_NO"], ["KC_NO", "KC_NO", "KC_NO", "KC_NO", "KC_NO"], ["KC_NO", "KC_NO", "KC_NO", "KC_NO", "KC_NO"], ["KC_NO", "KC_NO", "KC_NO", "KC_NO", "KC_NO"]], "key_override": [], "settings": {}}</textarea> | ||
<input type="button" value="Convert!" id="convert" /><br/> | ||
Output: | ||
<textarea id="out"></textarea> | ||
</main> | ||
<script src="VialToKeymapDrawer.js"></script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
body { | ||
background-color: #899FC6; | ||
font: 15px sans-serif; | ||
line-height: 1.5; | ||
} | ||
main { | ||
background-color: white; | ||
max-width: 640px; | ||
margin: 0 auto; | ||
padding: 0.5em; | ||
} | ||
main input[type="text"], | ||
main input[type="file"], | ||
main textarea { | ||
width: 100%; | ||
box-sizing: border-box; | ||
} | ||
#vil-form { | ||
margin-bottom: 0.25em; | ||
} | ||
#convert { | ||
padding: 0.4em 1em; | ||
} | ||
#vil { | ||
height: 20vh; | ||
} | ||
#out { | ||
height: 60vh; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package ; | ||
import vial.VialKeyNames; | ||
using StringTools; | ||
|
||
/** | ||
* ... | ||
* @author YellowAfterlife | ||
*/ | ||
class KcToKeyName { | ||
public static var map:Map<String, String> = [ | ||
"KC_TRNS" => "▽", | ||
"KC_NO" => "", | ||
]; | ||
public static function get(kc:String) { | ||
var s = map[kc]; | ||
if (s != null) return s; | ||
s = VialKeyNames.map[kc]; | ||
if (s != null) return s; | ||
if (kc.startsWith("KC_")) return kc.substr(3); | ||
return kc; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
package; | ||
|
||
import haxe.DynamicAccess; | ||
import haxe.Json; | ||
import js.Browser; | ||
import js.Lib; | ||
import js.html.Element; | ||
import js.html.Event; | ||
import js.html.FileReader; | ||
import js.html.FormElement; | ||
import js.html.InputElement; | ||
import js.html.TextAreaElement; | ||
import drawer.DrawerKeymap; | ||
import tools.ERegTools; | ||
import vial.VialKeymap; | ||
import VilToDrawer; | ||
using StringTools; | ||
|
||
/** | ||
* ... | ||
* @author YellowAfterlife | ||
*/ | ||
class Main { | ||
static inline function find<T:Element>(id:String, ?c:Class<T>):T { | ||
return cast Browser.document.getElementById(id); | ||
} | ||
static var fdVil:TextAreaElement = find("vil"); | ||
static var fdOut:TextAreaElement = find("out"); | ||
|
||
static var fmVil:FormElement = find("vil-form"); | ||
static var ffVil:InputElement = find("vil-picker"); | ||
|
||
static var cbHalfAfterHalf:InputElement = find("half-after-half"); | ||
static var cbMirrorRightHalf:InputElement = find("mirror-right-half"); | ||
static var fdKeyboard:InputElement = find("keyboard"); | ||
static var fdLayout:InputElement = find("layout"); | ||
static var fdMoveDefs:TextAreaElement = find("move-defs"); | ||
static var fdLayerNames:TextAreaElement = find("layer-names"); | ||
static var btConvert:InputElement = find("convert"); | ||
|
||
static function convert() { | ||
var opt = new VilToDrawerOpt(); | ||
opt.qmkKeyboard = fdKeyboard.value.trim(); | ||
opt.qmkLayout = fdLayout.value.trim(); | ||
opt.parseVil(fdVil.value); | ||
opt.halfAfterHalf = cbHalfAfterHalf.checked; | ||
opt.mirrorRightHalf = cbMirrorRightHalf.checked; | ||
opt.parseLayerNames(fdLayerNames.value); | ||
opt.parseMoveDefs(fdMoveDefs.value); | ||
fdOut.value = VilToDrawer.runTxt(opt); | ||
} | ||
static function main() { | ||
ffVil.onchange = function(e:Event) { | ||
var file = ffVil.files[0]; | ||
if (file == null) return; | ||
|
||
var fileReader = new FileReader(); | ||
fileReader.onloadend = function() fmVil.reset(); | ||
fileReader.onload = function() { | ||
fdVil.value = fileReader.result; | ||
} | ||
fileReader.readAsText(file); | ||
} | ||
|
||
btConvert.onclick = function() convert(); | ||
convert(); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
package ; | ||
import drawer.DrawerKeymap; | ||
import haxe.DynamicAccess; | ||
import haxe.Json; | ||
import tools.ERegTools; | ||
import vial.VialKeyNames; | ||
import vial.VialKeymap; | ||
import vial.VialKey; | ||
using StringTools; | ||
|
||
/** | ||
* ... | ||
* @author YellowAfterlife | ||
*/ | ||
class VilToDrawer { | ||
public static function run(opt:VilToDrawerOpt):DrawerKeymap { | ||
var vkm = opt.vil; | ||
var dkLayers:DynamicAccess<DrawerLayer> = new DynamicAccess(); | ||
// | ||
inline function getLayerName(li:Int) { | ||
return opt.getLayerName(li, true); | ||
} | ||
|
||
// flatten layers and fix key positions: | ||
var vLayers:Array<Array<VialKey>> = []; | ||
for (i => layer in vkm.layout) { | ||
var rows = layer.copy(); | ||
for (i => row in rows) rows[i] = row.copy(); | ||
// | ||
for (def in opt.moveDefs) { | ||
var key = rows[def.srcRow].splice(def.srcCol, 1)[0]; | ||
rows[def.dstRow].insert(def.dstCol, key); | ||
} | ||
// | ||
var rowCount = layer.length; | ||
var halfRowCount = rowCount >> 1; | ||
var newRows = [for (_ in 0 ... rowCount) null]; | ||
for (rk => row in rows) { | ||
var dk = rk; | ||
if (opt.halfAfterHalf) { | ||
if (dk >= halfRowCount) { | ||
dk = (dk - halfRowCount) * 2 + 1; | ||
if (opt.mirrorRightHalf) row.reverse(); | ||
} else { | ||
dk *= 2; | ||
} | ||
} | ||
newRows[dk] = row; | ||
} | ||
// | ||
var keys = []; | ||
for (row in newRows) for (key in row) keys.push(key); | ||
vLayers.push(keys); | ||
} | ||
// | ||
for (li => vkeys in vLayers) { | ||
var dkeys = []; | ||
for (k => kc in vkeys) { | ||
var dk = kc.toDrawerKey(opt); | ||
// is this a held key? | ||
var mo = "MO(" + li + ")"; | ||
var lts = "LT" + li + "("; | ||
var held = false; | ||
for (vkeys2 in vLayers) { | ||
if (vkeys == vkeys2) continue; | ||
var kc2 = vkeys2[k]; | ||
if (kc2 == null) continue; | ||
if (kc2 == mo || (kc2:String).startsWith(lts)) { | ||
held = true; | ||
break; | ||
} | ||
} | ||
if (held) { | ||
var dkx:DrawerKeyExt; | ||
if (dk is String) { | ||
dkx = { t: dk }; | ||
} else dkx = dk; | ||
dkx.type = "held"; | ||
if (dkx.t == VialKeyNames.map["KC_TRNS"]) dkx.t = ""; | ||
dk = dkx; | ||
} | ||
dkeys.push(dk); | ||
} | ||
dkLayers[getLayerName(li)] = dkeys; | ||
} | ||
// | ||
var dCombos:Array<DrawerCombo> = []; | ||
for (vCombo in vkm.combo) { | ||
var iResult = vCombo.length - 1; | ||
var inKeys = []; | ||
for (i in 0 ... iResult) if (vCombo[i].isValid()) inKeys.push(vCombo[i]); | ||
if (inKeys.length < 2) continue; | ||
var cResult = vCombo[iResult]; | ||
if (!cResult.isValid()) continue; | ||
|
||
for (li => vKeys in vLayers) { | ||
var keyPos = []; | ||
for (key in inKeys) { | ||
var kp = vKeys.indexOf(key); | ||
if (kp >= 0) keyPos.push(kp); else break; | ||
} | ||
if (keyPos.length < inKeys.length) continue; | ||
dCombos.push({ | ||
p: keyPos, | ||
k: cResult.toDrawerKey(opt), | ||
l: [getLayerName(li)], | ||
}); | ||
} | ||
} | ||
// | ||
var dkm:DrawerKeymap = { | ||
layout: { | ||
qmk_keyboard: opt.qmkKeyboard | ||
}, | ||
layers: dkLayers, | ||
combos: dCombos, | ||
}; | ||
if (opt.qmkLayout != null && opt.qmkLayout != "") dkm.layout.qmk_layout = opt.qmkLayout; | ||
return dkm; | ||
} | ||
public static function runTxt(opt:VilToDrawerOpt) { | ||
var dkm = run(opt); | ||
return Json.stringify(dkm, null, " "); | ||
} | ||
} |
Oops, something went wrong.