Module:Tabular data

local p = {} local lang = mw.getContentLanguage local navbar = require("Module:Navbar")

local messages = { ["true"] = "Yes", ["false"] = "No", null = "N/A", }

local bgColors = { ["true"] = "#9f9", ["false"] = "#f99", null = "#ececec", }

local colors = { null = "#2c2c2c", }

--- Returns the value of the cell at the given row index and column name. --- A row index of 1 refers to the first row in the table. A row index of -1 --- refers to the last row in the table. It is an error to specify a row index --- of 0. --- Usage: function p.cell(frame) local data = mw.ext.data.get(frame.args[1]) local rowIdx = tonumber(frame.args.output_row) local outputColumnName = frame.args.output_column local outputColumnIdx for i, field in ipairs(data.schema.fields) do		if field.name == outputColumnName then outputColumnIdx = i			break end end assert(outputColumnIdx, mw.ustring.format("Output column “%s” not found.", outputColumnName)) if rowIdx > 0 then rowIdx = (rowIdx - 1) % #data.data + 1 elseif rowIdx < 0 then rowIdx = rowIdx % #data.data + 1 else error("0 is not a valid row index.") end return data.data[rowIdx][outputColumnIdx] end

--- Returns the value of the cell in the given output column of the row matching --- the search key and column. --- Reminiscent of LOOKUP macros in popular spreadsheet applications, except --- that the search key must match exactly. (On the other hand, this means the --- table does not need to be sorted.) --- Usage: function p.lookup(frame) local data = mw.ext.data.get(frame.args[1]) local searchValue = frame.args.search_value local searchColumnName = frame.args.search_column local outputColumnName = frame.args.output_column local searchColumnIdx local outputColumnIdx for i, field in ipairs(data.schema.fields) do		if field.name == searchColumnName then searchColumnIdx = i		end if field.name == outputColumnName then outputColumnIdx = i		end if searchColumnIdx and outputColumnIdx then break end end assert(searchColumnIdx, mw.ustring.format("Search column “%s” not found.", searchColumnName)) assert(outputColumnIdx, mw.ustring.format("Output column “%s” not found.", outputColumnName)) for i, record in ipairs(data.data) do		if record[searchColumnIdx] == searchValue then return record[outputColumnIdx] end end end

--- Returns a tabular data page as a wikitext table. --- Usage: function p.wikitable(frame) local pageName = frame.args[1] local data = mw.ext.data.get(pageName) local datatypes = {} local htmlTable = mw.html.create("table") :addClass("wikitable sortable") htmlTable :tag("caption") :wikitext(navbar.navbar({ template = ":c:Data:" .. pageName, mini = "y", style = "float: right;", "view", "edit", }))		:wikitext(data.description) local headerRow = htmlTable :tag("tr") for i, field in ipairs(data.schema.fields) do		headerRow :tag("th") :attr("scope", "col") :attr("data-sort-type", datatypes[j] == "text" and "string" or datatypes[j]) :wikitext(field.title) datatypes[i] = field.type end for i, record in ipairs(data.data) do		local row = htmlTable:tag("tr") for j = 1, #data.schema.fields do			local cell = row:tag("td") if record[j] then local formattedData = record[j] if datatypes[j] == "number" then formattedData = lang:formatNum(formattedData) cell:attr("align", "right") elseif datatypes[j] == "boolean" then cell :addClass(record[j] and "table-yes" or "table-no") :css({							background = record[j] and bgColors["true"] or bgColors["false"],							color = record[j] and colors["true"] or colors["false"],							["vertical-align"] = "middle",							["text-align"] = "center",						}) :wikitext(record[j] and messages["true"] or messages["false"]) end cell:wikitext(formattedData) else cell :addClass("mw-tabular-value-null") :addClass("table-na") :css({						background = bgColors.null,						color = colors.null,						["vertical-align"] = "middle",						["text-align"] = "center",					}) :wikitext(messages.null) end end end local footer = htmlTable :tag("tr") :tag("td") :addClass("sortbottom") :attr("colspan", #data.schema.fields) footer:wikitext(data.sources) footer:tag("br") local licenseText = mw.message.new("Jsonconfig-license",		mw.ustring.format("[%s %s]", data.license.url, data.license.text)) footer :tag("i") :wikitext(tostring(licenseText)) return htmlTable end

return p