Module:Data Table/Tags

local File = require("Module:File") local Franchise = require("Module:Franchise") local GalleryList = require("Module:Gallery List") local Sequences = require("Module:Sequences") local Term = require("Module:Term") local TermList = require("Module:Term List") local utilsMarkup = require("Module:UtilsMarkup") local utilsString = require("Module:UtilsString") local utilsTable = require("Module:UtilsTable")

local frame = mw.getCurrentFrame

local playerNameOutput local function playerName return playerNameOutput or frame:expandTemplate({		title = "Player Name"	}) end

local function list(items, listType) if listType == "*" then return utilsMarkup.bulletList(items) elseif listType == "#" then return utilsMarkup.numberList(items) elseif listType == "plain" then return utilsMarkup.list(items) elseif #items > 1 then return utilsMarkup.list(items) else return items[1] end end

local function value(templateName, hasGameParam) return function(cell, tableArgs, tagArgs) local values = utilsString.split(cell, '%s*,[%D+|%s*]') local amountGame = tableArgs.game or tagArgs[1] local format = tagArgs[2] local cellSize = 0 local sortValue values = utilsTable.map(values, function(value)			local value, info = utilsMarkup.separateMarkup(value)			if #values == 1 then				sortValue = value:gsub(",", "")			end			cellSize = math.max(cellSize, value:len)			local args = {value, format}			if hasGameParam then				table.insert(args, 1, amountGame)			end			local text = frame:expandTemplate({ title = templateName, args = args, })			return text..info		end) local valuesList = list(values, "plain") return { text = valuesList, size = cell:len, sortValue = sortValue }	end end

local function terms(tagName, plural) return function(cell, tableArgs, tagArgs) local game = tagArgs[1] or tableArgs.game cell = string.gsub(cell, "%[Player Name%]", "Link") local pages if tagName == "Term" or tagName == "Plural" then pages = {cell} else pages = utilsString.split(cell) end local entries = utilsTable.map(pages, function(page)			return GalleryList.entry(game, "", page, { plural = plural, link = true })		end)

local cellSize = 0 for i, entry in ipairs(entries) do			local term = entry.term or "" cellSize = math.max(term:len, cellSize) end local isBulletList = tagName == "TermList" or tagName == "PluralList" local links = utilsTable.map(entries, "link") local list = list(links, isBulletList and "*" or "plain") local sortValue if #entries == 1 then sortValue = entries[1].term end return { text = list, sortValue = sortValue, size = cellSize }	end end

local spanningCellsByColumn = {} local spanCountsByColumn = {} function computeRowspan(cell) local columnIndex = cell.columnIndex if not columnIndex then return end local spanningCell = spanningCellsByColumn[columnIndex] local spanCount = spanCountsByColumn[columnIndex] if not spanningCell then spanningCell = cell spanCount = 1 elseif tostring(cell.content) == tostring(spanningCell.content) then cell.skip = true spanCount = spanCount + 1 else spanningCell.rowspan = spanCount spanningCell = cell spanCount = 1 end if cell.isLastRow then spanningCell.rowspan = spanCount end spanCountsByColumn[columnIndex] = spanCount spanningCellsByColumn[columnIndex] = spanningCell end

local p = { -- Tags in the source table which should not be automatically brought over to copies of the table nonCopiedTags = {"Width"}, -- Each function must return a table containing: -- text (required), the text to display in the cell -- size (optional), an estimation of the cell's width in characters -- sortValue (optional), a column sort value — column is unsortable if false, sorted by its content if nil contentTags = { [""] = function(cell) -- default: no tags local text = string.gsub(cell, "%[Player Name%]", playerName) local sortValue local markupStripped = string.gsub(text, "'", "") -- strip any bold or italics formatting local leadingNumber = string.match(markupStripped, "^(%d[%d,]*)") if leadingNumber then leadingNumber = string.gsub(leadingNumber, ",", "") leadingNumber = tonumber(leadingNumber) sortValue = leadingNumber end return { text = cell, size = cell:len, sortValue = sortValue, }		end, ["EmptyCell"] = function(cell) -- special case: empty cell return { text = " ", sortValue = "", size = 0, }		end, ["NotApplicable"] = function(cell) -- special case: cell starts with N/A local text, info = utilsMarkup.separateMarkup(cell) local tooltip = utilsMarkup.tooltip("—", "Not Applicable") text = text:gsub("N/A", tooltip) return { text = text..info, sortValue = text, size = cell:len, }		end,

-- Tags ["Amounts"] = function(cell, tableArgs, tagArgs) local text = frame:expandTemplate({				title = "Amounts",				args = {tableArgs.game, cell}			})

local cellSize = 0 local amounts = utilsString.split(cell, '%s*,[%D+|%s*]') for i, amount in ipairs(amounts) do				local item = string.gsub(amount, "$[%d,]+ ", "") local subject, info = utilsMarkup.separateMarkup(item) cellSize = math.max(cellSize, subject:len) end

return { text = text, size = cellSize, sortValue = false, }		end, ["Defense"] = value("Defense", true), ["Description"] = function(cell, tableArgs, tagArgs) local text = string.gsub(cell, "%[Player Name%]", playerName) text = "\n"..text.."\n" -- bullet lists don't work without the newlines return { text = text, size = cell:len, sortValue = false, }		end, ["Effect"] = value("Effect", false), ["HeartAmount"] = function(cell, tableArgs, tagArgs) local text = frame:expandTemplate({				title = "HeartAmount",				args = {cell, "true"}			}) return { text = text, size = 12, sortValue = cell }		end, ["IconList"] = function(cell, tableArgs, tagArgs) local cellSize = 0 local listItems = utilsString.split(cell) for i, listItem in ipairs(listItems) do				cellSize = math.max(listItem:len, cellSize) end local iconList = frame:expandTemplate({				title = "Icon List",				args = {tableArgs.game, cell}			}) return { text = iconList, size = cellSize, sortValue = false, }		end, ["Image"] = function(cell, tableArgs, tagArgs) cell = string.gsub(cell, "%[Player Name%]", "Link") local fileType = tagArgs[1] or Franchise.graphics(tableArgs.game) == "2D" and "Sprite" or "Icon" local entry = GalleryList.entry(tableArgs.game, fileType, cell, {				useTerms = false,			}) local image = File.image(entry.file, {				size = tagArgs[2] or "64x64px",			}) return { text = image, size = 20, sortValue = false, }		end, ["List"] = function(cell, tableArgs, tagArgs) local listItems = utilsString.split(cell, '%s*,[%D+|%s*]') local cellSize = 0 for i, listItem in ipairs(listItems) do				cellSize = math.max(cellSize, listItem:len) end local list = list(listItems, tagArgs[1] or "*") return { text = list, sortValue = false, }		end, ["Mon"] = value("Mon", false), ["Name"] = function(cell, tableArgs, tagArgs) local cellSize = cell:len local text = string.gsub(cell, "%[Player Name%]", playerName) local text = GalleryList.parseVariant(text) return { text = text, }		end, ["Plural"] = terms("Plural", true), ["PluralList"] = terms("PluralList", true), ["Rupees"] = value("Rupee", true), ["SortValue"] = function(cell, tableArgs, tagArgs) cell = string.gsub(cell, "%[Player Name%]", "Link") local sortValue = Sequences.sortValue(tableArgs.game, nil, cell) local termLink = Term.link(cell, tableArgs.game) return { size = cell:len, text = termLink, sortValue = sortValue, }		end, ["Term"] = terms("Term"), ["Terms"] = terms("Terms"), ["TermList"] = terms("TermList"), ["Transcript"] = function(cell, tableArgs, tagArgs) local text = string.gsub(cell, "%[Player Name%]", playerName) text = "\n"..text.."\n" -- bullet lists don't work without the newlines return { text = text, size = cell:len, sortValue = false, }		end, },	attributeTags = { ["ID"] = function(cell, tableArgs, tagArgs) cell.id = string.gsub(cell.raw, "%[Player Name%]", "Link") end, ["Nowrap"] = function(cell, tableArgs, tagArgs) cell.content:addClass("data-table__cell-content--nowrap") end, ["Rowspan"] = function(cell, tableArgs, tagArgs) computeRowspan(cell) end, ["Unsortable"] = function(cell, tableArgs, tagArgs) cell.sortValue = false end, ["Width"] = function(cell, tableArgs, tagArgs) cell.styles = cell.styles or {} cell.styles["width"] = tagArgs[1] end, } }

return p