Module:Data Table/Tags: Difference between revisions
From Zelda Wiki, the Zelda encyclopedia
no edit summary
PhantomCaleb (talk | contribs) No edit summary |
PhantomCaleb (talk | contribs) No edit summary |
||
(26 intermediate revisions by 2 users not shown) | |||
Line 18: | Line 18: | ||
end | end | ||
local function list(items, | local function list(items, listType) | ||
if | if listType == "*" then | ||
return utilsMarkup.bulletList(items) | return utilsMarkup.bulletList(items) | ||
elseif listType == "#" then | |||
return utilsMarkup.numberList(items) | |||
elseif listType == "plain" then | |||
return utilsMarkup.list(items) | |||
elseif #items > 1 then | elseif #items > 1 then | ||
return utilsMarkup.list(items) | return utilsMarkup.list(items) | ||
Line 29: | Line 33: | ||
local function value(templateName, hasGameParam) | local function value(templateName, hasGameParam) | ||
return function(cell, tableArgs, tagArgs) | return { | ||
formatter = 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 | local sortValue | ||
local text | |||
if #values == 1 then | if #values == 1 then | ||
local value, info = utilsMarkup.separateMarkup(values[1]) | |||
sortValue = value:gsub(",", "") | sortValue = value:gsub(",", "") | ||
if value == "" then | |||
text = info | |||
end | |||
end | end | ||
cellSize = math.max(cellSize, value:len()) | if not text then | ||
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) | |||
text = list(values, "plain") | |||
end | end | ||
return { | |||
text = text, | |||
size = cell:len(), | |||
sortValue = sortValue | |||
} | |||
end | |||
} | |||
end | end | ||
local function | local function links(tagName) | ||
return function(cell, tableArgs, tagArgs) | return { | ||
cell = string.gsub(cell, "%[Player Name%]", "Link") | formatter = 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) | |||
-- We use GalleryList here because we have to be aware of any GalleryList syntax that could be present in the cell, | |||
-- which may be the case if the [Image] tag is also applied to the column | |||
return GalleryList.parseEntry(page, game, "", { | |||
plural = tagName == "Plural" or tagName == "PluralList", | |||
link = true, | |||
useTerms = tagName ~= "LinkList", | |||
}) | |||
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" or tagName == "LinkList" | |||
local links = utilsTable.map(entries, function(entry) | |||
return entry.link..entry.info | |||
end) | |||
local text | |||
if #entries == 1 and entries[1].link == "[[]]" then | |||
text = entries[1].info | |||
else | |||
text = list(links, isBulletList and "*" or "plain") | |||
end | |||
local sortValue | |||
if #entries == 1 then | |||
sortValue = entries[1].term | |||
end | |||
return { | |||
text = text, | |||
sortValue = sortValue, | |||
size = cellSize | |||
} | |||
end | end | ||
} | |||
end | end | ||
local | local spanningCellsByColumn = {} | ||
local | local spanCountsByColumn = {} | ||
function computeRowspan(cell) | function computeRowspan(cell) | ||
local columnIndex = cell.columnIndex | |||
if not columnIndex then | |||
return | |||
end | |||
local spanningCell = spanningCellsByColumn[columnIndex] | |||
local spanCount = spanCountsByColumn[columnIndex] | |||
local na = string.find(tostring(cell.content), "Not Applicable") | |||
if not spanningCell then | if not spanningCell then | ||
spanningCell = cell | spanningCell = cell | ||
spanCount = 1 | spanCount = 1 | ||
elseif tostring(cell.content) == tostring(spanningCell.content) then | elseif tostring(cell.content) == tostring(spanningCell.content) and not na then | ||
cell.skip = true | cell.skip = true | ||
spanCount = spanCount + 1 | spanCount = spanCount + 1 | ||
Line 113: | Line 155: | ||
spanningCell.rowspan = spanCount | spanningCell.rowspan = spanCount | ||
end | end | ||
spanCountsByColumn[columnIndex] = spanCount | |||
spanningCellsByColumn[columnIndex] = spanningCell | |||
end | |||
-- So that the template is evaluated at most once per page | |||
local NA | |||
function notApplicable() | |||
NA = NA or mw.getCurrentFrame():expandTemplate({ title = "NA" }) | |||
return NA | |||
end | end | ||
local p = { | local p = { | ||
-- | -- formatter (required): a function that returns an object with the following properties: | ||
-- - 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 | |||
-- size (optional) | |||
-- sortValue (optional) | -- noCopy (optional): if set to true, the tag will not be automatically carried over to copies of the table | ||
contentTags = { | contentTags = { | ||
[""] = function(cell) -- default: no tags | [""] = { | ||
formatter = 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,]*)") | ||
end, | if leadingNumber then | ||
["NotApplicable"] = function(cell) -- special case: cell starts with N/A | leadingNumber = string.gsub(leadingNumber, ",", "") | ||
leadingNumber = tonumber(leadingNumber) | |||
sortValue = leadingNumber | |||
end | |||
return { | |||
text = cell, | |||
size = cell:len(), | |||
sortValue = sortValue, | |||
} | |||
end, | |||
}, | |||
["EmptyCell"] = { | |||
formatter = function(cell) -- special case: empty cell | |||
return { | |||
text = " ", | |||
sortValue = "", | |||
size = 0, | |||
} | |||
end, | |||
}, | |||
["NotApplicable"] = { | |||
formatter = function(cell) -- special case: cell starts with N/A | |||
local text, info = utilsMarkup.separateMarkup(cell) | |||
text = text:gsub("N/A", notApplicable()) | |||
return { | |||
text = text..info, | |||
sortValue = text, | |||
size = cell:len(), | |||
} | |||
end, | |||
}, | |||
-- | ["Amounts"] = { | ||
[" | formatter = function(cell, tableArgs, tagArgs) | ||
local text = frame:expandTemplate({ | |||
title = " | 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()) | |||
if #amounts == 1 and subject == "" then | |||
text = info | |||
end | |||
end | |||
return { | |||
text = text, | |||
size = cellSize, | |||
sortValue = false, | |||
} | |||
end, | |||
}, | |||
["Code"] = { | |||
formatter = function(cell, tableArgs, tagArgs) | |||
local value, info = utilsMarkup.separateMarkup(cell) | |||
return { | |||
text = "<code>"..value.."</code>"..info, | |||
size = value:len(), | |||
} | |||
end, | |||
}, | |||
["Defense"] = value("Defense", true), | |||
["Description"] = { | |||
formatter = 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"] = { | |||
formatter = function(cell, tableArgs, tagArgs) | |||
local text = frame:expandTemplate({ | |||
title = "HeartAmount", | |||
args = {cell, "true"} | |||
}) | |||
return { | |||
text = text, | |||
size = 12, | |||
sortValue = cell | |||
} | |||
end, | |||
}, | |||
["IconList"] = { | |||
formatter = 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"] = { | |||
formatter = 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.parseEntry(cell, tableArgs.game, fileType, { | |||
useTerms = false, | |||
}) | |||
local image = File.image(entry.file, { | |||
size = tagArgs[2] or "64x64px", | |||
checkExists = false, | |||
}) | |||
return { | |||
text = image, | |||
size = 20, | |||
sortValue = false, | |||
} | |||
end, | |||
}, | |||
["Link"] = { | |||
formatter = function(cell, tableArgs, tagArgs) | |||
local cellSize = cell:len() | |||
-- We use GalleryList here because we have to be aware of any GalleryList syntax that could be present in the cell, | |||
-- which may be the case if the [Image] tag is also applied to the column | |||
-- We have to escape the brackets in [Player Name] so that GalleryList doesn't parse it as a variant | |||
local entry = GalleryList.parseEntry(cell, "", "", { | |||
useTerms = false | |||
}) | |||
local text | |||
if entry.subject ~= "" then | |||
text = "[["..entry.subject.."]]"..entry.info | |||
else | |||
text = entry.info | |||
end | |||
return { | |||
text = text, | |||
sortValue = entry.subject | |||
} | |||
end, | |||
}, | |||
["LinkList"] = links("LinkList"), | |||
["List"] = { | |||
formatter = 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), | ["Mon"] = value("Mon", false), | ||
["Name"] = function(cell, tableArgs, tagArgs) | ["Name"] = { | ||
formatter = function(cell, tableArgs, tagArgs) | |||
local cellSize = cell:len() | |||
-- We use GalleryList here because we have to be aware of any GalleryList syntax that could be present in the cell, | |||
-- which may be the case if the [Image] tag is also applied to the column | |||
-- We have to escape the brackets in [Player Name] so that GalleryList doesn't parse it as a variant | |||
local text = string.gsub(cell, "%[Player Name%]", "{Player Name}") | |||
local entry = GalleryList.parseEntry(text, "", "", { | |||
["Plural"] = | useTerms = false | ||
["PluralList"] = | }) | ||
local text = string.gsub(entry.subject, "{Player Name}", playerName())..entry.info | |||
return { | |||
text = text, | |||
sortValue = text, | |||
} | |||
end, | |||
}, | |||
["Plural"] = links("Plural"), | |||
["PluralList"] = links("PluralList"), | |||
["Rupees"] = value("Rupee", true), | ["Rupees"] = value("Rupee", true), | ||
["SortValue"] = function(cell, tableArgs, tagArgs) | ["SortValue"] = { | ||
formatter = 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"] = | end, | ||
["Terms"] = | }, | ||
["TermList"] = | ["SyntaxHighlight"] = { | ||
["Transcript"] = function(cell, tableArgs, tagArgs) | formatter = function(cell, tableArgs, tagArgs) | ||
local text, notes = utilsMarkup.separateMarkup(cell) | |||
local codeBlock = frame:extensionTag({ | |||
name = "syntaxhighlight", | |||
args = { | |||
inline = true, | |||
lang = tagArgs[1] or "lua" | |||
}, | |||
content = text | |||
}) | |||
return { | |||
text = codeBlock..notes, | |||
size = text:len(), | |||
} | |||
end, | |||
}, | |||
["Term"] = links("Term"), | |||
["Terms"] = links("Terms"), | |||
["TermList"] = links("TermList"), | |||
["Transcript"] = { | |||
formatter = 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 = { | attributeTags = { | ||
["ID"] = function(cell, tableArgs, tagArgs) | ["ID"] = { | ||
formatter = function(cell, tableArgs, tagArgs) | |||
local id = string.gsub(cell.raw, "%[Player Name%]", "Link") | |||
["Nowrap"] = function(cell, tableArgs, tagArgs) | id = utilsMarkup.separateMarkup(id) | ||
cell.id = id | |||
cell.content:addClass("data-table__cell-content--id") | |||
["Rowspan"] = function(cell, tableArgs, tagArgs) | end, | ||
}, | |||
["Nowrap"] = { | |||
["Unsortable"] = function(cell, tableArgs, tagArgs) | formatter = function(cell, tableArgs, tagArgs) | ||
cell.content:addClass("data-table__cell-content--nowrap") | |||
end, | |||
["Width"] = function(cell, tableArgs, tagArgs) | }, | ||
["Rowspan"] = { | |||
formatter = function(cell, tableArgs, tagArgs) | |||
computeRowspan(cell) | |||
end, | |||
}, | |||
["Unsortable"] = { | |||
formatter = function(cell, tableArgs, tagArgs) | |||
cell.sortValue = false | |||
end, | |||
}, | |||
["Width"] = { | |||
noCopy = true, | |||
formatter = function(cell, tableArgs, tagArgs) | |||
cell.styles = cell.styles or {} | |||
cell.styles["width"] = tagArgs[1] | |||
end, | |||
}, | |||
} | } | ||
} | } | ||
return p | return p |