Module:UtilsMarkup/List

local p = {}

local utilsTable = require("Module:UtilsTable")

local function tag(tag, content, attributes) if not tag then return content end local html = mw.html.create(tag) :attr(attributes or {}) :wikitext(mw.getCurrentFrame:preprocess(content)) return tostring(html) end

local function tagList(listTag, itemTag, listAttributes, level) level = level or 1 return function(items) listAttributes = utilsTable.merge(listAttributes or {}, { -- backwards compatibility for a previous API			start = items.start 		}) if #items == 0 then return "" end local list = "" for _, item in ipairs(items) do			if utilsTable.isArray(item) then list = list .. tagList(listTag, itemTag, listAttributes, level + 1)(item) else list = list .. tag(itemTag, item) end end return tag(listTag, list, listAttributes) end end

function p.list(items) return tagList("ul", "li", {		class = "plainlist"	})(items) end

function p.bulletList(items, attributes) return tagList("ul", "li", attributes)(items) end

function p.numberList(items, attributes) return tagList("ol", "li", attributes)(items) end

function p.definitionList(items, attributes, level) level = level or 1 local listItems = {} for _, definitions in ipairs(items) do		local dt = definitions[1] if dt then table.insert(listItems, tag("dt", dt or "")) end for i = 2, table.maxn(definitions) do			local dd = definitions[i] if type(dd) == "table" then dd = p.definitionList(dd, attributes, level + 1) end table.insert(listItems, tag("dd", dd or "")) end end local list = tagList("dl", nil, attributes, level)(listItems) return list end

function p.Schemas local listItems = { type = "array", required = true, items = { type = "string" }, desc = "An array of strings (list items).", }	local attributes = { type = "record", properties = { {				name = "class", type = "string", desc = "Sets the  attribute of HTML list tag. Note that this is recursively applied to sub-lists.", },		},	}	return { list = { items = listItems, },		bulletList = { items = listItems, attributes = attributes, },		numberList = { items = listItems, attributes = { type = "record", properties = utilsTable.concat(attributes.properties, {					{						name = "start",						type = "number",						desc = "Sets the starting value.",					},				}), },		},		definitionList = { pairs = { type = "array", required = true, items = { type = "any" }, -- TODO desc = "Array of  of pairs where the first pair item is a term and the value is a definition.", },			attributes = attributes, }	} end

function p.Documentation return { list = { params = {"items"}, returns = "An unordered list with the  class.", cases = { {					args = { {} }, expect = "", },				{					args = { { "single item" } },					expect = ' single item', },				{					args = { { "multiple", "items", "" }, },					expect = ' multipleitems' },			},		},		bulletList = { params = {"items", "attributes"}, returns = "A string representation of an unordered list using HTML syntax.", cases = { {					args = { {} }, expect = "", },				{					args = { { "single item" }, },					expect = "single item", },				{					args = { { "multiple", "items", "" }, },					expect = "multiple</li>items</li></li></ul>", },				{					args = { {							"list", {								"with", {"nested", "items"}, "inside" },						},						{ class = "custom-class" }, },					expect = '<ul class="custom-class">list</li><ul class="custom-class">with</li><ul class="custom-class">nested</li>items</li></ul>inside</li></ul></ul>' },			}		},		numberList = { params = {"items", "attributes"}, returns = "A string representation of an ordered list using HTML syntax.", cases = { {					args = { {} }, expect = "", },				{					args = { { "single item" } },					expect = "<ol>single item</li></ol>", },				{					args = { { "multiple", "items", "" }, },					expect = "<ol>multiple</li>items</li></li></ol>" },				{					args = { {							"list", {								"with", {"nested", "items"}, "inside" },						},					},					expect = "<ol>list</li><ol>with</li><ol>nested</li>items</li></ol>inside</li></ol></ol>" },				{					args = { {							"Eight", "Nine", "Ten" },						{ class = "custom-class", start = 8 }, },					expect = '<ol start="8" class="custom-class"><li>Eight</li><li>Nine</li><li>Ten</li></ol>', },			}		},		definitionList = { params = {"pairs", "attributes"}, returns = "A string representation of a definition list using HTML syntax.", cases = { resultOnly = true, {					args = { {} }, expect = "", },				{					args = { {							{ "key1", "value1" }, }					},					expect = "<dl><dt>key1</dt><dd>value1</dd></dl>", },				{					args = { {							{ "key1", "value1" }, { "key2", "value2" }, }					},					expect = "<dl><dt>key1</dt><dd>value1</dd><dt>key2</dt><dd>value2</dd></dl>", },				{					args = { {							{ "", "value1" }, { nil, "value2" }, { "key3", "" }, { "key4", nil }, },					},					expect = "<dl><dt></dt><dd>value1</dd><dd>value2</dd><dt>key3</dt><dd></dd><dt>key4</dt></dl>" },				{					args = { {							{ "key 1", { {"key 1.1", { { "key 1.1.1", "value 1.1.1" }, }},								{"key 1.2", "value 1.2" }, }},							{ "key2", "value2" }, }					},					expect = "<dl><dt>key 1</dt><dd><dl><dt>key 1.1</dt><dd><dl><dt>key 1.1.1</dt><dd>value 1.1.1</dd></dl></dd><dt>key 1.2</dt><dd>value 1.2</dd></dl></dd><dt>key2</dt><dd>value2</dd></dl>" },				{					args = { {							{ "key 1", "value 1.1", { {"key 1.1", "value 1.2"}, { "key 1.2", "value 1.2"}, }},						},						{ class = "custom-class" }, },					expect = '<dl class="custom-class"><dt>key 1</dt><dd>value 1.1</dd><dd><dl class="custom-class"><dt>key 1.1</dt><dd>value 1.2</dd><dt>key 1.2</dt><dd>value 1.2</dd></dl></dd></dl>' },			},		},	} end return p