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 " 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-90-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.cfgkey
	if select('#', ...) > 0 then
		return mw.message.newRawMessage(msg, ...):plain()
	else
		return msg
	end
end
function Navigator:makeBlurb()
	local args = self.args
	if args1 == '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(
			'link=',
			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 numsi - numsi - 1 > 1 then
			table.insert(links, i, lang:getArrow('forwards'))
			break
		end
	end
	for i = currentIndex - 1, 1, -1 do
		if numsi + 1 - numsi > 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