2015-12-14 01:28:13 +01:00
|
|
|
|
#!/usr/bin/env ruby
|
|
|
|
|
# -*- encoding: utf-8 -*-
|
|
|
|
|
# Copyright muflax <mail@muflax.com>, 2015
|
|
|
|
|
# License: GNU GPLv3 (or later) <http://www.gnu.org/copyleft/gpl.html>
|
|
|
|
|
|
2016-08-22 00:50:03 +02:00
|
|
|
|
GC.disable
|
|
|
|
|
|
2016-06-12 07:51:49 +02:00
|
|
|
|
# avoid having to require muflax
|
|
|
|
|
class Object
|
|
|
|
|
def blank?
|
|
|
|
|
respond_to?(:empty?) ? !!empty? : !self
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
class String
|
|
|
|
|
BLANK_RE = /\A[[:space:]]*\z/
|
|
|
|
|
def blank?
|
|
|
|
|
BLANK_RE === self
|
|
|
|
|
end
|
|
|
|
|
end
|
2015-12-14 01:28:13 +01:00
|
|
|
|
|
2016-06-11 22:19:48 +02:00
|
|
|
|
LayoutDir = "src/keyboard"
|
2016-06-12 01:58:43 +02:00
|
|
|
|
LayoutFile = "#{LayoutDir}/layout.c"
|
2015-12-14 01:28:13 +01:00
|
|
|
|
|
|
|
|
|
puts "generating #{LayoutFile}..."
|
|
|
|
|
|
2016-08-21 20:32:32 +02:00
|
|
|
|
class Layer
|
|
|
|
|
@@layers = {}
|
|
|
|
|
@@primitives = 0
|
|
|
|
|
|
|
|
|
|
def initialize name
|
|
|
|
|
case name
|
|
|
|
|
when Symbol
|
|
|
|
|
raise "layer already defined: #{name}" if @@layers.include? name
|
|
|
|
|
|
|
|
|
|
@@primitives += 1
|
|
|
|
|
@@layers[name] = @@primitives
|
|
|
|
|
|
|
|
|
|
when Array
|
|
|
|
|
name.each do |prim|
|
|
|
|
|
raise "unknown layers: #{prim}" if not @@layers.include? prim
|
|
|
|
|
raise "can only combo primitive layers: #{prim}" if not prim.is_a? Symbol
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
combo = name.reduce(0) do |code, prim|
|
|
|
|
|
code | (@@layers[prim])
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
combo_name = name.sort_by{|p| @@layers[p]}.join("_").to_sym
|
|
|
|
|
|
|
|
|
|
@@layers[combo_name] = combo
|
|
|
|
|
|
|
|
|
|
else
|
|
|
|
|
raise "invalid layer definition: #{name}"
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
Keydef = Struct.new :code, :func
|
2015-12-14 01:28:13 +01:00
|
|
|
|
|
|
|
|
|
class Key
|
2016-08-22 00:50:03 +02:00
|
|
|
|
attr_reader :keydefs, :name, :row, :col
|
2015-12-14 01:28:13 +01:00
|
|
|
|
|
2016-08-22 00:50:03 +02:00
|
|
|
|
Layers = [ :LB, :LP, :LN, :LF, :LD ]
|
2015-12-14 01:28:13 +01:00
|
|
|
|
|
|
|
|
|
Functions = {
|
2016-08-21 20:32:32 +02:00
|
|
|
|
#
|
|
|
|
|
"basic" => "&kbfun_normal_press_release",
|
|
|
|
|
"media" => "&kbfun_mediakey_press_release",
|
|
|
|
|
#
|
|
|
|
|
"mod" => "&kbfun_modifier_press_release",
|
|
|
|
|
"sticky_mod" => "&kbfun_modifier_sticky",
|
|
|
|
|
#
|
|
|
|
|
"layer" => "&kbfun_layer_press_release",
|
|
|
|
|
"sticky" => "&kbfun_layer_sticky",
|
|
|
|
|
#
|
|
|
|
|
"shift" => "&kbfun_shift_press_release",
|
|
|
|
|
"ctrl" => "&kbfun_control_press_release",
|
|
|
|
|
"alt" => "&kbfun_alt_press_release",
|
|
|
|
|
"win" => "&kbfun_win_press_release",
|
|
|
|
|
"shift_layer" => "&kbfun_shift_layer_press_release",
|
|
|
|
|
"ctrl_layer" => "&kbfun_control_layer_press_release",
|
|
|
|
|
"alt_layer" => "&kbfun_alt_layer_press_release",
|
|
|
|
|
"win_layer" => "&kbfun_win_layer_press_release",
|
|
|
|
|
#
|
|
|
|
|
"capslock" => "&kbfun_capslock_press_release",
|
2016-08-22 00:50:03 +02:00
|
|
|
|
#
|
|
|
|
|
"S" => "&kbfun_shift_press_release",
|
|
|
|
|
"C" => "&kbfun_control_press_release",
|
|
|
|
|
"A" => "&kbfun_alt_press_release",
|
|
|
|
|
"M" => "&kbfun_alt_press_release",
|
|
|
|
|
"W" => "&kbfun_win_press_release",
|
|
|
|
|
"CL" => "&kbfun_capslock_press_release",
|
|
|
|
|
"_L" => "&kbfun_layer_sticky",
|
|
|
|
|
"_M" => "&kbfun_modifier_sticky",
|
|
|
|
|
"_C" => "&kbfun_control_layer_press_release",
|
|
|
|
|
"_A" => "&kbfun_alt_layer_press_release",
|
|
|
|
|
"_W" => "&kbfun_win_layer_press_release",
|
2015-12-14 01:28:13 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Keys = {
|
2016-08-22 00:50:03 +02:00
|
|
|
|
# letters
|
|
|
|
|
"a" => "KEY_a_A",
|
|
|
|
|
"b" => "KEY_b_B",
|
|
|
|
|
"c" => "KEY_c_C",
|
|
|
|
|
"d" => "KEY_d_D",
|
|
|
|
|
"e" => "KEY_e_E",
|
|
|
|
|
"f" => "KEY_f_F",
|
|
|
|
|
"g" => "KEY_g_G",
|
|
|
|
|
"h" => "KEY_h_H",
|
|
|
|
|
"i" => "KEY_i_I",
|
|
|
|
|
"j" => "KEY_j_J",
|
|
|
|
|
"k" => "KEY_k_K",
|
|
|
|
|
"l" => "KEY_l_L",
|
|
|
|
|
"m" => "KEY_m_M",
|
|
|
|
|
"n" => "KEY_n_N",
|
|
|
|
|
"o" => "KEY_o_O",
|
|
|
|
|
"p" => "KEY_p_P",
|
|
|
|
|
"q" => "KEY_q_Q",
|
|
|
|
|
"r" => "KEY_r_R",
|
|
|
|
|
"s" => "KEY_s_S",
|
|
|
|
|
"t" => "KEY_t_T",
|
|
|
|
|
"u" => "KEY_u_U",
|
|
|
|
|
"v" => "KEY_v_V",
|
|
|
|
|
"w" => "KEY_w_W",
|
|
|
|
|
"x" => "KEY_x_X",
|
|
|
|
|
"y" => "KEY_y_Y",
|
|
|
|
|
"z" => "KEY_z_Z",
|
|
|
|
|
# numbers
|
|
|
|
|
"0" => "KEY_0_RightParenthesis",
|
|
|
|
|
"1" => "KEY_1_Exclamation",
|
|
|
|
|
"2" => "KEY_2_At",
|
|
|
|
|
"3" => "KEY_3_Pound",
|
|
|
|
|
"4" => "KEY_4_Dollar",
|
|
|
|
|
"5" => "KEY_5_Percent",
|
|
|
|
|
"6" => "KEY_6_Caret",
|
|
|
|
|
"7" => "KEY_7_Ampersand",
|
|
|
|
|
"8" => "KEY_8_Asterisk",
|
|
|
|
|
"9" => "KEY_9_LeftParenthesis",
|
|
|
|
|
# punctuation
|
|
|
|
|
"\\" => "KEY_Backslash_Pipe",
|
|
|
|
|
"{" => ["KEY_LeftBracket_LeftBrace", "shift"],
|
|
|
|
|
"}" => ["KEY_RightBracket_RightBrace", "shift"],
|
|
|
|
|
"[" => "KEY_LeftBracket_LeftBrace",
|
|
|
|
|
"]" => "KEY_RightBracket_RightBrace",
|
|
|
|
|
"," => "KEY_Comma_LessThan",
|
|
|
|
|
"-" => "KEY_Dash_Underscore",
|
|
|
|
|
"=" => "KEY_Equal_Plus",
|
|
|
|
|
"`" => "KEY_GraveAccent_Tilde",
|
|
|
|
|
"." => "KEY_Period_GreaterThan",
|
|
|
|
|
"\'" => "KEY_SingleQuote_DoubleQuote",
|
|
|
|
|
";" => "KEY_Semicolon_Colon",
|
|
|
|
|
"/" => "KEY_Slash_Question",
|
|
|
|
|
"~" => ["KEY_GraveAccent_Tilde", "shift"],
|
|
|
|
|
"%" => ["KEY_5_Percent", "shift"],
|
|
|
|
|
"*" => ["KEY_8_Asterisk", "shift"],
|
|
|
|
|
":" => ["KEY_Semicolon_Colon", "shift"],
|
|
|
|
|
"^" => ["KEY_6_Caret", "shift"],
|
|
|
|
|
"<" => ["KEY_Comma_LessThan", "shift"],
|
|
|
|
|
">" => ["KEY_Period_GreaterThan", "shift"],
|
|
|
|
|
"?" => ["KEY_Slash_Question", "shift"],
|
|
|
|
|
"!" => ["KEY_1_Exclamation", "shift"],
|
|
|
|
|
"(" => ["KEY_9_LeftParenthesis", "shift"],
|
|
|
|
|
")" => ["KEY_0_RightParenthesis", "shift"],
|
|
|
|
|
"|" => ["KEY_Backslash_Pipe", "shift"],
|
|
|
|
|
"@" => ["KEY_2_At", "shift"],
|
|
|
|
|
"\"" => ["KEY_SingleQuote_DoubleQuote", "shift"],
|
|
|
|
|
"_" => ["KEY_Dash_Underscore", "shift"],
|
|
|
|
|
"+" => ["KEY_Equal_Plus", "shift"],
|
|
|
|
|
"$" => ["KEY_4_Dollar", "shift"],
|
|
|
|
|
"&" => ["KEY_7_Ampersand", "shift"],
|
|
|
|
|
"#" => ["KEY_3_Pound", "shift"],
|
|
|
|
|
"hash" => ["KEY_3_Pound", "shift"],
|
|
|
|
|
"hsh" => ["KEY_3_Pound", "shift"],
|
|
|
|
|
# enter etc
|
|
|
|
|
"enter" => "KEY_ReturnEnter",
|
|
|
|
|
"return" => "KEY_ReturnEnter",
|
|
|
|
|
"ret" => "KEY_ReturnEnter",
|
|
|
|
|
"space" => "KEY_Spacebar",
|
|
|
|
|
"spc" => "KEY_Spacebar",
|
|
|
|
|
"tab" => "KEY_Tab",
|
|
|
|
|
"backspace" => "KEY_DeleteBackspace",
|
|
|
|
|
"bksp" => "KEY_DeleteBackspace",
|
|
|
|
|
"bs" => "KEY_DeleteBackspace",
|
|
|
|
|
"delete" => "KEY_DeleteForward",
|
|
|
|
|
"del" => "KEY_DeleteForward",
|
|
|
|
|
"home" => "KEY_Home",
|
|
|
|
|
"hom" => "KEY_Home",
|
|
|
|
|
"end" => "KEY_End",
|
|
|
|
|
"page_up" => "KEY_PageUp",
|
|
|
|
|
"pgup" => "KEY_PageUp",
|
|
|
|
|
"p-^" => "KEY_PageUp",
|
|
|
|
|
"page_down" => "KEY_PageDown",
|
|
|
|
|
"pgdn" => "KEY_PageDown",
|
|
|
|
|
"p-v" => "KEY_PageDown",
|
|
|
|
|
"up" => "KEY_UpArrow",
|
|
|
|
|
"a-^" => "KEY_UpArrow",
|
|
|
|
|
"down" => "KEY_DownArrow",
|
|
|
|
|
"a-v" => "KEY_DownArrow",
|
|
|
|
|
"left" => "KEY_LeftArrow",
|
|
|
|
|
"a-<" => "KEY_LeftArrow",
|
|
|
|
|
"right" => "KEY_RightArrow",
|
|
|
|
|
"a->" => "KEY_RightArrow",
|
|
|
|
|
"escape" => "KEY_Escape",
|
|
|
|
|
"esc" => "KEY_Escape",
|
|
|
|
|
"insert" => "KEY_Insert",
|
|
|
|
|
"ins" => "KEY_Insert",
|
|
|
|
|
"menu" => "KEY_Application",
|
|
|
|
|
"men" => "KEY_Application",
|
|
|
|
|
# modifiers
|
|
|
|
|
"alt" => ["MOD_KEY_LeftAlt", "mod" ],
|
|
|
|
|
"A" => ["MOD_KEY_LeftAlt", "mod" ],
|
|
|
|
|
"M" => ["MOD_KEY_LeftAlt", "mod" ],
|
|
|
|
|
"alt_gr" => ["MOD_KEY_RightAlt", "mod" ],
|
|
|
|
|
"umlaut" => ["MOD_KEY_RightAlt", "mod" ],
|
|
|
|
|
# "UM" => ["MOD_KEY_RightAlt", "mod" ],
|
|
|
|
|
"UM" => ["MOD_KEY_RightAlt", "sticky_mod" ],
|
|
|
|
|
"ctrl" => ["MOD_KEY_LeftControl", "mod" ],
|
|
|
|
|
"C" => ["MOD_KEY_LeftControl", "mod" ],
|
|
|
|
|
"control_l" => ["MOD_KEY_LeftControl", "mod" ],
|
|
|
|
|
"control_r" => ["MOD_KEY_RightControl", "mod" ],
|
|
|
|
|
"win" => ["MOD_KEY_LeftGUI", "mod" ],
|
|
|
|
|
"W" => ["MOD_KEY_LeftGUI", "mod" ],
|
|
|
|
|
"shift_l" => ["MOD_KEY_LeftShift", "mod" ],
|
|
|
|
|
"S_l" => ["MOD_KEY_LeftShift", "mod" ],
|
|
|
|
|
"shift_r" => ["MOD_KEY_RightShift", "mod" ],
|
|
|
|
|
"S_r" => ["MOD_KEY_RightShift", "mod" ],
|
|
|
|
|
"scroll_lock" => "KEY_ScrollLock",
|
|
|
|
|
"SCL" => "KEY_ScrollLock",
|
|
|
|
|
# null
|
|
|
|
|
"NULL" => "KEY_NULL",
|
|
|
|
|
"NUL" => "KEY_NULL",
|
|
|
|
|
"■" => "KEY_NULL",
|
|
|
|
|
# functions 1..24
|
|
|
|
|
"f1" => "KEY_F1",
|
|
|
|
|
"f2" => "KEY_F2",
|
|
|
|
|
"f3" => "KEY_F3",
|
|
|
|
|
"f4" => "KEY_F4",
|
|
|
|
|
"f5" => "KEY_F5",
|
|
|
|
|
"f6" => "KEY_F6",
|
|
|
|
|
"f7" => "KEY_F7",
|
|
|
|
|
"f8" => "KEY_F8",
|
|
|
|
|
"f9" => "KEY_F9",
|
|
|
|
|
"f10" => "KEY_F10",
|
|
|
|
|
"f11" => "KEY_F11",
|
|
|
|
|
"f12" => "KEY_F12",
|
|
|
|
|
"f13" => "KEY_F13",
|
|
|
|
|
"f14" => "KEY_F14",
|
|
|
|
|
"f15" => "KEY_F15",
|
|
|
|
|
"f16" => "KEY_F16",
|
|
|
|
|
"f17" => "KEY_F17",
|
|
|
|
|
"f18" => "KEY_F18",
|
|
|
|
|
"f19" => "KEY_F19",
|
|
|
|
|
"f20" => "KEY_F20",
|
|
|
|
|
"f21" => "KEY_F21",
|
|
|
|
|
"f22" => "KEY_F22",
|
|
|
|
|
"f23" => "KEY_F23",
|
|
|
|
|
"f24" => "KEY_F24",
|
|
|
|
|
# keypad stuff
|
|
|
|
|
"kp_1" => "KEYPAD_1_End",
|
|
|
|
|
"kp_2" => "KEYPAD_2_DownArrow",
|
|
|
|
|
"kp_3" => "KEYPAD_3_PageDown",
|
|
|
|
|
"kp_4" => "KEYPAD_4_LeftArrow",
|
|
|
|
|
"kp_5" => "KEYPAD_5",
|
|
|
|
|
"kp_6" => "KEYPAD_6_RightArrow",
|
|
|
|
|
"kp_7" => "KEYPAD_7_Home",
|
|
|
|
|
"kp_8" => "KEYPAD_8_UpArrow",
|
|
|
|
|
"kp_9" => "KEYPAD_9_PageUp",
|
|
|
|
|
"kp_0" => "KEYPAD_0_Insert",
|
|
|
|
|
#
|
|
|
|
|
"kp_." => "KEYPAD_Period_Delete",
|
|
|
|
|
"kp_/" => "KEYPAD_Slash",
|
|
|
|
|
"kp_*" => "KEYPAD_Asterisk",
|
|
|
|
|
"kp_-" => "KEYPAD_Minus",
|
|
|
|
|
"kp_+" => "KEYPAD_Plus",
|
|
|
|
|
"kp_en" => "KEYPAD_ENTER",
|
|
|
|
|
# mediakeys
|
|
|
|
|
"MD_PP" => ["MEDIAKEY_PLAY_PAUSE", "media"],
|
|
|
|
|
"MD_PT" => ["MEDIAKEY_PREV_TRACK", "media"],
|
|
|
|
|
"MD_NT" => ["MEDIAKEY_NEXT_TRACK", "media"],
|
|
|
|
|
"MD_S" => ["MEDIAKEY_STOP", "media"],
|
|
|
|
|
"MD_M" => ["MEDIAKEY_AUDIO_MUTE", "media"],
|
|
|
|
|
"MD_VU" => ["MEDIAKEY_AUDIO_VOL_UP", "media"],
|
|
|
|
|
"MD_VD" => ["MEDIAKEY_AUDIO_VOL_DOWN", "media"],
|
|
|
|
|
"record" => ["MEDIAKEY_RECORD", "media"],
|
|
|
|
|
"rewind" => ["MEDIAKEY_REWIND", "media"],
|
|
|
|
|
"eject" => ["MEDIAKEY_EJECT", "media"],
|
|
|
|
|
"cc_config" => ["MEDIAKEY_CC_CONFIG", "media"],
|
|
|
|
|
"email" => ["MEDIAKEY_EMAIL", "media"],
|
|
|
|
|
"calculator" => ["MEDIAKEY_CALCULATOR", "media"],
|
|
|
|
|
"local_browser" => ["MEDIAKEY_LOCAL_BROWSER", "media"],
|
|
|
|
|
"bs_search" => ["MEDIAKEY_BROWSER_SEARCH", "media"],
|
|
|
|
|
"bs_home" => ["MEDIAKEY_BROWSER_HOME", "media"],
|
|
|
|
|
"bs_b" => ["MEDIAKEY_BROWSER_BACK", "media"],
|
|
|
|
|
"bs_f" => ["MEDIAKEY_BROWSER_FORWARD", "media"],
|
|
|
|
|
"bs_stop" => ["MEDIAKEY_BROWSER_STOP", "media"],
|
|
|
|
|
"bs_refresh" => ["MEDIAKEY_BROWSER_REFRESH", "media"],
|
|
|
|
|
"bs_bookmarks" => ["MEDIAKEY_BROWSER_BOOKMARKS", "media"],
|
|
|
|
|
# other weird shit
|
|
|
|
|
"pause" => "KEY_Pause",
|
|
|
|
|
"sysreq" => "KEY_SysReq_Attention",
|
|
|
|
|
"sreq" => "KEY_SysReq_Attention",
|
|
|
|
|
"SR" => "KEY_SysReq_Attention",
|
|
|
|
|
#
|
|
|
|
|
"clear" => "KEY_Clear",
|
|
|
|
|
# "Clear_Again" => "KEY_Clear_Again", # wut
|
|
|
|
|
"printscreen" => "KEY_PrintScreen",
|
|
|
|
|
"prtscr" => "KEY_PrintScreen",
|
|
|
|
|
"PS" => "KEY_PrintScreen",
|
|
|
|
|
#
|
|
|
|
|
"execute" => "KEY_Execute",
|
|
|
|
|
"exe" => "KEY_Execute",
|
|
|
|
|
"help" => "KEY_Help",
|
|
|
|
|
# "menu" => "KEY_Menu", # NOT normal menu!
|
|
|
|
|
"select" => "KEY_Select",
|
|
|
|
|
"selct" => "KEY_Select",
|
|
|
|
|
"sel" => "KEY_Select",
|
|
|
|
|
"stop" => "KEY_Stop",
|
|
|
|
|
#
|
|
|
|
|
"again" => "KEY_Again",
|
|
|
|
|
"redo" => "KEY_Again",
|
|
|
|
|
"undo" => "KEY_Undo",
|
|
|
|
|
#
|
|
|
|
|
"cut" => "KEY_Cut",
|
|
|
|
|
"copy" => "KEY_Copy",
|
|
|
|
|
"paste" => "KEY_Paste",
|
|
|
|
|
#
|
|
|
|
|
"find" => "KEY_Find",
|
|
|
|
|
#
|
|
|
|
|
"mute" => "KEY_Mute",
|
|
|
|
|
#
|
|
|
|
|
"volume_up" => "KEY_VolumeUp",
|
|
|
|
|
"volume_down" => "KEY_VolumeDown",
|
|
|
|
|
"vol_up" => "KEY_VolumeUp",
|
|
|
|
|
"vol_down" => "KEY_VolumeDown",
|
|
|
|
|
"volumeup" => "KEY_VolumeUp",
|
|
|
|
|
"volumedown" => "KEY_VolumeDown",
|
|
|
|
|
"voldown" => "KEY_VolumeDown",
|
|
|
|
|
"volup" => "KEY_VolumeUp",
|
|
|
|
|
"voldn" => "KEY_VolumeDown",
|
|
|
|
|
"vlup" => "KEY_VolumeUp",
|
|
|
|
|
"vldn" => "KEY_VolumeDown",
|
|
|
|
|
"vup" => "KEY_VolumeUp",
|
|
|
|
|
"vdn" => "KEY_VolumeDown",
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Names = {
|
|
|
|
|
# unique key identifiers, must have a name for each of the 80 physical keys
|
|
|
|
|
# NOTE: the mapping to the matrix is a bit weird, so be careful
|
|
|
|
|
|
|
|
|
|
# name row col
|
2016-08-22 01:24:28 +02:00
|
|
|
|
"Ln┳o" => [ 5, 0 ],
|
|
|
|
|
"Ln┳4" => [ 5, 1 ],
|
|
|
|
|
"Ln┳3" => [ 5, 2 ],
|
|
|
|
|
"Ln┳2" => [ 5, 3 ],
|
|
|
|
|
"Ln┳1" => [ 5, 4 ],
|
|
|
|
|
"Ln┳0" => [ 5, 5 ],
|
2016-08-22 00:50:03 +02:00
|
|
|
|
"Ln┳d" => [ 5, 6 ],
|
2016-08-22 01:24:28 +02:00
|
|
|
|
"Lt┳o" => [ 4, 0 ],
|
|
|
|
|
"Lt┳4" => [ 4, 1 ],
|
|
|
|
|
"Lt┳3" => [ 4, 2 ],
|
|
|
|
|
"Lt┳2" => [ 4, 3 ],
|
|
|
|
|
"Lt┳1" => [ 4, 4 ],
|
|
|
|
|
"Lt┳0" => [ 4, 5 ],
|
|
|
|
|
"Lt┳d" => [ 4, 6 ],
|
|
|
|
|
"Lh┳o" => [ 3, 0 ],
|
|
|
|
|
"Lh┳4" => [ 3, 1 ],
|
|
|
|
|
"Lh┳3" => [ 3, 2 ],
|
|
|
|
|
"Lh┳2" => [ 3, 3 ],
|
|
|
|
|
"Lh┳1" => [ 3, 4 ],
|
|
|
|
|
"Lh┳0" => [ 3, 5 ],
|
|
|
|
|
"Lb┳o" => [ 2, 0 ],
|
|
|
|
|
"Lb┳4" => [ 2, 1 ],
|
|
|
|
|
"Lb┳3" => [ 2, 2 ],
|
|
|
|
|
"Lb┳2" => [ 2, 3 ],
|
|
|
|
|
"Lb┳1" => [ 2, 4 ],
|
|
|
|
|
"Lb┳0" => [ 2, 5 ],
|
|
|
|
|
"Lb┳d" => [ 2, 6 ],
|
|
|
|
|
"Lu┳o" => [ 1, 0 ],
|
|
|
|
|
"Lu┳4" => [ 1, 1 ],
|
|
|
|
|
"Lu┳3" => [ 1, 2 ],
|
|
|
|
|
"Lu┳2" => [ 1, 3 ],
|
|
|
|
|
"Lu┳1" => [ 1, 4 ],
|
|
|
|
|
"Lz┳b" => [ 0, 5 ],
|
|
|
|
|
"Lz┳c" => [ 0, 6 ],
|
|
|
|
|
"Ly┳a" => [ 1, 5 ],
|
|
|
|
|
"Ly┳b" => [ 1, 6 ],
|
|
|
|
|
"Ly┳c" => [ 0, 4 ],
|
|
|
|
|
"Lx┳a" => [ 0, 3 ],
|
|
|
|
|
"Lx┳b" => [ 0, 2 ],
|
|
|
|
|
"Lx┳c" => [ 0, 1 ],
|
|
|
|
|
"Rn┳d" => [ 5, 7 ],
|
|
|
|
|
"Rn┳0" => [ 5, 8 ],
|
|
|
|
|
"Rn┳1" => [ 5, 9 ],
|
|
|
|
|
"Rn┳2" => [ 5, 10 ],
|
|
|
|
|
"Rn┳3" => [ 5, 11 ],
|
|
|
|
|
"Rn┳4" => [ 5, 12 ],
|
|
|
|
|
"Rn┳o" => [ 5, 13 ],
|
|
|
|
|
"Rt┳d" => [ 4, 7 ],
|
|
|
|
|
"Rt┳0" => [ 4, 8 ],
|
|
|
|
|
"Rt┳1" => [ 4, 9 ],
|
|
|
|
|
"Rt┳2" => [ 4, 10 ],
|
|
|
|
|
"Rt┳3" => [ 4, 11 ],
|
|
|
|
|
"Rt┳4" => [ 4, 12 ],
|
|
|
|
|
"Rt┳o" => [ 4, 13 ],
|
|
|
|
|
"Rh┳0" => [ 3, 8 ],
|
|
|
|
|
"Rh┳1" => [ 3, 9 ],
|
|
|
|
|
"Rh┳2" => [ 3, 10 ],
|
|
|
|
|
"Rh┳3" => [ 3, 11 ],
|
|
|
|
|
"Rh┳4" => [ 3, 12 ],
|
|
|
|
|
"Rh┳o" => [ 3, 13 ],
|
|
|
|
|
"Rb┳d" => [ 2, 7 ],
|
|
|
|
|
"Rb┳0" => [ 2, 8 ],
|
|
|
|
|
"Rb┳1" => [ 2, 9 ],
|
|
|
|
|
"Rb┳2" => [ 2, 10 ],
|
|
|
|
|
"Rb┳3" => [ 2, 11 ],
|
|
|
|
|
"Rb┳4" => [ 2, 12 ],
|
|
|
|
|
"Rb┳o" => [ 2, 13 ],
|
|
|
|
|
"Ru┳1" => [ 1, 9 ],
|
|
|
|
|
"Ru┳2" => [ 1, 10 ],
|
|
|
|
|
"Ru┳3" => [ 1, 11 ],
|
|
|
|
|
"Ru┳4" => [ 1, 12 ],
|
|
|
|
|
"Ru┳o" => [ 1, 13 ],
|
2016-08-22 00:50:03 +02:00
|
|
|
|
"Rz┳c" => [ 0, 7 ],
|
2016-08-22 01:24:28 +02:00
|
|
|
|
"Rz┳b" => [ 0, 8 ],
|
|
|
|
|
"Ry┳c" => [ 0, 9 ],
|
|
|
|
|
"Ry┳b" => [ 1, 7 ],
|
|
|
|
|
"Ry┳a" => [ 1, 8 ],
|
|
|
|
|
"Rx┳c" => [ 0, 12 ],
|
|
|
|
|
"Rx┳b" => [ 0, 11 ],
|
|
|
|
|
"Rx┳a" => [ 0, 10 ],
|
2015-12-14 01:28:13 +01:00
|
|
|
|
}
|
|
|
|
|
|
2016-02-04 16:28:11 +01:00
|
|
|
|
Layers.each.with_index do |layer, i|
|
2016-06-14 12:57:20 +02:00
|
|
|
|
Keys["#{layer}"] = ["#{i}", "layer"]
|
2016-02-04 16:28:11 +01:00
|
|
|
|
end
|
|
|
|
|
|
2016-08-22 00:50:03 +02:00
|
|
|
|
def initialize layers, name
|
|
|
|
|
@keydefs = Array.new(layers.size)
|
|
|
|
|
@name = name
|
|
|
|
|
@pos = Key::Names[name]
|
|
|
|
|
@row, @col = @pos
|
|
|
|
|
|
|
|
|
|
if layers.all?(&:empty?)
|
|
|
|
|
layers[0] = ["NUL"]
|
|
|
|
|
end
|
2015-12-14 01:28:13 +01:00
|
|
|
|
|
2016-06-12 07:44:09 +02:00
|
|
|
|
layers.each.with_index do |(key, type), i|
|
|
|
|
|
if type.nil? and key.nil?
|
2016-08-21 20:32:32 +02:00
|
|
|
|
@keydefs[i] = @keydefs[i-1]
|
2016-06-12 07:44:09 +02:00
|
|
|
|
next
|
|
|
|
|
end
|
|
|
|
|
|
2016-06-14 12:57:20 +02:00
|
|
|
|
# keycode and default keyfunc
|
|
|
|
|
keycode, default_type = Keys[key]
|
2016-06-14 10:39:45 +02:00
|
|
|
|
|
2016-06-14 12:57:20 +02:00
|
|
|
|
# keyfunc
|
2016-08-21 20:32:32 +02:00
|
|
|
|
type ||= default_type || "basic"
|
|
|
|
|
keyfunc = Functions[type]
|
2015-12-14 01:28:13 +01:00
|
|
|
|
|
2016-07-20 23:32:15 +02:00
|
|
|
|
raise "overwriting shift key: #{key}, #{type}" if default_type == "shift" and type != default_type
|
2016-06-14 12:57:20 +02:00
|
|
|
|
|
2016-06-12 07:44:09 +02:00
|
|
|
|
raise "key not found: #{key}" if keycode.nil?
|
2016-08-21 20:32:32 +02:00
|
|
|
|
raise "func not found: #{type}" if keyfunc.nil?
|
2016-06-12 07:44:09 +02:00
|
|
|
|
|
2016-06-14 10:39:45 +02:00
|
|
|
|
case type
|
2016-08-22 00:50:03 +02:00
|
|
|
|
when "layer", "sticky", "_L"
|
2016-06-14 10:39:45 +02:00
|
|
|
|
raise "invalid layer: #{key}" unless key.to_i < Key::Layers.size
|
2016-08-22 00:50:03 +02:00
|
|
|
|
when "mod", "sticky_mod", "_M"
|
2016-06-14 10:39:45 +02:00
|
|
|
|
raise "invalid modifier: #{key}" unless keycode.start_with? "MOD_KEY"
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
case keycode
|
|
|
|
|
when /^MOD_KEY/
|
|
|
|
|
case type
|
2016-08-22 00:50:03 +02:00
|
|
|
|
when "mod", "sticky_mod", "CL", "_M"; # pass
|
2016-06-14 10:39:45 +02:00
|
|
|
|
else
|
|
|
|
|
raise "invalid modifier keyfunc: #{key}, #{type}"
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2016-08-21 20:32:32 +02:00
|
|
|
|
@keydefs[i] = Keydef.new(keycode, keyfunc)
|
2015-12-14 01:28:13 +01:00
|
|
|
|
end
|
2016-06-12 07:44:09 +02:00
|
|
|
|
|
2016-08-21 20:32:32 +02:00
|
|
|
|
raise "transparency error: #{layers}" if @keydefs.any?(&:nil?)
|
2015-12-14 01:28:13 +01:00
|
|
|
|
end
|
2016-08-22 00:50:03 +02:00
|
|
|
|
|
|
|
|
|
Dummy = Key.new(Key::Layers.map{"NULL"}, "dummy")
|
2015-12-14 01:28:13 +01:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
class Layout
|
|
|
|
|
def initialize name, keys
|
2016-08-22 00:50:03 +02:00
|
|
|
|
@name = name
|
|
|
|
|
@keys = keys
|
|
|
|
|
|
|
|
|
|
@rows = @keys.map(&:row).max + 1
|
|
|
|
|
@cols = @keys.map(&:col).max + 1
|
|
|
|
|
@matrix = @rows.times.map{Array.new(@cols)}
|
|
|
|
|
|
|
|
|
|
@keys.each do |key|
|
|
|
|
|
@matrix[key.row][key.col] = key
|
|
|
|
|
end
|
2015-12-14 01:28:13 +01:00
|
|
|
|
end
|
|
|
|
|
|
2016-06-12 02:31:58 +02:00
|
|
|
|
def keys_to_matrix type, method
|
2016-08-22 00:50:03 +02:00
|
|
|
|
matrix = []
|
|
|
|
|
|
|
|
|
|
@matrix.each.with_index do |row, row_i|
|
|
|
|
|
matrix << "{"
|
|
|
|
|
row.each.with_index do |key, col_i|
|
|
|
|
|
key ||= Key::Dummy # some matrix positions are empty
|
|
|
|
|
|
|
|
|
|
matrix << "\t{ // row #{row_i} x col #{col_i}"
|
|
|
|
|
Key::Layers.each.with_index do |layer_name, layer|
|
|
|
|
|
matrix << "\t\t(#{type}) #{key.keydefs[layer].send(method)},".ljust(60) + "// #{key.name} on #{layer_name}"
|
|
|
|
|
end
|
|
|
|
|
matrix << "\t},"
|
|
|
|
|
end
|
|
|
|
|
matrix << "},"
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
matrix.join("\n")
|
2015-12-14 01:28:13 +01:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def save! file
|
|
|
|
|
puts "saving #{@name}..."
|
|
|
|
|
|
|
|
|
|
header =<<HEADER
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
// ergoDOX layout : saneo (generated)
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
HEADER
|
|
|
|
|
|
2016-06-14 02:49:01 +02:00
|
|
|
|
keys = keys_to_matrix "keycode", :code
|
2016-08-21 20:32:32 +02:00
|
|
|
|
funcs = keys_to_matrix "keyfunc", :func
|
2015-12-14 01:28:13 +01:00
|
|
|
|
|
2016-02-06 09:03:35 +01:00
|
|
|
|
File.open(LayoutFile, "w+") do |f|
|
2015-12-14 01:28:13 +01:00
|
|
|
|
f.puts header
|
2016-06-12 06:04:40 +02:00
|
|
|
|
f.puts "#define KB_LAYERS #{Key::Layers.size}"
|
2016-08-22 00:50:03 +02:00
|
|
|
|
f.puts "static const keycode PROGMEM _kb_layout_code[KB_ROWS][KB_COLUMNS][KB_LAYERS] = {", keys, "};"
|
|
|
|
|
f.puts "static const keyfunc PROGMEM _kb_layout_func[KB_ROWS][KB_COLUMNS][KB_LAYERS] = {", funcs, "};"
|
2015-12-14 01:28:13 +01:00
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2016-08-22 00:50:03 +02:00
|
|
|
|
left =<<EOL
|
|
|
|
|
╳ Ln┳o ___ __ Ln┳4 ___ __ Ln┳3 ___ __ Ln┳2 ___ __ Ln┳1 ___ __ Ln┳0 ___ __ Ln┳d ___ __
|
|
|
|
|
_LB ┃ 0 ┃ 1 ┃ 2 ┃ 3 ┃ 4 ┃ 5 ┃ 6
|
|
|
|
|
_LP ┃ f11 ┃ f1 ┃ f2 ┃ f3 ┃ f4 ┃ f5 ┃ f6
|
|
|
|
|
_LN ┃ f11 ┃ f1 ┃ f2 ┃ f3 ┃ f4 ┃ f5 ┃ f6
|
|
|
|
|
_LF ┃ f11 ┃ f1 ┃ f2 ┃ f3 ┃ f4 ┃ f5 ┃ f6
|
|
|
|
|
_LD ┃ 0 ┃ 1 ┃ 2 ┃ 3 ┃ 4 ┃ 5 ┃ 6
|
|
|
|
|
╳ Lt┳o ___ __ Lt┳4 ___ __ Lt┳3 ___ __ Lt┳2 ___ __ Lt┳1 ___ __ Lt┳0 ___ __ Lt┳d ___ __
|
|
|
|
|
_LB ┃ tab ┃ x ┃ v ┃ l ┃ c ┃ w ┃ tab
|
|
|
|
|
_LP ┃ ┃ ~ ┃ [ ┃ ' ┃ < ┃ \\ ┃
|
|
|
|
|
_LN ┃ ┃ esc ┃ bs ┃ ret ┃ del ┃ ins ┃
|
|
|
|
|
_LF ┃ ┃ f24 ┃ f23 ┃ f22 ┃ f21 ┃ f24 ┃
|
|
|
|
|
_LD ┃ ┃ 8 ┃ 7 ┃ 6 ┃ 5 ┃ 9 ┃
|
|
|
|
|
╳ Lh┳o ___ __ Lh┳4 ___ __ Lh┳3 ___ __ Lh┳2 ___ __ Lh┳1 ___ __ Lh┳0 ___ __
|
|
|
|
|
_LB ┃ UM ┃ u ┃ i ┃ a ┃ e ┃ o
|
|
|
|
|
_LP ┃ ┃ , ┃ \{ ┃ ? ┃ ! ┃ (
|
|
|
|
|
_LN ┃ ┃ a-< ┃ a-^ ┃ a-v ┃ a-> ┃ tab
|
|
|
|
|
_LF ┃ ┃ f14 ┃ f13 ┃ f12 ┃ f11 ┃ f20
|
|
|
|
|
_LD ┃ ┃ 4 ┃ 3 ┃ 2 ┃ 1 ┃ 0
|
|
|
|
|
╳ Lb┳o ___ __ Lb┳4 ___ __ Lb┳3 ___ __ Lb┳2 ___ __ Lb┳1 ___ __ Lb┳0 ___ __ Lb┳d ___ __
|
|
|
|
|
_LB ┃ S_l CL ┃ % ┃ * ┃ : ┃ p ┃ z ┃ ret
|
|
|
|
|
_LP ┃ ┃ ` ┃ ^ ┃ | ┃ - ┃ @ ┃
|
|
|
|
|
_LN ┃ ┃ hom ┃ p-^ ┃ p-v ┃ end ┃ NUL ┃
|
|
|
|
|
_LF ┃ ┃ f18 ┃ f17 ┃ f16 ┃ f15 ┃ f19 ┃
|
|
|
|
|
_LD ┃ ┃ 8 ┃ 7 ┃ 6 ┃ 5 ┃ 9 ┃
|
|
|
|
|
╳ Lu┳o ___ __ Lu┳4 ___ __ Lu┳3 ___ __ Lu┳2 ___ __ Lu┳1 ___ __
|
|
|
|
|
_LB ┃ a-< ┃ a-^ ┃ a-v ┃ a-> ┃ W
|
|
|
|
|
_LP ┃ ┃ ┃ ┃ ┃
|
|
|
|
|
_LN ┃ ┃ ┃ ┃ ┃
|
|
|
|
|
_LF ┃ ┃ ┃ ┃ ┃
|
|
|
|
|
_LD ┃ ┃ ┃ ┃ ┃
|
|
|
|
|
╳ Lz┳b ___ __ Lz┳c ___ __
|
|
|
|
|
_LB ┃ SCL ┃ LF
|
|
|
|
|
_LP ┃ ┃
|
|
|
|
|
_LN ┃ ┃
|
|
|
|
|
_LF ┃ ┃
|
|
|
|
|
_LD ┃ ┃
|
|
|
|
|
╳ Ly┳a ___ __ Ly┳b ___ __ Ly┳c ___ __
|
|
|
|
|
_LB ┃ spc ┃ C ┃ A
|
|
|
|
|
_LP ┃ ┃ ┃
|
|
|
|
|
_LN ┃ ┃ ┃
|
|
|
|
|
_LF ┃ ┃ ┃
|
|
|
|
|
_LD ┃ ┃ ┃
|
|
|
|
|
╳ Lx┳a ___ __ Lx┳b ___ __ Lx┳c ___ __
|
|
|
|
|
_LB ┃ spc ┃ C _M ┃ A _M
|
|
|
|
|
_LP ┃ ┃ ┃
|
|
|
|
|
_LN ┃ ┃ ┃
|
|
|
|
|
_LF ┃ ┃ ┃
|
|
|
|
|
_LD ┃ ┃ ┃
|
|
|
|
|
EOL
|
|
|
|
|
|
|
|
|
|
right =<<EOL
|
|
|
|
|
╳ Rn┳d ___ __ Rn┳0 ___ __ Rn┳1 ___ __ Rn┳2 ___ __ Rn┳3 ___ __ Rn┳4 ___ __ Rn┳o ___ __
|
|
|
|
|
_LB ┃ 5 ┃ 6 ┃ 7 ┃ 8 ┃ 9 ┃ 0 ┃ 0
|
|
|
|
|
_LP ┃ f5 ┃ f6 ┃ f7 ┃ f8 ┃ f9 ┃ f10 ┃ f12
|
|
|
|
|
_LN ┃ f5 ┃ f6 ┃ f7 ┃ f8 ┃ f9 ┃ f10 ┃ f12
|
|
|
|
|
_LF ┃ f5 ┃ f6 ┃ f7 ┃ f8 ┃ f9 ┃ f10 ┃ f12
|
|
|
|
|
_LD ┃ 5 ┃ 6 ┃ 7 ┃ 8 ┃ 9 ┃ 0 ┃ 0
|
|
|
|
|
╳ Rt┳d ___ __ Rt┳0 ___ __ Rt┳1 ___ __ Rt┳2 ___ __ Rt┳3 ___ __ Rt┳4 ___ __ Rt┳o ___ __
|
|
|
|
|
_LB ┃ NUL ┃ k ┃ h ┃ g ┃ f ┃ q ┃ q
|
|
|
|
|
_LP ┃ ┃ = ┃ > ┃ " ┃ ] ┃ ` ┃ `
|
|
|
|
|
_LN ┃ ┃ 9 ┃ 5 ┃ 6 ┃ 7 ┃ 8 ┃ 8
|
|
|
|
|
_LF ┃ ┃ f24 ┃ f21 ┃ f22 ┃ f23 ┃ f24 ┃ f24
|
|
|
|
|
_LD ┃ ┃ 9 ┃ 5 ┃ 6 ┃ 7 ┃ 8 ┃ 8
|
|
|
|
|
╳ Rh┳0 ___ __ Rh┳1 ___ __ Rh┳2 ___ __ Rh┳3 ___ __ Rh┳4 ___ __ Rh┳o ___ __
|
|
|
|
|
_LB ┃ s ┃ n ┃ r ┃ t ┃ d ┃ UM
|
|
|
|
|
_LP ┃ ) ┃ _ ┃ / ┃ \} ┃ . ┃
|
|
|
|
|
_LN ┃ 0 ┃ 1 ┃ 2 ┃ 3 ┃ 4 ┃
|
|
|
|
|
_LF ┃ f10 ┃ f1 ┃ f2 ┃ f3 ┃ f4 ┃
|
|
|
|
|
_LD ┃ 0 ┃ 1 ┃ 2 ┃ 3 ┃ 4 ┃
|
|
|
|
|
╳ Rb┳d ___ __ Rb┳0 ___ __ Rb┳1 ___ __ Rb┳2 ___ __ Rb┳3 ___ __ Rb┳4 ___ __ Rb┳o ___ __
|
|
|
|
|
_LB ┃ ret ┃ b ┃ m ┃ j ┃ y ┃ ; ┃ S_r CL
|
|
|
|
|
_LP ┃ ┃ + ┃ $ ┃ & ┃ hsh ┃ ^ ┃
|
|
|
|
|
_LN ┃ ┃ 9 ┃ 5 ┃ 6 ┃ 7 ┃ 8 ┃
|
|
|
|
|
_LF ┃ ┃ f9 ┃ f5 ┃ f6 ┃ f7 ┃ f8 ┃
|
|
|
|
|
_LD ┃ ┃ 9 ┃ 5 ┃ 6 ┃ 7 ┃ 8 ┃
|
|
|
|
|
╳ Ru┳1 ___ __ Ru┳2 ___ __ Ru┳3 ___ __ Ru┳4 ___ __ Ru┳o ___ __
|
|
|
|
|
_LB ┃ LN ┃ a-< ┃ a-^ ┃ a-v ┃ a->
|
|
|
|
|
_LP ┃ ┃ ┃ ┃ ┃
|
|
|
|
|
_LN ┃ ┃ ┃ ┃ ┃
|
|
|
|
|
_LF ┃ ┃ ┃ ┃ ┃
|
|
|
|
|
_LD ┃ ┃ ┃ ┃ ┃
|
|
|
|
|
╳ Rz┳c ___ __ Rz┳b ___ __
|
|
|
|
|
_LB ┃ LF ┃ LF _C
|
|
|
|
|
_LP ┃ ┃
|
|
|
|
|
_LN ┃ ┃
|
|
|
|
|
_LF ┃ ┃
|
|
|
|
|
_LD ┃ ┃
|
|
|
|
|
╳ Ry┳c ___ __ Ry┳b ___ __ Ry┳a ___ __
|
|
|
|
|
_LB ┃ men ┃ LF ┃ LP _L
|
|
|
|
|
_LP ┃ ┃ ┃
|
|
|
|
|
_LN ┃ ┃ ┃
|
|
|
|
|
_LF ┃ ┃ ┃
|
|
|
|
|
_LD ┃ ┃ ┃
|
|
|
|
|
╳ Rx┳c ___ __ Rx┳b ___ __ Rx┳a ___ __
|
|
|
|
|
_LB ┃ men ┃ LF ┃ LP _L
|
|
|
|
|
_LP ┃ ┃ ┃
|
|
|
|
|
_LN ┃ ┃ ┃
|
|
|
|
|
_LF ┃ ┃ ┃
|
|
|
|
|
_LD ┃ ┃ ┃
|
|
|
|
|
EOL
|
|
|
|
|
|
|
|
|
|
keys_string = [
|
|
|
|
|
left,
|
|
|
|
|
right,
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
groups = keys_string.flat_map do |str|
|
|
|
|
|
str.gsub(/#.*$/, '').split(/╳/).reject(&:blank?).map(&:lines)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
keys_parsed = {}
|
|
|
|
|
|
|
|
|
|
groups.each.with_index(1) do |group, group_id|
|
|
|
|
|
layers = Key::Layers.size
|
|
|
|
|
|
|
|
|
|
# extract names
|
|
|
|
|
names = group.first
|
|
|
|
|
names = names.scan(/(\S+)(?:[ ]*\t[^\t]*){2}/).map{|name, _| name.strip}
|
|
|
|
|
keyrow = group[1..-1].reject(&:blank?)
|
|
|
|
|
|
|
|
|
|
# sanity check
|
|
|
|
|
if keyrow.size != layers
|
|
|
|
|
raise "wrong number of key layers in group ##{group_id}: #{keyrow}"
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# remove first label
|
|
|
|
|
keyrow = keyrow.map{|l| l.split("┃").drop(1)}
|
|
|
|
|
|
|
|
|
|
(0..(keyrow.size-1)).step(layers).each do |row|
|
|
|
|
|
keyrow[row].size.times do |col|
|
|
|
|
|
key = layers.times.map do |layer|
|
|
|
|
|
keyrow[row+layer][col]
|
|
|
|
|
end
|
|
|
|
|
key = key.map{|l| l.strip.split(/\s+/, 2)}
|
|
|
|
|
name = names[col]
|
|
|
|
|
|
|
|
|
|
raise "name not unique: #{name}" if keys_parsed.include? name
|
|
|
|
|
raise "unknown name: #{name}" unless Key::Names.include? name
|
|
|
|
|
keys_parsed[name] = key
|
|
|
|
|
end
|
|
|
|
|
end
|
2015-12-14 01:28:13 +01:00
|
|
|
|
end
|
|
|
|
|
|
2016-08-22 00:50:03 +02:00
|
|
|
|
keys = keys_parsed.map {|name, layers| Key.new(layers, name)}
|
|
|
|
|
|
2015-12-14 01:28:13 +01:00
|
|
|
|
saneo = Layout.new :saneo, keys
|
|
|
|
|
saneo.save! LayoutFile
|