模組:AutoStat

維基詞典,自由的多語言詞典

用於實現{{autoStat}}。使用說明詳見模板頁。


local p = {}

local m_languages = require("Module:languages")

-- remove space, make sure #args is correct
local function trimAndConvertArgs(args)
    local newArgs = {}
    for k, v in pairs(args) do
        if k >= 7 then
            newArgs[k] = tonumber(mw.text.trim(tostring(v))) or v
        else
            newArgs[k] = mw.text.trim(tostring(v))
        end
    end
    return newArgs
end

local function fn(num)
	return mw.language.new('zh'):formatNum(num)
end

local function fn2(num)
	local sign = num >= 0 and "+" or ""
    return sign .. mw.language.new('zh'):formatNum(num)
end

local function cn(num) -- colorNum
    local color = num > 0 and "green" or num < 0 and "red" or "black"
    local newNum = num >= 0 and '↑' .. fn(num) or '↓' .. fn(num * (-1))
    return string.format('<span style="color:%s;">%s</span>', color, newNum)
end

local function cn2(num)
    local color = num < 0 and "green" or num > 0 and "red" or "black"
    local newNum = num >= 0 and '↑' .. fn(num) or '↓' .. fn(num * (-1))
    return string.format('<span style="color:%s;">%s</span>', color, newNum)
end

local function calculateDate(baseDate, n)
    local year, month, day = baseDate:match("(%d+)-(%d+)-(%d+)")
    year, month, day = tonumber(year), tonumber(month), tonumber(day)
    local timestamp = os.time({year = year, month = month, day = day})
    local newTimestamp = timestamp + n * 86400  -- 86400 s = 1 day
    local newDate = os.date("%Y-%m-%d", newTimestamp)
    return newDate
end

local function isNumeric(s)
    return s:match('^%d+$') ~= nil
end

function p.main(frame)
    local args = frame:getParent().args
    args = trimAndConvertArgs(args)
    local baseDate = args[1]
    local codes, names = {}, {}
	
    for i = 2, 6 do
        if args[i] ~= nil and args[i] ~= "" then
            local lang = m_languages.getByCode(args[i])
            table.insert(codes, args[i])
            table.insert(names, lang and lang:getCanonicalName() or "")
	        if #codes == 5 then
	            break
	        end
        end
    end
    
    local head = '{| class="wikitable sortable"\n|-\n! 日期'
    names[3] = '中文'
	for i, code in ipairs(codes) do
	    if i < 5 then
	        head = head .. string.format(" !! colspan=\"2\" | [[:%s:Special:Statistics|%s版]] !! colspan=\"2\" | 差距", code, names[i])
	    else
	        head = head .. string.format(" !! colspan=\"2\" | [[:%s:Special:Statistics|%s版]]\n", code, names[i])
	    end
	end
	local val = head
	local tail = ''
	
    for i = 7, #args-5, 5 do
    	if #args % 5 == 2 and i == #args-5 then -- empty tail
    		tail = tail .. '|-style="text-align: center;"\n! 趨勢'
			for j = 0, 8 do
			    if j < 8 then
			        tail = tail .. ' !! colspan=\"2\" | &nbsp;'
			    else
			        tail = tail .. ' !! colspan=\"2\" | &nbsp;\n'
			    end
			end
			break
		elseif #args % 5 == 0 and i == #args - 13 then -- tail with text
    		tail = tail .. '|-style="text-align: center;"\n! 趨勢'
			for j = 0, 8 do
			    if j < 8 then
			        tail = tail .. string.format(' !! colspan=\"2\" | %s', args[i+j+5])
			    else
			        tail = tail .. string.format(' !! colspan=\"2\" | %s\n', args[i+j+5])
			    end
			end
			break
    	end
    	
    	local idx = (i-2) / 5 - 1 -- start from 0
    	local o1, o2, o3, o4, o5, n1, n2, n3, n4, n5 = args[i], args[i+1], args[i+2], args[i+3], args[i+4], args[i+5], args[i+6], args[i+7], args[i+8], args[i+9] 
        local line = [=[|-style="text-align: right;"
! scope="row" | %s
| style="background-color:#F9F9EF; border-right: none;" | %s
| style="background-color:#F9F9EF; font-size: smaller; border-left: none;" | %s
| style="border-right: none;" | %s
| style="font-size: smaller; border-left: none;" | %s
| style="background-color:#F9F9EF; border-right: none;" | %s
| style="background-color:#F9F9EF; font-size: smaller; border-left: none;" | %s
| style="border-right: none;" | %s
| style="font-size: smaller; border-left: none;" | %s
| style="background-color:#F0F0FF; border-right: none;" | %s
| style="background-color:#F0F0FF; font-size: smaller; border-left: none;" | %s
| style="border-right: none;" | %s
| style="font-size: smaller; border-left: none;" | %s
| style="background-color:#F9F9EF; border-right: none;" | %s
| style="background-color:#F9F9EF; font-size: smaller; border-left: none;" | %s
| style="border-right: none;" | %s
| style="font-size: smaller; border-left: none;" | %s
| style="background-color:#F9F9EF; border-right: none;" | %s
| style="background-color:#F9F9EF; font-size: smaller; border-left: none;" | %s
]=]

		val = val .. string.format(line, calculateDate(baseDate, idx),
			fn(n1), fn2(n1 - o1), fn(n1 - n3), cn2((n1 - n3) - (o1 - o3)), 
			fn(n2), fn2(n2 - o2), fn(n2 - n3), cn2((n2 - n3) - (o2 - o3)), 
			fn(n3), fn2(n3 - o3), fn(n3 - n4), cn((n3 - n4) - (o3 - o4)), 
			fn(n4), fn2(n4 - o4), fn(n3 - n5), cn((n3 - n5) - (o3 - o5)), 
			fn(n5), fn2(n5 - o5))
    end
    val = val .. tail
    val = val .. '|}'
    return val
end

return p