Module:Formatting

--Categories: --

local Effects local ResourceIcons = require("Module:ResourceIcons") local StatIcons = require("Module:StatIcons") local format = require("Module:StringInterpolation").format

local Formatting = { _image_template = "", _no_image = "Catbomb.png", _no_image_size = "300px", _resource_template = "${label} ${value}", _stat_with_detail_template = "${stat} (${detail})", _stat_with_max_template = "${stat} (${max})", _remodel_level_template = "Level ${level}", _remodel_items_template = " (${items})", _simple_link = "${link}${section}", _aliased_link = "${text}", _edit_link = '${link} ${text}', _no_edit_link = '[${text}]', _edit_action = "edit", _stat_effect = "${label}${value:+}", _luck_stat_effect = "${label}${value:+.1}", _hidden_stat_effect = "${label}: ${value:+}", _lang_ja_attribute = {lang = "ja"}, _tooltip_style = {cursor = "help", ["border-bottom"] = "1px dotted"}, --["text-decoration"] = "underline dotted" _display_inline_block_css = {display = "inline-block"}, _vertical_align_middle_css = {["vertical-align"] = "middle"}, _div_tag = 'div', _span_tag = 'span', _id_attribute = 'id', _title_attribute = 'title', _extra_style_background_image_template = " background-image: ${bloom}${sparkles}", _strike_template = " ${text} ", _star = "☆", _double_star = "☆ ☆", _triple_star = "☆ ☆ ☆", _quad_star = "☆ ☆ ☆ ☆", _no_star = "-", _excluding_exception_template = "${ship_type} (excluding ${exception})", _all = "All", _all_except = "All except ", _ship_image_template = "${ship_type} ${ship_name} ${api_id:3} ${image_type}.${extension}", _equipment_image_template = "${equipment_name} ${api_id:3} ${image_type}.png", _card_suffix = "Card", _card_damaged_suffix = "Card Damaged", _battle_card_suffix = "Battle", _battle_card_damaged_suffix = "Battle Damaged", _cg_suffix = "Full", _cg_damaged_suffix = "Full Damaged", _fairy_suffix = "Character", _equipment_suffix = "Equipment", _default_extension = { ["Card"] = "jpg", ["Card Damaged"] = "jpg", ["Battle"] = "jpg", ["Battle Damaged"] = "jpg", ["Full"] = "png", ["Full Damaged"] = "png", },	_stats = { "firepower", "bombing", "torpedo", "aa", "armor", "asw", "shelling_accuracy", "evasion", "los", "speed", "luck", "range", },	_hidden_stats = { "torpedo_accuracy", },	_modernization_stats = { "firepower", "torpedo", "aa", "armor", "luck", },	_resources = { "fuel", "ammo", "steel", "bauxite", "devmat", "screw", }, }

function Formatting:_check_effects if not Effects then Effects = require('Module:Effects') end end

function Formatting:seconds_to_hms(seconds) return format{"${hours:2}:${minutes:2}:${seconds:2}", hours = math.floor(seconds / 3600), minutes = math.floor(seconds / 60) % 60, seconds = seconds % 60 } end

function Formatting:format_image(args) local image_options = {}

if not args[1] then table.insert(image_options, self._no_image) else table.insert(image_options, args[1]) end

if args.format then table.insert(image_options, args.format) end

if args.align then table.insert(image_options, args.align) end

if args.valign then table.insert(image_options, args.valign) end

if args.size then table.insert(image_options, args.size) elseif not args[1] then table.insert(image_options, self._no_image_size) end

if args.link ~= nil then table.insert(image_options, "link=" .. (args.link ~= false and args.link or "")) end

if args.caption then table.insert(image_options, args.caption) end

return format{self._image_template, image = table.concat(image_options, "|")} end

function Formatting:inline_block(content, classes, style) local result = mw.html.create(self._div_tag):css(style or {}):css(self._display_inline_block_css):wikitext(content) if classes then if type(classes) == "string" then result:addClass(classes) else for _, class in ipairs(classes or {}) do				result:addClass(class) end end end return tostring(result) end

function Formatting:ship_card(api_id, ship_name, ship_type, extension_override) return self:ship_image(self._card_suffix, api_id, ship_name, ship_type, extension_override) end

