Jump to content

Module:Vertical header/sandbox: Difference between revisions

From Wikipedia, the free encyclopedia
Content deleted Content added
refactor the attribute-getting code and the result-formatting code into separate functions
use "cell" instead of "th", because 1) template header cells are technically cells, 2) the existing parameter name is "cellstyles", and 3) it is possible (though unwise) to use the template in a non-header cell
Line 14: Line 14:


local function getAttributeData(options)
local function getAttributeData(options)
local thClasses = {"vertical-header", "nowrap"}
local cellClasses = {"vertical-header", "nowrap"}
local thStyles = {}
local cellStyles = {}
local divClasses = {}
local divClasses = {}
local divStyles = {}
local divStyles = {}


if options.sortPadding then
if options.sortPadding then
table.insert(thClasses, "vertical-header-sortable")
table.insert(cellClasses, "vertical-header-sortable")
else
else
table.insert(thClasses, "unsortable")
table.insert(cellClasses, "unsortable")
end
end
if options.vertAlign == "top" then
if options.vertAlign == "top" then
table.insert(thClasses, "vertical-header-align-top")
table.insert(cellClasses, "vertical-header-align-top")
elseif options.vertAlign == "middle" then
elseif options.vertAlign == "middle" then
table.insert(thClasses, "vertical-header-align-middle")
table.insert(cellClasses, "vertical-header-align-middle")
end
end


if options.manualWidth then
if options.manualWidth then
table.insert(thStyles, "width:" .. options.manualWidth)
table.insert(cellStyles, "width:" .. options.manualWidth)
else
else
local rowCount = getRowCount(options.text)
local rowCount = getRowCount(options.text)
Line 49: Line 49:
end
end
table.insert(thStyles, options.extraThStyles)
table.insert(cellStyles, options.extraCellStyles)
table.insert(divStyles, options.extraDivStyles)
table.insert(divStyles, options.extraDivStyles)


return thClasses, thStyles, divClasses, divStyles
return cellClasses, cellStyles, divClasses, divStyles
end
end


Line 67: Line 67:
end
end


local function formatOutput(text, thClasses, thStyles, divClasses, divStyles)
local function formatOutput(text, cellClasses, cellStyles, divClasses, divStyles)
thAttributes = {}
thAttributes = {}
table.insert(thAttributes, formatAttribute{attrName = "class", attrs = thClasses, separator = " "})
table.insert(thAttributes, formatAttribute{attrName = "class", attrs = cellClasses, separator = " "})
table.insert(thAttributes, formatAttribute{attrName = "style", attrs = thStyles})
table.insert(thAttributes, formatAttribute{attrName = "style", attrs = cellStyles})
local div = mw.html.create("div")
local div = mw.html.create("div")
Line 86: Line 86:
function p._cell(args)
function p._cell(args)
local text = args[1]
local text = args[1]
local thClasses, thStyles, divClasses, divStyles = getAttributeData{
local cellClasses, cellStyles, divClasses, divStyles = getAttributeData{
text = text,
text = text,
sortPadding = args.stp,
sortPadding = args.stp,
Line 92: Line 92:
manualWidth = args.mw,
manualWidth = args.mw,
noBold = args.nb,
noBold = args.nb,
extraThStyles = escapeQuotes(args.cellstyle),
extraCellStyles = escapeQuotes(args.cellstyle),
extraDivStyles = escapeQuotes(args.style)
extraDivStyles = escapeQuotes(args.style)
}
}
return formatOutput(text, thClasses, thStyles, divClasses, divStyles)
return formatOutput(text, cellClasses, cellStyles, divClasses, divStyles)
end
end



Revision as of 07:32, 2 August 2020

local p = {}

local function escapeQuotes(text)
	if not text then
		return nil
	end
	return text:gsub("\"", """)
end

local function getRowCount(text)
	local _, count = text:gsub("<[bB][rR] */? *>", "%0")
	return count + 1
end

local function getAttributeData(options)
	local cellClasses = {"vertical-header", "nowrap"}
	local cellStyles = {}
	local divClasses = {}
	local divStyles = {}

	if options.sortPadding then
		table.insert(cellClasses, "vertical-header-sortable")
	else
		table.insert(cellClasses, "unsortable")
	end
	
	if options.vertAlign == "top" then
		table.insert(cellClasses, "vertical-header-align-top")
	elseif options.vertAlign == "middle" then
		table.insert(cellClasses, "vertical-header-align-middle")
	end

	if options.manualWidth then
		table.insert(cellStyles, "width:" .. options.manualWidth)
	else
		local rowCount = getRowCount(options.text)
		-- The styles for 1 row are in the default vertical-header class. For
		-- 2, 3, or 4 rows, we add special classes to get the correct width.
		-- In the rare event that there are more than 4 rows, use inline styles.
		if rowCount >= 2 and rowCount <= 4 then
			table.insert(tableClasses, string.format("vertical-header-%drows", rowCount))
		elseif rowCount > 4 then
			table.insert(tableStyles, string.format("width:%.3fem", rowCount * 0.875))
		end
	end
	
	if options.noBold then
		table.insert(divClasses, "vertical-header-nobold")
	end
	
	table.insert(cellStyles, options.extraCellStyles)
	table.insert(divStyles, options.extraDivStyles)

	return cellClasses, cellStyles, divClasses, divStyles
end

local function formatAttribute(options)
	if #options.attrs == 0 then
		return nil
	end
	local separator = options.separator or ""
	return string.format(
		'%s="%s"',
		options.attrName,
		table.concat(options.attrs, separator)
	)
end

local function formatOutput(text, cellClasses, cellStyles, divClasses, divStyles)
	thAttributes = {}
	table.insert(thAttributes, formatAttribute{attrName = "class", attrs = cellClasses, separator = " "})
	table.insert(thAttributes, formatAttribute{attrName = "style", attrs = cellStyles})
	
	local div = mw.html.create("div")
	for _, class in ipairs(divClasses) do
		div:addClass(class)
	end
	for _, cssText in ipairs(divStyles) do
		div:cssText(cssText)
	end
	div:wikitext(text)

	return string.format("%s | %s", table.concat(thAttributes, " "), tostring(div))
end

function p._cell(args)
	local text = args[1]
	local cellClasses, cellStyles, divClasses, divStyles = getAttributeData{
		text = text,
		sortPadding = args.stp,
		vertAlign = args.va,
		manualWidth = args.mw,
		noBold = args.nb,
		extraCellStyles = escapeQuotes(args.cellstyle),
		extraDivStyles = escapeQuotes(args.style)
	}
	return formatOutput(text, cellClasses, cellStyles, divClasses, divStyles)
end

function p.cell(frame)
	local args = require("Module:Arguments").getArgs(frame, {
		wrapper="Template:Vertical header"
	})
	return p._cell(args)
end

return p