Documentation for this module may be created at Module:UtilsMarkup/List/doc
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 <code>class</code> 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 <code>table</code> 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 <code>plainlist</code> class.", cases = { { args = { {} }, expect = "", }, { args = { { "single item" } }, expect = '<ul class="plainlist"><li>single item</li></ul>', }, { args = { { "multiple", "items", "" }, }, expect = '<ul class="plainlist"><li>multiple</li><li>items</li><li></li></ul>' }, }, }, bulletList = { params = {"items", "attributes"}, returns = "A string representation of an unordered list using HTML syntax.", cases = { { args = { {} }, expect = "", }, { args = { { "single item" }, }, expect = "<ul><li>single item</li></ul>", }, { args = { { "multiple", "items", "" }, }, expect = "<ul><li>multiple</li><li>items</li><li></li></ul>", }, { args = { { "list", { "with", {"nested", "items"}, "inside" }, }, { class = "custom-class" }, }, expect = '<ul class="custom-class"><li>list</li><ul class="custom-class"><li>with</li><ul class="custom-class"><li>nested</li><li>items</li></ul><li>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><li>single item</li></ol>", }, { args = { { "multiple", "items", "" }, }, expect = "<ol><li>multiple</li><li>items</li><li></li></ol>" }, { args = { { "list", { "with", {"nested", "items"}, "inside" }, }, }, expect = "<ol><li>list</li><ol><li>with</li><ol><li>nested</li><li>items</li></ol><li>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