function Formatting:ship_card_damaged(api_id, ship_name, ship_type, extension_override) return self:ship_image(self._card_damaged_suffix, api_id, ship_name, ship_type, extension_override) end

function Formatting:ship_battle_card(api_id, ship_name, ship_type, extension_override) return self:ship_image(self._battle_card_suffix, api_id, ship_name, ship_type, extension_override) end

function Formatting:ship_battle_card_damaged(api_id, ship_name, ship_type, extension_override) return self:ship_image(self._battle_card_damaged_suffix, api_id, ship_name, ship_type, extension_override) end

function Formatting:ship_cg(api_id, ship_name, ship_type, extension_override) return self:ship_image(self._cg_suffix, api_id, ship_name, ship_type, extension_override) end

function Formatting:ship_cg_damaged(api_id, ship_name, ship_type, extension_override) return self:ship_image(self._cg_damaged_suffix, api_id, ship_name, ship_type, extension_override) end

function Formatting:ship_image(image_type, api_id, ship_name, ship_type, extension_override) return format{self._ship_image_template, image_type = image_type, api_id = api_id, ship_name = ship_name, ship_type = self:format_ship_code(ship_type), extension = extension_override or self._default_extension[image_type]} end

function Formatting:equipment_card(api_id, equipment_name) return self:equipment_image(self._card_suffix, api_id, equipment_name) end

function Formatting:equipment_fairy(api_id, equipment_name) return self:equipment_image(self._fairy_suffix, api_id, equipment_name) end

function Formatting:equipment_cg(api_id, equipment_name) return self:equipment_image(self._equipment_suffix, api_id, equipment_name) end

function Formatting:equipment_full(api_id, equipment_name) return self:equipment_image(self._cg_suffix, api_id, equipment_name) end

function Formatting:equipment_image(image_type, api_id, equipment_name) return format{self._equipment_image_template, image_type = image_type, api_id = api_id, equipment_name = equipment_name} end

function Formatting:create_formatter(lookup, nil_value) return function(self, stat) if stat == nil then return nil_value or "??" end local result = lookup[stat] if result == nil then return stat else return result end end end

function Formatting:format_resources(resources) local strings = {} for _, resource_type in ipairs(self._resources) do		if resources[resource_type] ~= false then table.insert(strings, format{self._resource_template, label = self:format_image{ResourceIcons[resource_type], caption = Formatting:format_resource_name(resource_type)}, value = self:format_stat(resources[resource_type])}) end end return table.concat(strings, " ") end

function Formatting:format_slot_size(size, estimation) if estimation then return self:_format_slot_size(size) .. "?"	end return self:_format_slot_size(size) end

function Formatting:format_remodel_level_and_item_cost(remodel_level, blueprint, catapult) local item_requirements = self:format_remodel_items(blueprint, catapult) if remodel_level == nil then remodel_level = "??" end local result = format{self._remodel_level_template, level = remodel_level} if item_requirements then result = result .. format{self._remodel_items_template, items = item_requirements} end return result end

function Formatting:format_remodel_items(blueprint, catapult) local items = {} if blueprint ~= false then local value = self:format_image{ResourceIcons.blueprint, size = "24px", caption = Formatting:format_resource_name("blueprint")} if blueprint == nil then value = value .. "?"		end table.insert(items, value) end if catapult ~= false then local value = self:format_image{ResourceIcons.prototype_deck_catapult_item, size = "24px", caption = Formatting:format_resource_name("prototype_deck_catapult_item")} if catapult == nil then value = value .. "?"		end table.insert(items, value) end if #items > 0 then return table.concat(items, " ") end return nil end

function Formatting:format_blueprint_requirement(blueprint, force) if force or (blueprint ~= false) then local value if blueprint == false then value = "✗" elseif blueprint == true then value = self:format_image{ResourceIcons.blueprint, size = "24px", caption = Formatting:format_resource_name("blueprint")} else value = "??" end return value end return "" end

Formatting.format_blueprint_requirement_simple = Formatting.format_blueprint_requirement

