模組:PatternedCandidateUtils2
外观
--[[
FIXME: 已知以下幾種情況會導致錯誤:
1. 有標題無內容
2. 內容含有Enter
3. <nowiki>
...
== aaa ==
...
</nowiki>
4. HTML標籤是大寫的:<S>(目前未作特殊處理)
]]--
local z = {}
local HTMLTAGS = {'b', 'big', 'blockquote', 'br', 'caption', 'center', 'code', 'del', 'div', 'em', 'font', 'i', 'kbd', 'mark', 'p', 'q', 'rp', 'rt', 'ruby', 's', 'small', 'span', 'strong', 'sub', 'sup', 'time', 'tt'}
function getCandidates( frame )
local page = mw.title.new( frame.args.title ):getContent()
local matches = {}
local black = {}
if frame.args.black then
for b in mw.text.gsplit( frame.args.black, '|', true ) do
black[b] = true
end
end
for m in mw.ustring.gmatch( page, frame.args.pattern ) do
if not black[m] then
table.insert( matches, m )
end
end
return matches
end
function z.count( frame )
return #getCandidates( frame )
end
local function encodetitle( frame, text )
local nowikis = {}
-- 提取<pre>、<nowiki>與<ref>內容
local r = mw.text.trim(text or '')
r = string.gsub(r, '<pre>(.-)</pre>', function (s)
nowikis[#nowikis+1] = s
return '__NOWIKI_UNIT_' .. #nowikis .. '_'
end)
r = string.gsub(r, '<nowiki>(.-)</nowiki>', function (s)
nowikis[#nowikis+1] = s
return '__NOWIKI_UNIT_' .. #nowikis .. '_'
end)
r = string.gsub(r, '<ref>(.-)</ref>', function (s)
nowikis[#nowikis+1] = s
return '__NOWIKI_UNIT_' .. #nowikis .. '_'
end)
-- 解析wikitext
r = frame:preprocess(r)
-- 粗體與斜體
r = string.gsub(r, "'''''(.-)'''''", '%1')
r = string.gsub(r, "'''(.-)'''", '%1')
r = string.gsub(r, "''(.-)''", '%1')
-- 去除圖片
r = string.gsub(r, '%[%[[Ff]ile:([^\n]-)%]%]', '')
r = string.gsub(r, '%[%[文件:([^\n]-)%]%]', '')
r = string.gsub(r, '%[%[檔案:([^\n]-)%]%]', '')
-- 展開連結
r = string.gsub(r, '%[%[[^%|%]\n]-%|([^\n]-)%]%]', '%1')
r = string.gsub(r, '%[%[:?([^\n]-)%]%]', '%1')
-- 去除HTML標籤
for i, t in ipairs(HTMLTAGS) do
r = string.gsub(r, '</?' .. t.. '.->', '')
end
-- 將pre與nowiki內容放回文字之中
for i, t in ipairs(nowikis) do
local u = string.gsub(t, '&', '&')
u = string.gsub(t, '<', '<')
u = string.gsub(t, '>', '>')
r = string.gsub(r, '__NOWIKI_UNIT_' .. i .. '_', u)
end
-- 更換特殊字元
r = string.gsub(r, '%[', '[')
r = string.gsub(r, '%]', ']')
r = string.gsub(r, '%|', '|')
r = string.gsub(r, '{', '{')
r = string.gsub(r, '}', '}')
return mw.text.trim(r)
end
function z.list( frame )
local list = getCandidates( frame )
local linkprefix = mw.text.trim(frame.args.linkprefix)
local anchorno = {}
for i = 1, #list do
if linkprefix then
local title = encodetitle(frame, list[i])
-- 記錄標題文字,如果重複,那麼在後面附加「_2」、「_3」……
anchorno[title] = (anchorno[title] or 0) + 1
local postfix = (anchorno[title] > 1 and '_' .. anchorno[title]) or ''
list[i] = '[[:' .. linkprefix .. string.gsub(title, '&', '&') .. postfix .. '|' .. title .. ']]'
else
list[i] = '[[:' .. list[i] .. ']]'
end
end
if #list > 0 then
return table.concat( list, '-' )
else
return '暂无'
end
end
function z.listtalk( frame )
frame.args.pattern = '[^=]==%s*([^=]+)%s*==[^=]'
if frame.args[1] and not frame.args.title then
frame.args.title = frame.args[1]
end
frame.args.linkprefix = mw.text.trim(frame.args.title or '') .. '#'
return z.list(frame)
end
return z