Module:AutosortTable

--[[
AutosortTable: Creates a table which is automatically sorted
 
Usage: (Remove the hidden comments before use)
 
{{#invoke: AutosortTable|create
 
| class = wikitable                          <!-- Class for the entire table -->
| style = width: 50%;                        <!-- CSS for the entire table -->
| separator = --                             <!-- Separator string used to separate cells; pipe (|) invalid -->
| order = 2, 1                               <!-- Order for sorting preference, takes a comma-separated list of column numbers -->
| numeric = 2                                <!-- Columns which use numeric sorting. Takes comma-separated list of column numbers -->
| descending = 1                             <!-- Columns for which sort order should be descending. Takes comma-separated list of col numbers -->
| hidden = 2                                 <!-- Columns which are not to be displayed. Takes comma-separated list of col numbers -->
| rowheader = 1                              <!-- Cell(s) in each non-header row to be emitted as row header, per WP:ACCESS#Data tables. Usually just 1, but accepts comma-separated list of col numbers -->
| caption = Notable people by age            <!-- Table caption per WP:ACCESS -->
| header =  -- Name -- Age                   <!-- Table header -->
| footer =                                   <!-- Table footer, typically a totals row or duplication of header -->
| -- Bob -- 20                               <!-- Row 1 -->
| -- Peter -- 35                             <!-- Row 2 -->
| -- John -- 35                              <!-- Row 3 -->
| -- James -- 50                             <!-- Row 4 -->
| background-color: #FFDDDD -- Henry -- 45   <!-- Row 5, with CSS -->
| colstyle = -- text-align:left; -- text-align:right; -- -- --
											 <!-- CSS to be used on content of respective columns, here 1st & 2nd -->

}}
]]
 
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 {key = key, css = css, data = strSplit(s, sep, true)}
    end
 
    --[[
        Writes a row to the table.
        css: CSS to apply to the row
        data: The data (cells) of the row
        _type: Can be 'header', 'footer' or nil.
    ]]
    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

Content Disclaimer

Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.

  1. The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
  2. There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
  3. It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
  4. Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
  5. Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.