function Formatting:format_catapult_requirement(catapult, force) if force or (catapult ~= false) then local value if catapult == false then value = "✗" elseif catapult == true then value = self:format_image{ResourceIcons.prototype_deck_catapult_item, size = "24px", caption = Formatting:format_resource_name("prototype_deck_catapult_item")} else value = "??" end return value end return "" end

function Formatting:format_equipment_icon(icon) if not icon then return "Xx_c.png" end return icon end

function Formatting:format_stat_with_detail(stat, detail) return format{self._stat_with_detail_template, stat = stat, detail = detail} end

function Formatting:format_detailed_aircraft(total, slots) if not slots or #slots == 0 then return self:format_stat(total) else slot_summary = table.concat(slots, ",") return format{self._stat_with_detail_template, stat = total, detail = slot_summary} end end

function Formatting:strike(text) return format{self._strike_template, text = text} end

function Formatting:tooltip(content, title, cursor, extra_style, raw) if not cursor then cursor = self._tooltip_style end result = mw.html.create(self._span_tag):attr(self._title_attribute, title):css(cursor):css(extra_style or {}):wikitext(content) if raw then return result else return tostring(result) end end

function Formatting:japanese_text(japanese, reading, cursor, extra_style, raw) if reading then result = self:tooltip(japanese, reading, cursor, extra_style, true) else result = mw.html.create(self._span_tag):wikiText(japanese) end result = result:attr(self._lang_ja_attribute) if raw then return result else return tostring(result) end end

function Formatting:format_stat_bonuses(stat_table, separator) --normal stats local result = {} for _, stat in ipairs(self._stats) do		local value = stat_table[stat] if value ~= false then table.insert(result, format{self._stat_effect, label = self:format_image{StatIcons[stat], caption = self:format_stat_name(stat)}, value = self:format_stat(value)}) end end result = table.concat(result, separator or " ") if stat_table.special ~= false then local special = self:format_stat(stat_table.special) if result:len == 0 then result = special else result = result .. " " .. special end end

--hidden stats local extra_result = {} for _, stat in ipairs(self._hidden_stats) do		local value = stat_table[stat] if value ~= false then table.insert(extra_result, format{self._hidden_stat_effect, label = self:format_stat_name(stat), value = self:format_stat(value)}) end end if #extra_result > 0 then result = self:tooltip(result, table.concat(extra_result, ", ")) end

return result end

function Formatting:format_bonus(value, label, false_value, decimal) if value ~= false then return format{decimal and self._luck_stat_effect or self._stat_effect, label = label or "", value = self:format_stat(value)} else return false_value or "" end end

function Formatting:format_modernization_bonuses(stat_table) local result = {} for _, stat in ipairs(self._modernization_stats) do		local value = stat_table[stat] if value ~= false then table.insert(result, format{stat == "luck" and self._luck_stat_effect or self._stat_effect, label = self:format_image{StatIcons[stat], caption = self:format_stat_name(stat)}, value = self:format_stat(value)}) end end

return table.concat(result, " ") end

function Formatting:format_stat_with_max(stat, max) if max == false then return self:format_stat(stat) else return format{self._stat_with_max_template, stat = self:format_stat(stat), max = self:format_stat(max)} end end

function Formatting:format_link(link, text, section) if section then section = "#" .. section else section = "" end link = self:format_stat(link) if text then return format{self._aliased_link, link = link, text = text, section = section} else return format{self._simple_link, link = link, section = section} end end

function Formatting:fragment_link(id, prefix, text) if prefix then id = prefix .. "-" .. id	end return Formatting:format_link("", text, id) end

function Formatting:id_span(id, prefix, content, raw) if prefix then id = prefix .. "-" .. id	end local result = mw.html.create(self._span_tag):attr(self._id_attribute, id):wikitext(content) if not raw then result = tostring(result) end return result end

function Formatting:class_span(class, prefix, content, raw) if prefix then class = prefix .. "-" .. class end local result = mw.html.create(self._span_tag):addClass(class):wikitext(content) if not raw then result = tostring(result) end return result end

function Formatting:error_span(content) return self:class_span("error", nil, content) end

function Formatting:format_edit_link(page, text, editintro, tooltip) if page then local args = {action = self._edit_action} if editintro then args.editintro = editintro end if tooltip then text = self:tooltip(text, tooltip) end return format{self._edit_link, text = text, link = tostring(mw.uri.fullUrl(page, args))} else return format{self._no_edit_link, text = self:strike(text)} end end

