模組:Loop/archive
外观
local p = {}
local mError = setmetatable({}, {
__index = function (t, k)
local _mError = require('Module:Error')
mError = _mError
return _mError[k]
end
})
local mIfexist
local mTemplateParameters
local mYesno
local function inArray(item, arr)
for i, v in ipairs(arr) do
if item == v then
return v
end
end
return nil
end
local function titleExists(title, usePF)
if not mIfexist then
mIfexist = require('Module:Ifexist')
end
return mIfexist[usePF and '_parseFunctionExists' or '_luaExists'](title)
end
local function yesno(value)
if not mYesno then
mYesno = require('Module:Yesno')
end
return mYesno(value)
end
local function makeError(message)
return mError.error({ '[[Module:Loop/archive]]錯誤:' .. message })
end
local function buildLink(titleText, display, checkExists, checkExistsPF)
local success, title = pcall(mw.title.new, titleText)
if not success or not title then
return ''
end
if checkExists and not titleExists(title) then
return string.format('<!--noexist:lua--><span style="color: var(--color-disabled, #a2a9b1);">%s</span>', display)
end
if checkExistsPF then
if titleExists(title, true) then
return string.format('[[%s|%s]]', title.prefixedText, display)
else
return string.format('<!--noexist:pf--><span style="color: var(--color-disabled, #a2a9b1);">%s</span>', display)
end
end
return string.format('[[%s|%s]]', title.prefixedText, display)
end
local function formatTemplate(template, vars)
local result = ""
local i = 1
while i <= mw.ustring.len(template) do
local char = mw.ustring.sub(template, i, i)
if char == "%" then
local nextChar = mw.ustring.sub(template, i + 1, i + 1)
local nextNextChar = mw.ustring.sub(template, i + 2, i + 2)
if nextChar == "%" then
result = result .. "%"
i = i + 2
elseif vars[nextChar .. nextNextChar] then
result = result .. vars[nextChar .. nextNextChar]
i = i + 3
elseif vars[nextChar] then
result = result .. vars[nextChar]
i = i + 2
else
error("Invalid format sequence: %" .. (nextChar or ""))
end
else
result = result .. char
i = i + 1
end
end
return result
end
local function escapePrefix(prefix)
prefix = prefix:gsub('%%', '%%%%'):gsub('%/$', '')
-- omit gsub 2nd return value
return prefix
end
local currentYear = tonumber(os.date('%Y'))
local currentMonth = tonumber(os.date('%m'))
--[=[
byYear 提供的變數:
年分
%Y 對應解析器函數的 Y
]=]
function p.byYear(frame)
local args = frame.args
local prefix = args.prefix -- 存檔母頁面
local template = args.template -- 存檔頁面名模板 預設是套用 prefix/%Y年
if not template and not prefix then
return makeError('至少必須指定前綴 <code>prefix</code> 或 <code>template</code> 其中一個參數。')
end
local startYear = tonumber(args.start) -- 循環開始年分
local endYear = tonumber(args['end']) or currentYear -- 循環終止年分
local range = tonumber(args.range) or 1 -- 循環年分分組
local offset = tonumber(args.offset) or 0 -- 正常會用 2001~2005 2006~2010 此方法分組 此參數指定後對範圍進行偏移偏移
local checkExists = args.checkExists and yesno(args.checkExists) or false -- 檢查存檔目標是否存在
local checkExistsPF = not checkExists and (args.checkExistsPF and yesno(args.checkExistsPF) or true) -- 檢查存檔目標是否存在(解析器函式版)
local outputTableBox = args.outputTableBox and yesno(args.outputTableBox) or false -- 是否輸出表格的框 {| |}
local tableProps = outputTableBox and (args.tableProps ~= nil and args.tableProps or 'style="width:100%;"') -- 表格屬性組
local disableCurrentBold = args.disableCurrentBold and yesno(args.disableCurrentBold) or false -- 是否阻止對當前年分加粗
template = template or '%prefix/%Y年'
template = template:gsub('%%prefix', escapePrefix(prefix))
local output = {}
if outputTableBox then
local tableBox = '{|'
if tableProps then
tableBox = tableBox .. ' ' .. mw.text.trim(tableProps)
end
output[#output + 1] = tableBox
end
local index = math.ceil((startYear - offset) / range) - 1
while index * range + offset < endYear do
output[#output + 1] = '|-'
for i = 1, range, 1 do
local curYear = index * range + offset + i
local link = (curYear >= startYear and curYear <= endYear)
and buildLink(
formatTemplate(template, {
Y = tostring(curYear)
}),
string.format(
(curYear == currentYear and not disableCurrentBold)
and '<span style="font-weight: bold;">%4d</span>'
or '%4d',
curYear
),
checkExists,
checkExistsPF
)
or string.format('<!--%4d-->', curYear)
output[#output + 1] = '|' .. link
end
output[#output + 1] = '|style="text-align: right;"|年'
index = index + 1
end
if outputTableBox then
output[#output + 1] = '|}'
end
return table.concat(output, '\n')
end
local function getMonthGroup(month, monthInGroup)
return math.ceil(month / monthInGroup)
end
--[=[
byMonth 提供的變數:
年分
%Y 對應解析器函數的 Y
月份(monthInGroup = 1 時才有定義)
%m 對應解析器函數的 m,有補 0
%n 對應解析器函數的 n,沒補 0
該組開始月份
%Sm 對應解析器函數的 m,有補 0
%Sn 對應解析器函數的 n,沒補 0
該組結束月份
%Em 對應解析器函數的 m,有補 0
%En 對應解析器函數的 n,沒補 0
當前組是該年的第幾組(例如 monthInGroup = 3 時 %gi 就是第幾季)
%gI 有補 0
%gi 沒補 0
]=]
function p.byMonth(frame)
local args = frame.args
local prefix = args.prefix -- 存檔母頁面
local template = args.template -- 存檔頁面名模板 預設是套用 prefix/%Y年/%n月(monthInGroup = 1) / prefix/%Y年/%Sn-%En月(monthInGroup > 1)
if not template and not prefix then
return makeError('至少必須指定前綴 <code>prefix</code> 或 <code>template</code> 其中一個參數。')
end
local startYear = tonumber(args.startYear) -- 循環開始年分
local startMonth = tonumber(args.startMonth) -- 循環開始月份
local endYear = tonumber(args.endYear) or currentYear -- 循環終止年分
local endMonth = tonumber(args.endMonth) or currentMonth -- 循環終止月份
local monthInGroup = tonumber(args.monthInGroup) or 1 -- 循環月份分組
if monthInGroup == 12 then
return makeError('byMonth 不接受僅把一年分成一組。')
elseif 12 % monthInGroup ~= 0 then
return makeError('無法用 ' .. range .. ' 整除月份總數 12。')
end
local addColspan = tonumber(args.addColspan) or false -- 加入 colspan 方便排版
local startMonthGroup = getMonthGroup(startMonth, monthInGroup)
local endMonthGroup = getMonthGroup(endMonth, monthInGroup)
template = template or (monthInGroup > 1 and '%prefix/%Y年/%Sn-%En月' or '%prefix/%Y年/%n月')
template = template:gsub('%%prefix', escapePrefix(prefix))
local checkExists = args.checkExists and yesno(args.checkExists) or false -- 檢查存檔目標是否存在
local checkExistsPF = not checkExists and (args.checkExistsPF and yesno(args.checkExistsPF) or true) -- 檢查存檔目標是否存在(解析器函式版)
local outputTableBox = args.outputTableBox and yesno(args.outputTableBox) or false -- 是否輸出表格的框 {| |}
local tableProps = outputTableBox and (args.tableProps ~= nil and args.tableProps or 'style="width: 100%;"') -- 表格屬性組
local disableCurrentBold = args.disableCurrentBold and yesno(args.disableCurrentBold) or false -- 是否阻止對當前月份組加粗
local output = {}
if outputTableBox then
local tableBox = '{|'
if tableProps then
tableBox = tableBox .. ' ' .. mw.text.trim(tableProps)
end
output[#output + 1] = tableBox
end
for year = startYear, endYear, 1 do
output[#output + 1] = '|-'
output[#output + 1] = string.format('!style="text-align: left;"|%4d年', year)
for monthGroup = 1, 12 / monthInGroup, 1 do
local shouldPrintLink = not ((year == startYear and monthGroup < startMonthGroup) or (year == endYear and monthGroup > endMonthGroup))
local link, ceilProp
if monthInGroup == 1 then
link = shouldPrintLink
and buildLink(
formatTemplate(template, {
Y = tostring(year),
m = string.format('%2d', monthGroup),
n = tostring(monthGroup),
Sm = string.format('%2d', monthGroup),
Sn = tostring(monthGroup),
Em = string.format('%2d', monthGroup),
En = tostring(monthGroup),
gI = string.format('%2d', monthGroup),
gi = tostring(monthGroup),
}),
string.format(
(year == currentYear and monthGroup == currentMonth and not disableCurrentBold)
and '<span style="font-weight: bold;">%d</span>'
or '%d',
monthGroup
),
checkExists,
checkExistsPF
)
or string.format('<!--%d-->', monthGroup)
else
local startMonth = (monthGroup - 1) * monthInGroup + 1
local endMonth = monthGroup * monthInGroup
link = shouldPrintLink
and buildLink(
formatTemplate(template, {
Y = tostring(year),
Sm = string.format('%2d', startMonth),
Sn = tostring(startMonth),
Em = string.format('%2d', endMonth),
En = tostring(endMonth),
gI = string.format('%2d', monthGroup),
gi = tostring(monthGroup),
}),
string.format(
(year == currentYear and monthGroup == getMonthGroup(currentMonth, monthInGroup) and not disableCurrentBold)
and '<span style="font-weight: bold;">%d-%d</span>'
or '%d-%d',
startMonth, endMonth
),
checkExists,
checkExistsPF
)
or string.format('<!--%d-%d-->', startMonth, endMonth)
if addColspan then
ceilProp = string.format('colspan=%d', monthInGroup)
end
end
output[#output + 1] = ceilProp and string.format('|%s|%s', ceilProp, link) or string.format('|%s', link)
end
output[#output + 1] = '|style="text-align: right;"|月'
end
if outputTableBox then
output[#output + 1] = '|}'
end
return table.concat(output, '\n')
end
return p