此模块的文档可以在模块:Utility/doc创建

--<pre> This module includes useful functions
--p.getArgs(myFrame)
local p = {}
--Frame functions
function p.getFrame(bParent)
    local oFrame  = mw.getCurrentFrame()
    if bParent  and oFrame~=nil and oFrame:getParent() then 
        oFrame = mw.getCurrentFrame():getParent()
    end 
    return oFrame
end

-- Put all arguments into a real table - Returns Parent, child args table
function p.getArgs(frame)
    local tParent = frame:getParent()
    local tChild = p.fetchArgs(frame.args)
    
    if frame  and tParent then
        tParent = p.fetchArgs(tParent.args)
    end
    return tParent or tChild
end

function p.fetchArgs(tTmp)
    if not(tTmp) then 
        return 
    end
    local sName
    for sName ,_ in  pairs( tTmp ) do
        if sName then
            return tTmp
        end
    end
end

--Check if args are enough for script to run
function p.checkArgs(frame, iArgs,bParent)
    local iCount =0
    local  tParent, tChild = p.getArgs(frame)
    local tArgTable = tParent
    if not(bParent) then
        tArgTable = tChild
    end
    if not(tArgTable) then
        return
    end
    local value
    for _, value in  pairs( tArgTable ) do 
        iCount = iCount + 1
        if (iCount) == tonumber(iArgs) then  
            return true      
        end      
    end
    return false
end
-- End Frame functions

--Date functions
--Check if date is in appropriate format
function p.checkDate(date,format)
    local pat=format or "(%d%d%d%d)-(%d%d)-(%d%d)"
    if date then
        local year,month,day=date:match(pat)
        if year and month and day then 
            if (tonumber(month) < 13 and tonumber(day) < 32 and not(tonumber(year)< 0)) then
                return true
            end
        end
    end
    return false
end
-- Calculate difference between two dates
function p.datediff( date1, date2,bAllowNeg)
    if p.checkDate(date1) and p.checkDate(date2) then
        local tDate1 =p.getdate(date1)
        local tDate2 =p.getdate(date2)
        local days = ((os.difftime(tDate1,tDate2))/3600/24)
        if not(bAllowNeg) then   
            days = math.abs(days)
        end
        return days
    end
    return 0
end

--Get timestamp using custom format
function p.getTimestamp(date,format)
    if not(p.checkDate(date,format)) then 
        return  
    end
    local pat=format or "(%d%d%d%d)-(%d%d)-(%d%d)"
    local year,month,day=date:match(pat)
    local date1=(os.time({month=month,year=year,day=day}) )
    return date1
end

function p.getdate(date, format)
    return p.getTimestamp (date, format)
end

function p.addDays(sDate,iDays,bReturnTable, sFormat)
    if (iDays and tonumber(iDays)) then
        iDayToSecs = iDays  * 24 * 60 *60
        if (bReturnTable) then
            return os.date("*t",p.getdate(sDate,sFormat) + iDayToSecs)
        end
        return os.date("%Y-%m-%d",p.getdate(sDate,sFormat) + iDayToSecs)
    end
    return sDate
end