function Formatting:extra_style_background_image(bloom, sparkles) if bloom or sparkles then self:_check_effects return format{self._extra_style_background_image_template, bloom = bloom and Effects.bloom or "", sparkles = sparkles and Effects.sparkles or ""} end end

function Formatting:format_equipment_compatibility_table(compatibility_table) for index, value in pairs(compatibility_table) do		if type(value) ~= "table" then compatibility_table[index] = self:format_equipment_compatibility(value) else value.value = self:format_equipment_compatibility(value.value) end end end

function Formatting:format_stars(stars) if not stars then return "??" end local result = {} if stars > 0 then while stars > 6 do			table.insert(result, self:inline_block(self._quad_star, nil, self._vertical_align_middle_css)) stars = stars - 4 end while stars > 4 do			table.insert(result, self:inline_block(self._triple_star, nil, self._vertical_align_middle_css)) stars = stars - 3 end if stars == 4 then table.insert(result, self:inline_block(self._quad_star, nil, self._vertical_align_middle_css)) elseif stars == 3 then table.insert(result, self:inline_block(self._triple_star, nil, self._vertical_align_middle_css)) elseif stars == 2 then table.insert(result, self:inline_block(self._double_star, nil, self._vertical_align_middle_css)) elseif stars == 1 then table.insert(result, self:inline_block(self._star, nil, self._vertical_align_middle_css)) end else table.insert(result, self:inline_block(self._no_star, nil, self._vertical_align_middle_css)) end return table.concat(result, " ") end

Formatting.format_boolean = Formatting:create_formatter({	[true] = "Yes",	[false] = "No", })

Formatting.format_stat_name = Formatting:create_formatter({	firepower = "Firepower",	bombing = "Bombing",	torpedo = "Torpedo",	aa = "AA",	armor = "Armor",	asw = "ASW",	shelling_accuracy = "Accuracy",	evasion = "Evasion",	los = "LOS",	speed = "Speed",	luck = "Luck",	range = "Range",	torpedo_accuracy = "Torpedo Accuracy (Unused)",	hp = "HP",	fuel = "Max Fuel Consumption",	ammo = "Max Ammo Consumption",	remodel = "Remodel Level",	aircraft = "Aircraft", })

Formatting.format_resource_name = Formatting:create_formatter({	fuel = "Fuel",	ammo = "Ammunition",	steel = "Steel",	bauxite = "Bauxite",	blueprint = "Blueprint",	bucket = "Instant Repair",	torch = "Instant Construction",	devmat = "Development Material",	screw = "Improvement Material",	development_material = "Development Material",	improvement_material = "Improvement Material",	furniture_coin = "Furniture Coin",	furniture_coin_box_small = "Furniture Coin Box (Small)",	furniture_coin_box_medium = "Furniture Coin Box (Medium)",	furniture_coin_box_large = "Furniture Coin Box (Large)",	mamiya = "Mamiya",	irako = "Irako",	medal = "Medal",	first_class_medal = "First Class Medal",	prototype_deck_catapult = "Prototype Deck Catapult",	prototype_deck_catapult_item = "Prototype Deck Catapult", })

Formatting.format_ship_back = Formatting:create_formatter({	[0] = "whitesmoke",	[1] = "#8eb0ed",	[2] = "#afddfa",	[3] = "#92d1cf",	[4] = "silver",	[5] = "#ffe140",	[6] = "#eebbee",	[7] = "#eebbee",	[8] = "#eebbee",	[-1] = "#aab3b2",	[-2] = "#cc1414",	[-3] = "#fff133",	[-4] = "#aab3b2",	[-5] = "#cc1414",	[-6] = "#fff133",	[-7] = "#aab3b2",	[-8] = "#cc1414",	[-9] = "#fff133",	[-10] = "#bf1313",	[-11] = "#bf1313",	[-12] = "#e61616",	}, "whitesmoke")

Formatting.format_equipment_back = Formatting:create_formatter({	[-2] = "deepskyblue", --repair team	[-1] = "lightskyblue", --a kohyoteki, daihatsu	[0] = "whitesmoke",	[1] = "lightgrey",	[2] = "lightblue",	[3] = "#eebbee",	[4] = "#eebbee",	[5] = "#eebbee",	}, "whitesmoke")

