Module:AutosortTable/sandbox explained

--create | class = wikitable | style = width: 50%; | separator = -- | order = 2, 1 | numeric = 2 | descending = 1 | hidden = 2 | rowheader = 1 | caption = Notable people by age | header = -- Name -- Age | footer = | -- Bob -- 20 | -- Peter -- 35 | -- John -- 35 | -- James -- 50 | background-color: #FFDDDD -- Henry -- 45 | colstyle = -- text-align:left; -- text-align:right; -- -- --

}}

local _module = _module.create = function(frame) local args = frame.args -- Named parameters local class = args.class local style = args.style local sep = args.separator local order = args.order local desc = args.descending or "" local nsort = args.numeric or "" local hidden = args.hidden or "" local header = args.header local footer = args.footer local colstyle = args.colstyle local rowheader = args.rowheader or "" local caption = args.caption -- Frequently-used functions local strIndexOf = mw.ustring.find local strSplit = mw.text.split local strSub = mw.ustring.sub local strTrim = mw.text.trim local seplen = #sep local nsortLookup, descLookup, hiddenLookup, rowHeading =,,, -- Create the table local html = mw.html.create local htable = html:tag('table') if class then htable:attr('class', class) end if style then htable:attr('style', style) end if caption then local hcaption = htable:tag('caption') hcaption:wikitext(caption) end

-- Parses a row string. The 'key' parameter is used to assign a unique key to the result so that equal rows do not cause sort errors. local parse = function(s, key) local css local firstSep = strIndexOf(s, sep, 1, true) if firstSep

1 then -- no CSS css = nil s = strSub(s, seplen + 1, -1) else -- CSS before first separator css = strSub(s, 1, firstSep - 1) s = strSub(s, firstSep + seplen, -1) end return end -- local writeHtml = function(css, data, _type) local row = htable:tag('tr') if css then row:attr('style', strTrim(css)) end for i, v in ipairs(data) do if not hiddenLookup[i] then local cell if _type

'header' then -- Header: use the 'th' tag with scope="col" cell = row:tag('th') cell:attr('scope', 'col') elseif _type

'footer' then -- Footer: Mark as 'sortbottom' so that it does not sort when the table is made user-sortable -- with the 'wikitable sortable' class cell = row:tag('td') cell:attr('class', 'sortbottom') else if rowHeading[i] then -- Cell is a row heading cell = row:tag('th') cell:attr('scope', 'row') else -- Ordinary cell cell = row:tag('td') end local cellCss = colstyle and colstyle[i] if cellCss then cell:attr('style', strTrim(cellCss)) end -- Apply the column styling, if necessary end cell:wikitext(strTrim(v)) end end return row end -- Parse the column styles if colstyle then colstyle = parse(colstyle, -1).data end -- Write the header first if header then local headerData = parse(header) writeHtml(headerData.css, headerData.data, 'header') end -- Parse the data local data = for i, v in ipairs(frame.args) do data[i] = parse(v, i) end order = strSplit(order, '%s*,%s*') nsort = strSplit(nsort, '%s*,%s*') desc = strSplit(desc, '%s*,%s*') hidden = strSplit(hidden, '%s*,%s*') rowheader = strSplit(rowheader, '%s*,%s*')

for i, v in ipairs(order) do order[i] = tonumber(v) end for i, v in ipairs(nsort) do nsortLookup[tonumber(v) or -1] = true end for i, v in ipairs(desc) do descLookup[tonumber(v) or -1] = true end for i, v in ipairs(hidden) do hiddenLookup[tonumber(v) or -1] = true end for i, v in ipairs(rowheader) do rowHeading[tonumber(v) or -1] = true end

--Sorting comparator function. local sortFunc = function(a, b) local ad, bd = a.data, b.data for i = 1, #order do local index = order[i] local ai, bi = ad[index], bd[index] if nsortLookup[index] then -- Numeric sort. Find the first occurrence of a number and use it. Decimal points are allowed. Scientific notation not supported. ai = tonumber((ai:find('.', 1, true) and ai:match('[+-]?%d*%.%d+') or ai:match('[+-]?%d+')) or 0) bi = tonumber((bi:find('.', 1, true) and bi:match('[+-]?%d*%.%d+') or bi:match('[+-]?%d+')) or 0) end if ai ~= bi then if descLookup[index] then return ai > bi else return ai < bi end end end return a.key < b.key end table.sort(data, sortFunc) -- Write the sorted data to the HTML output for i, v in ipairs(data) do writeHtml(v.css, v.data, nil) end -- Write the footer if footer then local footerData = parse(footer) writeHtml(footerData.css, footerData.data, 'footer') end

return tostring(html)end

return _module