# Module:Key

-- This module implements .  

local kbdPrefix = '<kbd>'  

local kbdSuffix = '</kbd>'  

local keyText = {  
['caps lock'] = '⇪ Caps Lock',  
['caps lock'] = '⇪ Caps Lock',  
['shift'] = '⇧ Shift',  
['shift'] = '⇧ Shift',  
['enter'] = '↵ Enter',  
['enter'] = '↵ Enter',  
['cmd'] = '⌘ Cmd',  
['cmd'] = '⌘ Cmd',  
['command'] = '⌘ Command',  
['command'] = '⌘ Command',  
['opt'] = '⌥ Opt',  
['opt'] = '⌥ Opt',  
['option'] = '⌥ Option',  
['option'] = '⌥ Option',  
['tab'] = 'Tab ↹',  
['tab'] = 'Tab ↹',  
['backspace'] = '← Backspace',  
['backspace'] = '← Backspace',  
['win'] = '⊞ Win',  
['win'] = '⊞ Win',  
['menu'] = '≣ Menu',  
['menu'] = '≣ Menu',  
['up'] = '↑',  
['up'] = '↑',  
['down'] = '↓',  
['down'] = '↓',  
[''] = '←',  
['[[arrow keys|]]'] = '←',  
[''] = '→',  
['[[arrow keys|]]'] = '→',  
['asterisk'] = '&#42;',  
['hash'] = '&#35;',  
['#'] = '#',  
['colon'] = '&#58;',  
[':'] = ':',  
['pipe'] = '&#124;',  
['[[|]]'] = '&#124;',  
['semicolon'] = '&#59;',  
[';'] = '&#59;',  
['equals'] = '&#61;',  

-- Left & analog sticks.  
['l up'] = 'L↑',  
['l down'] = 'L↓',  
['l '] = 'L←',  
['l '] = 'L→',  
['l ne'] = 'L↗',  
['l se'] = 'L↘',  
['l nw'] = 'L↖',  
['l sw'] = 'L↙',  

['r up'] = 'R↑',  
['r down'] = 'R↓',  
['r '] = 'R←',  
['r '] = 'R→',  
['r ne'] = 'R↗',  
['r se'] = 'R↘',  
['r nw'] = 'R↖',  
['r sw'] = 'R↙',  

-- PlayStation.  
['ex'] = '×',  
['circle'] = '○',  
['square'] = '□',  
['triangle'] = '△',  

-- Nintendo 64 and GameCube.  
['c up'] = 'C↑',  
['c down'] = 'C↓',  
['c '] = 'C←',  
['c '] = 'C→',  
['c ne'] = 'C↗',  
['c se'] = 'C↘',  
['c nw'] = 'C↖',  
['c sw'] = 'C↙',  
}  

local keyAlias = {  
-- ['alternate name for key (alias)'] = 'name for key used in key table'  
['cmd'] = 'cmd',  
['command'] = 'command',  
['opt'] = 'opt',  
['option key'] = 'option',  
['option'] = 'option',  
['win'] = 'win',  
['*'] = 'asterisk',  
['#'] = 'hash',  
[':'] = 'colon',  
[';'] = 'semicolon',  
['l-up'] = 'l up',  
['l-down'] = 'l down',  
['l-'] = 'l ',  
['l-'] = 'l ',  
['l-ne'] = 'l ne',  
['l-se'] = 'l se',  
['l-nw'] = 'l nw',  
['l-sw'] = 'l sw',  
['r-up'] = 'r up',  
['r-down'] = 'r down',  
['r-'] = 'r ',  
['r-'] = 'r ',  
['r-ne'] = 'r ne',  
['r-se'] = 'r se',  
['r-nw'] = 'r nw',  
['r-sw'] = 'r sw',  
['ps x'] = 'ex',  
['ps c'] = 'circle',  
['ps s'] = 'square',  
['ps t'] = 'triangle',  
['c-up'] = 'c up',  
['c-down'] = 'c down',  
['c-'] = 'c ',  
['c-'] = 'c ',  
['c-ne'] = 'c ne',  
['c-se'] = 'c se',  
['c-nw'] = 'c nw',  
['c-sw'] = 'c sw',  
}  

local Collection = {}  
Collection.__index = Collection  
do  
function Collection:add(item)  
if item ~= nil then  
self.n = self.n + 1  
self[self.n] = item  
end  
end  
function Collection:join(sep)  
return table.concat(self, sep)  
end  
function Collection:sort(comp)  
table.sort(self, comp)  
end  
function Collection.new  
return setmetatable({n = 0}, Collection)  
end  
end  

local function keyPress(args)  
local chainNames = {  
'chain first',  
'chain second',  
'chain third',  
'chain fourth',  
'chain fifth',  
'chain sixth',  
'chain seventh',  
'chain eighth',  
'chain ninth',  
}  
local result = Collection.new  
local chainDefault = args.chain or '+'  
for i, id in ipairs(args) do  
if i > 1 then  
result:add(args[chainNames[i - 1]] or chainDefault)  
end  
local lc = id:lower  
local text = keyText[lc] or keyText[keyAlias[lc]] or id  
result:add(kbdPrefix .. text .. kbdSuffix)  
end  
return mw.getCurrentFrame:extensionTag{  
name = 'templatestyles', args = { src = 'Template:Key press/styles.css'}  
} .. result:join  
end  

local function keypress  
-- Called by "".  
-- Using the template doubles the post‐expand include size.  
return keyPress(:getParent.args)  
end  

local function press  
-- Called by "".  
return keyPress(.args)  
end  

return {  
keypress = keypress,  
press = press,  
}