--Get time using Iso format ((YYYY-MM-DD)
function p.getfrmdate(frame)
    local currTable = p.getArgs(frame)
    if (not (currTable)) then 
        return 
    end
    date = currTable[1]
    format = currTable[2]
    if not(format) then 
        format = "%Y-%m-%d" 
    end
    local date1 = p.getdate(date,format)
    local sDate = os.date(format,date1) 
    return sDate
end

local function isLeapYear (year)
    if ((year % 4 == 0) and (year % 100 ~=  0))
    or (year % 400 == 0)
        then return true
    end
end

function p.isValidDate(year,month,day)
    local tValidDays = {31,28,31,30,31,30,31,30,31,30,31,30}
    local tValidMonths = {january=1,february=2,march=3,april=4,
        may=5,june=6,july=7,august=8,september=9,october=10,november=11,december=12}
    local bYear,bMonth,bDay
 
    month = tonumber(month) or string.lower(month)
    month = tonumber(month) or tValidMonths[month]
    mw.log(year)
    if tonumber(year) and tonumber(year)>-1 then 
        if isLeapYear(year) then
             tValidDays[2]=29
        end
        bYear = true
    end
    if tValidMonths[month] or tValidDays[month] then
        bMonth =true
        if tonumber(month) and tonumber(day) and
            0<day and tValidDays[month]>=tonumber(day) then
            bDay = true
        end
    end
    return bYear, bMonth, bDay
end


-- end date functions

-- Table functions
-- Check if table is empty
function p.isEmpty(table)
    if next(table) == nil then
        return true
    end
    return false
end

--Source: http://help.interfaceware.com/kb/112
--Saves table
function p.savetable(Table)
    local savedTables = {} -- used to record tables that have been saved, so that we do not go into an infinite recursion
    local outFuncs = {
    ['string']  = function(value) return string.format("%q",value) end;
    ['boolean'] = function(value) if (value) then return 'true' else return 'false' end end;
    ['number']  = function(value) return value end;
    }
    local outFuncsMeta = {
    __index = function(t,k) error('Invalid Type For SaveTable: '..k) end      
    }
    setmetatable(outFuncs,outFuncsMeta)
    local tableOut = function(value)
    if (savedTables[value]) then
        error('There is a cyclical reference (table value referencing another table value) in this set.');
    end
    local outValue = function(value) return outFuncs[type(value)](value) end
    local out = '{'
    for i,v in pairs(value) do out = out..'['..outValue(i)..']='..outValue(v)..';' end
        savedTables[value] = true; --record that it has already been saved
        return out..'}'
    end
    outFuncs['table'] = tableOut;
    return tableOut(Table);
end

-- Only loads level 1 tables
function p.loadtable(sTab)
    local tTable = {}
    if not(sTab) then return t end
    for sKey, value in string.gfind(sTab, "([^&=]+)=([^&=]+);") do
        local _,s,tKey = string.find(sKey,"%[(.*)%]")
        tKey = tonumber(tKey) or tKey
        tTable[tKey] = value
    end
    return tTable
end

-- prints a table with indents
function p.table_print (tt, indent, done)
    done = done or {}
    indent = indent or 0
    if type(tt) == "table" then
        local sb = {}
        for key, value in pairs (tt) do
            table.insert(sb, string.rep (" ", indent)) -- indent it
            if type (value) == "table" and not done [value] then
                done [value] = true
                table.insert(sb, '\n["'..key..'"]'.."={\n");
                table.insert(sb, p.table_print (value, indent + 2, done))
                table.insert(sb, string.rep (" ", indent)) -- indent it
                table.insert(sb, "},\n");
            elseif "number" == type(key) then
                table.insert(sb, string.format("\"%s\"\n", tostring(value)))
            else
                table.insert(sb, string.format(
                "%s = \"%s\"\n", tostring ('["'..key..'"]'), tostring(value))..",")
            end
        end
        mw.log(table.concat(sb))
        return table.concat(sb)
    else
        return tt 
    end
end

--Sorts an array
function p.spairs(t, order)
    -- collect the keys
    local keys = {}
    local iItemCount= 0;
    for k in pairs(t) do keys[#keys+1] = k; iItemCount = iItemCount + 1 end
    -- if order function given, sort by it by passing the table and keys a, b,
    -- otherwise just sort the keys 
    if order then
        table.sort(keys, function(a,b) return order(t, a, b) end)
    else
        table.sort(keys)
    end
    -- return the iterator function
    local i = 0
    return function()
        i = i + 1
        if keys[i] then
            return keys[i], t[keys[i]]
        end
    end, iItemCount
end
-- End table functions

-- Math functions
--Increments a number using iNoToIncrement
function p.incNo(iNumber, iNoToIncrement)
    if not(tonumber(iNoToIncrement)) then
        iNoToIncrement = 1;
    end
    if ( tonumber(iNumber)) then
       iNoToIncrement = iNoToIncrement 
       iNumber = iNumber + iNoToIncrement;
       return iNumber
    end
end

-- round a number
function p.round(num, idp)
    return tonumber(string.format("%." .. (idp or 0) .. "f", num))
end

--End math functions

--Debugging functions
-- Generates a traceback (lines where error originated) for a function in case of error
function p.testFunction(fFunction)
    local success, result = xpcall(fFunction,
        function(err) 
            return debug.traceback(err) 
        end)
    return success, result
end 
--end debug functions

function p.log(oData)
    local sOutput = oData
    if type(oData)=="table" then
        sOutput = "table ={\n" .. p.table_print(oData,4) .. "}"
    end
    mw.log(sOutput)
    return sOutput
end

function p.preprocess(text)
    if mw.getCurrentFrame() then
       return mw.getCurrentFrame():preprocess(text) 
    end
    
    return text
end
return p
除了特别提示,社区内容遵循CC-BY-SA授权协议。