# 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,
}