Module:PortalDYK

From Uncyclopedia, the content-free encyclopedia
Jump to navigation Jump to search

local p = {}

-- Trim whitespace from start and end of string
local function trim(s)
    if not s then return nil end
    return s:match("^%s*(.-)%s*$")
end

-- Fisher–Yates shuffle
local function shuffle(t)
    local n = #t
    for i = n, 2, -1 do
        local j = math.random(i)
        t[i], t[j] = t[j], t[i]
    end
end

-- Remove HTML comments <!-- ... --> including multi-line
local function removeComments(s)
    if not s then return "" end
    return s:gsub("<!--.-?-->", "")
end

-- Extract all bulleted items from wikitext, grouping sub-bullets with their parent
local function extractBullets(wikitext)
    local items = {}
    local text = removeComments(wikitext)
    for line in text:gmatch("[^\r\n]+") do
        if line:match("^%s*%*") then
            if line:match("^%s*%*%*") then
                -- Sub-bullet: append to the last top-level item
                local sub = trim(line:match("^%s*%*+%s*(.+)$"))
                if sub and sub ~= "" and #items > 0 then
                    items[#items] = items[#items] .. "\n" .. line
                end
            else
                -- Top-level bullet
                local bullet = trim(line:match("^%s*%*%s*(.+)$"))
                if bullet and bullet ~= "" then
                    table.insert(items, line)
                end
            end
        end
    end
    return items
end

-- Main function called from a template
function p.main(frame)
    local args = frame:getParent().args

    -- First argument: page name
    local pageName = trim(args[1] or args.page)
    -- Second argument: count of items to return, defaults to 4
    local count = tonumber(args[2] or args.count) or 4

    if not pageName or not count or count < 1 then
        return ""
    end

    -- Load the page
    local title = mw.title.new(pageName)
    if not title or not title.exists then
        return '<span class="error">Error: Page "' .. pageName .. '" does not exist.</span>'
    end

    local content = title:getContent()
    if not content then
        return '<span class="error">Error: Page "' .. pageName .. '" has no content.</span>'
    end

    -- Extract bullets
    local items = extractBullets(content)
    if #items == 0 then
        return '<span class="error">Error: No list items could be retrieved from "' .. pageName .. '".</span>'
    end

    -- Seed random for better shuffling
    math.randomseed(os.time() + (os.clock() * 1000000))
    shuffle(items)

    -- Limit count to total number of items to prevent duplicates
    local limit = math.min(count, #items)
    local output = {}
    for i = 1, limit do
        table.insert(output, items[i])
    end

    return frame:preprocess(table.concat(output, "\n"))
end

return p