Module:Data Table/Tags: Difference between revisions
Jump to navigation
Jump to search
(Testing something) Tag: Reverted |
PhantomCaleb (talk | contribs) No edit summary |
||
(9 intermediate revisions by 2 users not shown) | |||
Line 39: | Line 39: | ||
local format = tagArgs[2] | local format = tagArgs[2] | ||
local cellSize = 0 | local cellSize = 0 | ||
local sortValue | local sortValue | ||
values = | local text | ||
local value, info = utilsMarkup.separateMarkup( | if #values == 1 then | ||
local value, info = utilsMarkup.separateMarkup(values[1]) | |||
sortValue = value:gsub(",", "") | |||
if value == "" then | |||
text = info | |||
end | end | ||
cellSize = math.max(cellSize, value:len()) | end | ||
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 | |||
return { | return { | ||
text = | text = text, | ||
size = cell:len(), | size = cell:len(), | ||
sortValue = sortValue | sortValue = sortValue | ||
Line 66: | Line 77: | ||
end | end | ||
local function | local function links(tagName) | ||
return { | return { | ||
formatter = function(cell, tableArgs, tagArgs) | formatter = function(cell, tableArgs, tagArgs) | ||
Line 80: | Line 91: | ||
local entries = utilsTable.map(pages, function(page) | local entries = utilsTable.map(pages, function(page) | ||
return GalleryList. | -- We use GalleryList here because we have to be aware of any GalleryList syntax that could be present in the cell, | ||
plural = | -- which may be the case if the [Image] tag is also applied to the column | ||
link = true | return GalleryList.parseEntry(page, game, "", { | ||
plural = tagName == "Plural" or tagName == "PluralList", | |||
link = true, | |||
useTerms = tagName ~= "LinkList", | |||
}) | }) | ||
end) | end) | ||
Line 92: | Line 106: | ||
end | end | ||
local isBulletList = tagName == "TermList" or tagName == "PluralList" | local isBulletList = tagName == "TermList" or tagName == "PluralList" or tagName == "LinkList" | ||
local links = utilsTable.map(entries, | local links = utilsTable.map(entries, function(entry) | ||
local | 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 | local sortValue | ||
Line 101: | Line 123: | ||
end | end | ||
return { | return { | ||
text = | text = text, | ||
sortValue = sortValue, | sortValue = sortValue, | ||
size = cellSize | size = cellSize | ||
Line 118: | Line 140: | ||
local spanningCell = spanningCellsByColumn[columnIndex] | local spanningCell = spanningCellsByColumn[columnIndex] | ||
local spanCount = spanCountsByColumn[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 172: | Line 195: | ||
formatter = function(cell) -- special case: empty cell | formatter = function(cell) -- special case: empty cell | ||
return { | return { | ||
text = "", | text = " ", | ||
sortValue = "", | sortValue = "", | ||
size = 0, | size = 0, | ||
Line 203: | Line 226: | ||
local subject, info = utilsMarkup.separateMarkup(item) | local subject, info = utilsMarkup.separateMarkup(item) | ||
cellSize = math.max(cellSize, subject:len()) | cellSize = math.max(cellSize, subject:len()) | ||
if #amounts == 1 and subject == "" then | |||
text = info | |||
end | |||
end | end | ||
Line 269: | Line 295: | ||
cell = string.gsub(cell, "%[Player Name%]", "Link") | cell = string.gsub(cell, "%[Player Name%]", "Link") | ||
local fileType = tagArgs[1] or Franchise.graphics(tableArgs.game) == "2D" and "Sprite" or "Icon" | local fileType = tagArgs[1] or Franchise.graphics(tableArgs.game) == "2D" and "Sprite" or "Icon" | ||
local entry = GalleryList. | local entry = GalleryList.parseEntry(cell, tableArgs.game, fileType, { | ||
useTerms = false, | useTerms = false, | ||
}) | }) | ||
Line 283: | Line 309: | ||
end, | 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"] = { | ["List"] = { | ||
formatter = function(cell, tableArgs, tagArgs) | formatter = function(cell, tableArgs, tagArgs) | ||
Line 301: | Line 351: | ||
formatter = function(cell, tableArgs, tagArgs) | formatter = function(cell, tableArgs, tagArgs) | ||
local cellSize = cell:len() | local cellSize = cell:len() | ||
local text = string.gsub(cell, "%[Player Name%]", | -- We use GalleryList here because we have to be aware of any GalleryList syntax that could be present in the cell, | ||
local text = | -- 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, "", "", { | |||
useTerms = false | |||
}) | |||
local text = string.gsub(entry.subject, "{Player Name}", playerName())..entry.info | |||
return { | return { | ||
text = text, | text = text, | ||
sortValue = text, | |||
} | } | ||
end, | end, | ||
}, | }, | ||
["Plural"] = | ["Plural"] = links("Plural"), | ||
["PluralList"] = | ["PluralList"] = links("PluralList"), | ||
["Rupees"] = value("Rupee", true), | ["Rupees"] = value("Rupee", true), | ||
["SortValue"] = { | ["SortValue"] = { | ||
Line 340: | Line 397: | ||
end, | end, | ||
}, | }, | ||
["Term"] = | ["Term"] = links("Term"), | ||
["Terms"] = | ["Terms"] = links("Terms"), | ||
["TermList"] = | ["TermList"] = links("TermList"), | ||
["Transcript"] = { | ["Transcript"] = { | ||
formatter = function(cell, tableArgs, tagArgs) | formatter = function(cell, tableArgs, tagArgs) | ||
Line 358: | Line 415: | ||
["ID"] = { | ["ID"] = { | ||
formatter = function(cell, tableArgs, tagArgs) | formatter = function(cell, tableArgs, tagArgs) | ||
local id = string.gsub(cell.raw, "%[Player Name%]", "Link") | |||
id = utilsMarkup.separateMarkup(id) | |||
cell.id = id | |||
cell.content:addClass("data-table__cell-content--id") | |||
end, | end, | ||
}, | }, |
Latest revision as of 12:42, 6 November 2023
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 {
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 sortValue
local text
if #values == 1 then
local value, info = utilsMarkup.separateMarkup(values[1])
sortValue = value:gsub(",", "")
if value == "" then
text = info
end
end
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
return {
text = text,
size = cell:len(),
sortValue = sortValue
}
end
}
end
local function links(tagName)
return {
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
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]
local na = string.find(tostring(cell.content), "Not Applicable")
if not spanningCell then
spanningCell = cell
spanCount = 1
elseif tostring(cell.content) == tostring(spanningCell.content) and not na 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
-- 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
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
-- noCopy (optional): if set to true, the tag will not be automatically carried over to copies of the table
contentTags = {
[""] = {
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,]*)")
if leadingNumber then
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 = "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),
["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, "", "", {
useTerms = false
})
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),
["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,
},
["SyntaxHighlight"] = {
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 = {
["ID"] = {
formatter = function(cell, tableArgs, tagArgs)
local id = string.gsub(cell.raw, "%[Player Name%]", "Link")
id = utilsMarkup.separateMarkup(id)
cell.id = id
cell.content:addClass("data-table__cell-content--id")
end,
},
["Nowrap"] = {
formatter = function(cell, tableArgs, tagArgs)
cell.content:addClass("data-table__cell-content--nowrap")
end,
},
["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