Mô đun:AutomaticArchiveNavigator

-------------------------------------------------------------------------------
-- AutomaticArchiveNavigator
--
-- This module produces a talk archive banner, together with an automatically-
-- generated list of navigation links to other archives of the talk page in
-- question. It implements and
-- .
-------------------------------------------------------------------------------

local yesno = require('Mô đun:Yesno')

-------------------------------------------------------------------------------
-- Helper functions
-------------------------------------------------------------------------------

local function makeWikilink(page, display)
if display then
return string.format('%s', page, display)
else
return string.format('%s', page)
end
end

local function escapePattern(s)
-- Escape punctuation in a string so it can be used in a Lua pattern.
s = s:gsub('%p', '%%%0')
return s
end

-------------------------------------------------------------------------------
-- Navigator class
-------------------------------------------------------------------------------

local Navigator = {}
Navigator.__index = Navigator

function Navigator.new(args, cfg, currentTitle)
local obj = setmetatable({}, Navigator)

-- Set inputs
obj.args = args
obj.cfg = cfg
obj.currentTitle = currentTitle

-- Archive prefix
-- Decode HTML entities so users can enter things like "Archive&32;" from
-- wikitext.
obj.archivePrefix = obj.args.prefix or obj:message('archive-prefix')
obj.archivePrefix = mw.text.decode(obj.archivePrefix)

-- Current archive number
do
local pattern = string.format(
'^%s([1-9][0-9])$',
escapePattern(obj.archivePrefix)
)
obj.currentArchiveNum = obj.currentTitle.subpageText:match(pattern)
obj.currentArchiveNum = tonumber(obj.currentArchiveNum)
end

-- Highest archive number
obj.highestArchiveNum = require('Mô đun:Highest archive number')._main(
obj.currentTitle.nsText ..
':' ..
obj.currentTitle.baseText ..
'/' ..
obj.archivePrefix
)

return obj
end

function Navigator:message(key, ...)
local msg = self.cfg[key]
if select('', ...) > 0 then
return mw.message.newRawMessage(msg, ...):plain()
else
return msg
end
end

function Navigator:makeBlurb()
local args = self.args
if args[1] == '1' then
-- The old template used "|1" to suppress the blurb.
return
else
local ret
if args.text then
ret = args.text
else
local talkPage = self.currentTitle.nsText ..
':' ..
self.currentTitle.baseText
if args.period then
ret = self:message('blurb-period', talkPage, args.period)
else
ret = self:message('blurb-noperiod', talkPage)
end
end
return ret
end
end

function Navigator:makeMessageBox()
local args = self.args

local image
if args.image then
image = args.image
else
local icon = args.icon or self:message('default-icon')
image = string.format(
,
icon,
self:message('image-size')
)
end

local mbox = require('Mô đun:Message box').main('tmbox', {
image = image,
imageright = args.imageright,
style = args.style or 'width:80%;margin-left:auto;margin-right:auto',
textstyle = args.textstyle or 'text-align:center',
text = self:makeBlurb()
})

return mbox
end

function Navigator:getArchiveNums()
-- Returns an array of the archive numbers to format.
local noLinks = tonumber(self.args.links) or self:message('default-link-count')
noLinks = math.floor(noLinks)
-- If |noredlinks is "yes", true or absent, don't allow red links. If it is
-- 'no' or false, allow red links.
local allowRedLinks = yesno(self.args.noredlinks) == false

local current = self.currentArchiveNum
local highest = self.highestArchiveNum

if not current or not highest or noLinks 7
local currentIndex
for i, num in ipairs(nums) do
local subpage = self.archivePrefix .. tostring(num)
local display
if isCompact then
display = tostring(num)
else
display = self:message('archive-link-display', num)
end
local link = makeWikilink('../' .. subpage, display)
if num == self.currentArchiveNum then
link = string.format('%s', link)
currentIndex = i
end
table.insert(links, link)
end

-- Add the arrows.
-- We must do the forwards arrow first as we are adding elements to the
-- links table. If we did the backwards arrow first the index for the
-- current archive would be wrong.
currentIndex = currentIndex or math.ceil(links / 2)
for i = currentIndex + 1, links do
if nums[i] - nums[i - 1] > 1 then
table.insert(links, i, lang:getArrow('forwards'))
break
end
end
for i = currentIndex - 1, 1, -1 do
if nums[i + 1] - nums[i] > 1 then
table.insert(links, i + 1, lang:getArrow('backwards'))
break
end
end

-- Output the wikitable.
local ret = {}
local width
if noLinks <= 3 then
width = string.format('%dem', noLinks 10)
elseif noLinks <= 7 then
width = string.format('%dem', (noLinks + 3) 5)
else
width = '50em'
end
ret[ret + 1] = string.format(

return table.concat(ret)
end

function Navigator:__tostring()
return self:makeMessageBox() ..
'\n' ..
self:makeArchiveLinksWikitable() ..
' __NONEWSECTIONLINK__ __NOEDITSECTION__'
end

-------------------------------------------------------------------------------
-- Exports
-------------------------------------------------------------------------------

local p = {}

function p._aan(args, cfg, currentTitle)
cfg = cfg or mw.loadData('Module:AutomaticArchiveNavigator/config')
currentTitle = currentTitle or mw.title.getCurrentTitle()
local aan = Navigator.new(args, cfg, currentTitle)
return tostring(aan)
end

function p._tan(args)
args.links = args.links or 3
args.noredlinks = args.noredlinks or false
return p._aan(args)
end

function p._exportClasses()
return {
Navigator = Navigator
}
end

setmetatable(p, {__index = function(t, k)
return function(frame)
local args = require('Mô đun:Arguments').getArgs(frame, {
wrappers = {
'Bản mẫu:Ltln',
'Bản mẫu:Lưunav'
}
})
return p['_' .. k](args)
end
end})

return p