Jump to content

Module:Vertical header/sandbox

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Mr. Stradivarius (talk | contribs) at 07:32, 2 August 2020 (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). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
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