Module:DropList

local format = require('Module:StringInterpolation').format local getArgs = require('Module:GetArgs') local Ship = require('Module:Ship') local Formatting = require('Module:Formatting')

-- http://kancolle.wikia.com/wiki/Thread:295964 local rare_ships = { 'Akitsushima', 'Akizuki', 'Amagi', 'Isokaze', 'Katsuragi', 'Littorio', 'Prinz Eugen', 'Roma', 'Tokitsukaze', 'Akitsu Maru', 'Bismarck', 'Musashi', 'Noshiro', 'Yamato', 'Taihou', 'Agano', 'Akashi', 'Amatsukaze', 'Asagumo', 'Asashimo', 'Harusame', 'Hatsukaze', 'Hayashimo', 'I-401', 'Katori', 'Kiyoshimo', 'Maruyu', 'Mikuma', 'Nowaki', 'Ooyodo', 'Sakawa', 'Taigei', 'Takanami', 'U-511', 'Unryuu', 'Uzuki', 'Yahagi', 'Z1', 'Z3', 'Tanikaze', 'Maikaze', 'Libeccio', 'Mizuho', 'Kazagumo', 'Umikaze', 'Kawakaze', 'Hayasui', 'Teruzuki', 'Graf Zeppelin', 'Arashi', 'Kashima', 'Hagikaze', }

local args_grammar = { node          = '^%s*(%a)%s*$', comma_list    = '[^,]+', ship_and_nodes = '^%s*(.-)%s*:%s*(.-)%s*$', just_node     = '^%s*(%a)%s*$', node_and_diff = '^%s*(%a)%s*/%s*(%S-)%s*$' }

local diff_colors = { ['Easy']  = '5a5', ['Medium'] = 'da6', ['Hard']  = 'd33', ['?']     = '0ff' }

local diff_names = { ['Easy']  = 'Easy+', ['Medium'] = 'Medium+', ['Hard']  = 'Hard+', ['?']     = '?' }

function find(tbl, v_, k_) for _, v in pairs(tbl) do		if k_ and v[k_] == v_ or not k_ and v == v_ then return true end end return false end

function parseArgs(args)

local tbl = { nodes = {}, rows = {}, debug = '' }

function log(message, value) tbl.debug = tbl.debug .. string.format('%s: %s\n', message, value) end

-- header args local boss = args.boss and string.upper(args.boss) or '?' for node_ in string.gmatch(args.nodes, args_grammar.comma_list) do		local node = node_:match(args_grammar.node) if node then local node = string.upper(node) if find(tbl.nodes, node, 'name') then log('node duplicate', node) else table.insert(tbl.nodes, { name = node, boss = node == boss }) end else log('node syntax error', node_) end end if not find(tbl.nodes, boss, 'name') then log('boss node ignored', boss) end

-- ship args for arg_name, ship_and_nodes in pairs(args) do		if tonumber(arg_name) then local ship, nodes = ship_and_nodes:match(args_grammar.ship_and_nodes) if ship and nodes then local ship_table = Ship:get_table(ship, '') if ship_table and ship_table._type then if find(tbl.rows, ship, 'ship') then log('ship duplicate', ship) else table.insert(tbl.rows, {							ship = ship,							rare = find(rare_ships, ship),							type = Formatting:format_ship_code(ship_table._type) or '?',							nodes = {}						}) local row = tbl.rows[#tbl.rows] for _, node in pairs(tbl.nodes) do							row.nodes[node.name] = nil end for node_and_diff in string.gmatch(nodes, args_grammar.comma_list) do							local node, diff = node_and_diff:match(args_grammar.node_and_diff) if not node or not diff then node = node_and_diff:match(args_grammar.just_node) diff = nil end if node then local node = string.upper(node) if row.nodes[node] then log('ship node duplicate', string.format('%s for %s', node, ship)) elseif not find(tbl.nodes, node, 'name') then log('node ignored', string.format('%s for %s', node, ship)) else row.nodes[node] = { color = diff and diff_colors[diff] or diff_colors['?'], diff = diff and diff_names[diff] or '?' }								end else log('ship node syntax error', string.format('%s for %s', node_and_diff, ship)) end end end else log('ship ignored', ship) end else log('ship syntax error', ship_and_nodes) end end end

return tbl

end

local table_format = { header          = '{| class="article-table sortable" align="center" width="100%" style="text-align:center"\n!Type\n!Ship\n', header_node     = '!width="10%%"|${node}\n', header_boss_node = '!width="10%%" style="background-color:pink;color:red;"|\'\'\'${node}\'\'\'\n', row             = '|-\n', type_cell       = '|${type}\n', ship_cell       = '|${ship}\n', rare_ship_cell  = '| ${ship} \n', node_cell       = '|style="background-color:#${color};"|${diff}\n', empty_cell      = '|\n', footer          = '|}\n', debugger        = [[{| style="width:100%;" align="center" cellspacing="0" class="article-table mw-collapsible mw-collapsed" !Script warnings }
 * ${debug}
 * }]]
 * }]]

function showTable(tbl)

local res = table_format.header

-- header for _, node in pairs(tbl.nodes) do res = res .. format{ node.boss and table_format.header_boss_node or table_format.header_node, node = node.name }	end

-- rows for key, row in pairs(tbl.rows) do		if row.rare then res = res .. table_format.row res = res .. format{table_format.type_cell, type = row.type} res = res .. format{ table_format.rare_ship_cell, ship = row.ship }			for _, node in pairs(tbl.nodes) do				local node = row.nodes[node.name] res = res .. (node and format{					table_format.node_cell,					color = node.color,					diff = node.diff				} or table_format.empty_cell) end end end for key, row in pairs(tbl.rows) do		if not row.rare then res = res .. table_format.row res = res .. format{table_format.type_cell, type = row.type} res = res .. format{ table_format.ship_cell, ship = row.ship }			for _, node in pairs(tbl.nodes) do				local node = row.nodes[node.name] res = res .. (node and format{					table_format.node_cell,					color = node.color,					diff = node.diff				} or table_format.empty_cell) end end end

res = res .. table_format.footer

if tbl.debug ~= '' then res = res .. format{table_format.debugger, debug = tbl.debug} end

return res

end

local DropList = {}

function DropList.show(frame) local args = getArgs{frame = frame:getParent} return showTable(parseArgs(args)) end

return DropList