Formatting.format_equipment_compatibility = Formatting:create_formatter({	[0] = "whitesmoke",	[1] = "#73ff4d",	[2] = "#ffff40",	}, "transparent")

Formatting.format_stat = Formatting:create_formatter({	[false] = "",	})

Formatting._format_slot_size = Formatting:create_formatter({	[false] = "-",	})

Formatting.format_speed = Formatting:create_formatter({	[0] = "None",	[5] = "Slow",	[10] = "Fast",	})

Formatting.format_range = Formatting:create_formatter({	[0] = "None",	[1] = "Short",	[2] = "Medium",	[3] = "Long",	[4] = "Very Long",	})

Formatting.format_ship_rarity = Formatting:create_formatter({	[1] = "Very Common",	[2] = "Common",	[3] = "Uncommon",	[4] = "Rare",	[5] = "Very Rare",	[6] = "Holo",	[7] = "S Holo",	[8] = "SS Holo",	[-1] = "Abyssal",	[-2] = "Elite",	[-3] = "Flagship",	[-4] = "Kai",	[-5] = "Kai Elite",	[-6] = "Kai Flagship",	[-7] = "Late Model",	[-8] = "Late Model Elite",	[-9] = "Late Model Flagship",	[-10] = "Abyssal Boss", --grey background	[-11] = "Abyssal Boss", --red background	[-12] = "Abyssal Boss (Final Form)",	})

Formatting.format_ship_type = Formatting:create_formatter({	[false] = "-",	[1] = "Coastal Defence Ship",	[2] = "Destroyer",	[3] = "Light Cruiser",	[4] = "Torpedo Cruiser",	[5] = "Heavy Cruiser",	[6] = "Aviation Cruiser",	[7] = "Light Carrier",	[8] = "Fast Battleship",	[9] = "Battleship",	[10] = "Aviation Battleship",	[11] = "Standard Carrier",	[12] = "Super Dreadnought",	[13] = "Submarine",	[14] = "Aircraft Carrying Submarine",	[15] = "Transport Ship",	[16] = "Seaplane Tender",	[17] = "Amphibious Assault Ship",	[18] = "Armored Carrier",	[19] = "Repair Ship",	[20] = "Submarine Tender",	[21] = "Training Cruiser",	[22] = "Fleet Oiler",	})

Formatting.format_ship_code = Formatting:create_formatter({	[1] = "PF",	[2] = "DD",	[3] = "CL",	[4] = "CLT",	[5] = "CA",	[6] = "CAV",	[7] = "CVL",	[8] = "FBB",	[9] = "BB",	[10] = "BBV",	[11] = "CV",	[12] = "B",	[13] = "SS",	[14] = "SSV",	[15] = "AP",	[16] = "AV",	[17] = "LHA",	[18] = "CVB",	[19] = "AR",	[20] = "AS",	[21] = "CT",	[22] = "AO",	})

function Formatting:format_ship_compatibility(compatibility_table) if compatibility_table[3] == compatibility_table[4] then compatibility_table[3] = {value = compatibility_table[3], code = "CL(T)"} compatibility_table[4] = false end if compatibility_table[5] == compatibility_table[6] then compatibility_table[5] = {value = compatibility_table[5], code = "CA(V)"} compatibility_table[6] = false end if compatibility_table[18] == compatibility_table[11] then compatibility_table[18] = false end if compatibility_table[7] == compatibility_table[11] then compatibility_table[7] = false compatibility_table[11] = {value = compatibility_table[11], code = "CV(L)"} end if compatibility_table[9] == compatibility_table[10] then compatibility_table[9] = {value = compatibility_table[9], code = "BB(V)"} compatibility_table[10] = false end if compatibility_table[13] == compatibility_table[14] then compatibility_table[13] = {value = compatibility_table[13], code = "SS(V)"} compatibility_table[14] = false end compatibility_table[1] = false compatibility_table[12] = false compatibility_table[15] = false local compatible = {} local incompatible = {} for ship_type, compatibility_value in ipairs(compatibility_table) do		local code = Formatting:format_ship_code(ship_type) if type(compatibility_value) == "table" then code = compatibility_value.code compatibility_value = compatibility_value.value end if compatibility_value == 0 then table.insert(incompatible, code) elseif compatibility_value == 1 then table.insert(compatible, code) elseif compatibility_value == 2 then table.insert(compatible, code) table.insert(incompatible, format{self._excluding_exception_template, ship_type = Formatting:format_ship_code(ship_type), exception = code}) end end if #incompatible < 5 then if #incompatible == 0 then return self._all end return self._all_except .. table.concat(incompatible, ", ") else return table.concat(compatible, ", ") end end

