پودمان:AutomaticTOC

از ویکی‌پدیا، دانشنامهٔ آزاد
توضیحات پودمان[ایجاد] [پاکسازی]
z = {};

-- main function
function z.main(frame)
    local args = frame.args
    local title = handle_param(args.title, nil)
    title = title and mw.title.new(args.title) or mw.title.getCurrentTitle()
    local delim = handle_param(args.delim, ",")
    local sep = handle_param(args.sep, " ")
    local short = handle_param(args.short, nil)
    local name = handle_param(args.name, '')
    name = (name == '') and '' or "'''" .. name .. "'''"
    name = "|" .. (short and name or "<center>" .. name .. "</center>\n|-") .. "\n|"
    
    local include = args.include and Set(Split(args.include, "%" .. delim)) or {}
    local exclude = args.exclude and Set(Split(args.exclude, "%" .. delim)) or {}
    
    local pre = args.pre and Split(args.pre, "%" .. delim) or {}
    local prebreak = handle_param(args.prebreak, sep)
    
    local post = args.post and Split(args.post, "%" .. delim) or {}
    local postbreak = handle_param(args.postbreak, sep)
    
    local prefix = handle_param(args.prefix, "")
    local suffix = handle_param(args.suffix, "")
    
    local anchor = handle_param(args.anchor, nil)
    local wiki_text = title:getContent()
    local all = {}
    
    local level = handle_param(tonumber(args.level), 1)
    
    eval = function(v)
        v = v:match "^%s*(.-)%s*$"
        if v ~= "" then
            if (mw.ustring.len(v) <= level or include[v]) then table.insert(all, v) end
        end
    end
    
    for line in wiki_text:gmatch("[^\n]+") do
        ---
        eval(string.gsub(line:match("^=+%s*(.-)%s*=+%s-$") or "", "%b{}", ""))
        if anchor then
            for _, v in pairs(Split(line:match("%{%{[Aa]nchor%|(.-)%}%}") or "", "%|")) do eval(v) end
        end
        ---
    end
    
    table.sort(all, function(a, b) return mw.ustring.codepoint(a) < mw.ustring.codepoint(b) end)
    
    complete_list = {}
    for k, v in pairs(all) do
        if not exclude[v] and (k == 0 or (k > 0 and all[k - 1] ~= v)) then
            table.insert(complete_list, table.concat{"[[#", v, "|", prefix, v, suffix, "]]"})
        end
    end

    if #complete_list == 0 then
        return errorPrinter({{"", "no section link found[[Category:Page transcluded AutomaticTOC without section link]]"}})
    end
    if #pre == 0 then prebreak = "" end
    if #post == 0 then postbreak = "" end
    
    out = '{| class="toccolours" style="margin: 0px auto;"\n' .. name ..
          table.concat(pre, sep) .. prebreak .. table.concat(complete_list, sep) .. postbreak ..
          table.concat(post, sep) .. ' __NOTOC__\n|}'
          
    if args.db then out = '<pre>' .. out .. '</pre>' end
    return frame:preprocess(out)
end

-- handle parameter
function handle_param(value, default)
    if (value == nil or value == "¬") then
        return default
    else
        return value
    end
end

-- from Module:Coordinates
function errorPrinter(errors)
    local result = ""
    for i,v in ipairs(errors) do
        local errorHTML = '<strong class="error">AutomaticTOC: ' .. v[2] .. '</strong>'
        result = result .. errorHTML .. "<br />"
    end
    return result
end

-- http://stackoverflow.com/questions/656199/search-for-an-item-in-a-lua-list
function Set (list)
    local set = {}
    for _, l in pairs(list) do set[l] = true end
    return set
end

-- http://lua-users.org/wiki/SplitJoin
function Split(str, delim, maxNb)
    -- Eliminate bad cases...
    if string.find(str, delim) == nil then
        if str == "" then return {} else return {str} end
    end
    if maxNb == nil or maxNb < 1 then
        maxNb = 0    -- No limit
    end
    local result = {}
    local pat = "(.-)" .. delim .. "()"
    local nb = 0
    local lastPos
    for part, pos in string.gfind(str, pat) do
        nb = nb + 1
        result[nb] = part
        lastPos = pos
        if nb == maxNb then break end
    end
    -- Handle the last field
    if nb ~= maxNb then
        nb = nb + 1
        result[nb] = string.sub(str, lastPos)
    end
    if result[nb] == "" then table.remove(result, nb) end
    return result
end

return z

-- 2 May 2013:‎ Thanks to [[:en:User:Darklama]] for helping improving the code :)