模块:Topic list
此模块及其文档搬运自中文Minecraft Wiki页面[[mcwzh:{{{page}}}|{{{page}}}]]。
这些内容依据CC BY-NC-SA 3.0协议引入。原贡献者请参见[{{fullurl:mcwzh:{{{page}}}|action=history}} 原页面的历史]。
经过双方编者的修改,这些内容与来源可能存在差异。
From interwiki:sync参数无效
创建一个讨论页的顶端目录,通过解析页面文本实现。
该目录实现来自于wzh:User:Kanashimi的机器人所维护的目录,但是是使用lua运行的,而非原实现方式。
用法
{{#invoke:Topic list|main|解析的页面名}}
注意内容
该模块或使用该模块的页面在嵌入时解析的页面时,应添加<noinclude>{{模板名}}</noinclude>
,否则会模板循环。
维护
如果文本中的特殊字符影响目录的生成,请在模块的conv
(全局转换)和titleConv
(标题输出转换)函数中添加字符转换,使目录正常生成。
引用
一般情况在条目讨论页中不直接引用此模块,而是引用{{topic list}}
模板。
local p = {}
local getArgs = require('Module:Arguments').getArgs
function conv(talk)
-- 关键词替换
-- 如有字符导致生成错误,请在这里添加转换
talk = talk
:gsub('===(.-)===', '%1')
:gsub('Special:用户贡献/(%d+%.%d+%.%d+%.%d+)', 'User:ip:%1') -- handle ip user first
:gsub('Special:Contributions/(%d+%.%d+%.%d+%.%d+)', 'User:ip:%1')
:gsub('Special:Contribs/(%d+%.%d+%.%d+%.%d+)', 'User:ip:%1')
:gsub('用户', 'User')
:gsub('user', 'User')
return talk
end
function titleStrip(talk)
talk = talk
:gsub('===(.-)===', '%1')
return talk
end
function titleConv(title)
-- 论题转换
title = title
:gsub('<.->', '')
:gsub('%[%[:?.-|(.-)%]%]', '%1')
:gsub('%[%[:?(.-)%]%]', '%1')
return title
end
function table.unique(t, bArray)
local check = {}
local n = {}
local idx = 1
for k, v in pairs(t) do
if not check[v] then
if bArray then
n[idx] = v
idx = idx + 1
else
n[k] = v
end
check[v] = true
end
end
return n
end
function getTimeStyle(time)
if time == '未知日期' then
return 'background-color: #fee;'
end
local _, _, year, month, day, hour, min = time:find '(%d+)年(%d+)月(%d+)日%s%(.-%)%s(%d+):(%d+)'
-- divided by 86400 is to convert seconds to days
local diff = os.difftime(os.time(), os.time {year = year, month = month, day = day, hour = hour, min = min}) / 86400
if diff >= 30 then
return 'background-color: #bbb;'
end
if diff >= 7 then
return 'background-color: #ddd;'
end
if diff >= 1 then
return ''
end
return 'background-color: #efe;'
end
function close(text)
if text:match 'closed%-topic%-yes' then
return 'background-color: #efe;'
end
if text:match 'closed%-topic%-no' then
return 'background-color: #fee;'
end
return ""
end
function trim(text)
-- remove special strip markers and spaces
text = mw.text.killMarkers(text):gsub('^[%s\t\r\n\f]*(.-)[%s\t\r\n\f]*$', '%1')
return text
end
function makeUserLink(text)
if text == '?' then
return text
end
-- 输入用户名以及带有ip:前缀的ip用户。
local ipUser = text:match 'ip:(.*)'
if ipUser then
return '[[Special:用户贡献/' .. ipUser .. '|' .. ipUser .. ']]'
else
return '[[User:' .. text .. '|' .. text .. ']]'
end
end
function getTalkList(pageName)
-- 输入页面名,返回一个包含文本的讨论信息表
-- 例如:talklist[1][text]
local talk = conv(mw.getCurrentFrame():expandTemplate {title = ':' .. pageName}) .. '=='
local talkList = {}
for topic in talk:gmatch '==\n(.-)==' do
talkList[#talkList + 1] = trim(topic)
end
return talkList
end
function getTitleList(pageName)
local talk = titleStrip(mw.getCurrentFrame():expandTemplate {title = ':' .. pageName})
local titleList = {}
for title in talk:gmatch '==(.-)==' do
titleList[#titleList + 1] = titleConv(trim(title))
end
return titleList
end
function getTalkTime(talk)
local result = talk:match '[%s%S]*(%d%d%d%d.*) %(CST%)' or '未知日期'
return result
end
function getUserInfo(text)
-- 输入讨论的文本,输出和User有关的转换部分table
local userList = {}
if text:match '[^\n]*User:([^\n]-)%|[^\n]-UTC' == nil then
return {userNum = '?', uniqueUserNum = '?', firstUser = '?', lastUser = '?'}
end
for user in text:gmatch '[^\n]*User:([^\n]-)%|[^\n]-UTC' do
userList[#userList + 1] = user
end
local userNum = #userList
local uniqueUserNum = #(table.unique(userList, true))
return {userNum = userNum, uniqueUserNum = uniqueUserNum, firstUser = userList[1], lastUser = userList[#userList]}
end
function generateTable(pageName, talkTitle, talkText)
local body = {
'{| class="wikitable sortable collapsible talktable" style="text-align: center; float: left;"',
'|-',
'! # !! 话题 !! 发言条数 !! 参与人数 ',
'! class="talkpage-topic-list-author" | 发起者',
'! class="talkpage-topic-list-last-editor" | 最后发言者',
'! class="talkpage-topic-list-time" | 最后发言时间(UTC)'
}
local userInfo, time
local userStyle, uniqueUserStyle, timeStyle, serialStyle
for i = 1, #talkText do
time, userInfo = getTalkTime(talkText[i]), getUserInfo(talkText[i])
-- 对表格添加样式
userStyle = userInfo.userNum == 1 and 'background-color: #fcc;' or ''
uniqueUserStyle = userInfo.uniqueUserNum == 1 and 'background-color: #fcc;' or ''
timeStyle = getTimeStyle(time)
serialStyle = close(talkText[i])
-- 组装表格一个话题的部分
table.insert(
body,
table.concat(
{
'|-',
'! style="' .. serialStyle .. '" | ' .. i,
'| [[' .. pageName .. '#' .. talkTitle[i] .. '|' .. talkTitle[i].. ']]',
'| style="' .. userStyle .. '" | ' .. userInfo.userNum,
'| style="' .. uniqueUserStyle .. '" | ' .. userInfo.uniqueUserNum,
'| class="talkpage-topic-list-author" | ' .. makeUserLink(userInfo.firstUser),
'| class="talkpage-topic-list-last-editor" style="' .. timeStyle .. '" | ' .. makeUserLink(userInfo.lastUser),
'| class="talkpage-topic-list-time" style="' .. timeStyle .. '" | ' .. time
},
'\n'
)
)
end
table.insert(body, '|}')
return table.concat(body, '\n')
end
function p.main(frame)
local args = getArgs(frame)
local f = mw.getCurrentFrame()
local talkTitle, talkText = getTitleList(args[1]), getTalkList(args[1])
for i = 1, #talkTitle do
talkTitle[i] = f:preprocess(talkTitle[i])
end
local result = generateTable(args[1], talkTitle, talkText)
if #talkTitle == #talkText then
return result
else
return error 'Topic list获取错误。'
end
end
return p