Formatting.format_equipment_type = Formatting:create_formatter({	[1] = "Small Caliber Main Gun",	[2] = "Medium Caliber Main Gun",	[3] = "Large Caliber Main Gun",	[4] = "Secondary Gun",	[5] = "Torpedo",	[6] = "Carrier-based Fighter Aircraft",	[7] = "Carrier-based Dive Bomber",	[8] = "Carrier-based Torpedo Bomber",	[9] = "Carrier-based Reconnaissance Aircraft",	[10] = "Reconnaissance Seaplane",	[11] = "Seaplane Bomber",	[12] = "Small Radar",	[13] = "Large Radar",	[14] = "Sonar",	[15] = "Depth Charge",	[16] = "Extra Armor",	[17] = "Engine Improvement",	[18] = "Anti-Aircraft Shell",	[19] = "Armor Piercing Shell",	[20] = "VT Fuze",	[21] = "Anti-Aircraft Gun",	[22] = "Midget Submarine",	[23] = "Damage Control Personnel",	[24] = "Landing Craft",	[25] = "Autogyro",	[26] = "Anti-submarine Patrol Aircraft",	[27] = "Extra Armor (Medium)",	[28] = "Extra Armor (Large)",	[29] = "Searchlight",	[30] = "Supply Transport Container", [31] = "Ship Repair Facility", [32] = "Submarine Torpedo", [33] = "Star Shell", [34] = "Command Facility", [35] = "Aviation Personnel", [36] = "Anti-Aircraft Fire Director", [37] = "Anti-Ground Equipment", [38] = "Large Caliber Main Gun (II)", [39] = "Surface Ship Personnel", [40] = "Large Sonar", [41] = "Large Flying Boat", [42] = "Large Searchlight", [43] = "Combat Ration", [44] = "Supplies", [93] = "Large Radar (II)", [94] = "Carrier-based Reconnaissance Aircraft (II)", })

Formatting.format_equipment_icon = Formatting:create_formatter({	[false] = "Xx_c.png",	[1] = "RedGunLight.png",	[2] = "RedGunMedium.png",	[3] = "RedGunHeavy.png",	[4] = "YellowGun.png",	[5] = "Torpedo.png",	[6] = "GreenPlane.png",	[7] = "RedPlane.png",	[8] = "BluePlane.png",	[9] = "YellowPlane.png",	[10] = "Seaplane.png",	[11] = "Radar.png",	[12] = "GreenAmmo.png",	[13] = "RedAmmo.png",	[14] = "EmergencyRepair.png",	[15] = "GreenGunMG.png",	[16] = "GreenGunDP.png",	[17] = "DepthCharge.png",	[18] = "Sonar.png",	[19] = "Turbine.png",	[20] = "LandingCraft.png",	[21] = "Heli.png",	[22] = "Subplane.png",	[23] = "Expansion Bulge (Medium).png",	[24] = "Searchlight.png",	[25] = "Drum.png",	[26] = "Facility.png",	[27] = "FlareIcon.png",	[28] = "Cf_c.png",	[29] = "Ap_c.png",	[30] = "Aafd_c.png",	[31] = "Agat_c.png",	[32] = "Ssp_c.png",	[33] = "Large Flying Boat Icon.png",	[34] = "Combat Provisions Icon.png", [35] = "Supplies Icon.png", }, "Xx_c.png")

Formatting.format_equipment_rarity = Formatting:create_formatter({	[0] = "Common",	[1] = "Rare",	[2] = "Holo",	[3] = "S Holo",	[4] = "SS Holo",	[5] = "SS Holo",	})

return Formatting