Module:Automatic archive navigator/sandbox

From blackwiki
< Module:Automatic archive navigator
Revision as of 01:12, 8 October 2014 by blackwiki>Mr. Stradivarius (add blurb-making methods)
Jump to navigation Jump to search

Documentation for this module may be created at Module:Automatic archive navigator/sandbox/doc

--
-- This module implements {{Automatic archive navigator}}
--

require('Module:No globals')
local checkType = require('libraryUtil').checkType

-------------------------------------------------------------------------------
-- Config
-------------------------------------------------------------------------------

local cfg = {
['blurb-period'] = "This is an '''[[Help:Archiving a talk page|archive]]''' " ..
	"of past discussions for the period '''$2'''. '''Do not edit the " ..
	"contents of this page.''' If you wish to start a new discussion or " ..
	"revive an old one, please do so on the $1.",
['blurb-noperiod'] = "This is an '''[[Help:Archiving a talk page|archive]]''' " ..
	"of past discussions. '''Do not edit the contents of this page.''' If " ..
	"you wish to start a new discussion or revive an old one, please do so " ..
	"on the $1.",
['blurb-talk-link-display'] = 'current talk page',
['default-icon'] = 'Replacement filing cabinet.svg',
['image-size'] = '40x40px'
}

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

local function makeWikilink(page, display)
	return string.format('[[%s|%s]]', page, display)
end

-------------------------------------------------------------------------------
-- Archive class
-------------------------------------------------------------------------------

local Archive = {}
Archive.__index = Archive

function Archive.new(basePageName, prefix, num)
	checkType('Archive.new', 1, num, 'number')
	local obj = setmetatable({}, Archive)
	obj.basePageName = basePageName
	obj.prefix = prefix
	obj.num = num
	return obj
end

function Archive:makeLink(current)
	local subpage = self.prefix .. tostring(self.num)
	local page = self.basePageName .. subpage
	local link = makeWikilink(page, subpage)
	if current and self.num == current then
		link = string.format('<span style="font-size:115%;">%s</span>', link)
	end
	return link
end

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

local Navigator = {}
Navigator.__index = Navigator

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

	-- Define object structure.
	obj.links = {}

	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 = '----\n'
		if args.text then
			ret = ret .. args.text
		else
			local basePage = self.currentTitle.basePageTitle.prefixedText
			local talkLink = makeWikilink(
				basePage,
				self:message('blurb-talk-link-display')
			)
			local key = args.period and 'blurb-period' or 'blurb-noperiod'
			ret = ret .. self:message(key, talkLink, args.period or '')
		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(
			'[[File:%s|%s|alt=|link=]]',
			icon,
			self:message('image-size')
		)
	end

	local mbox = require('Module: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:makeLinksWikitable()
	-- Makes a single-row wikitable from an array of links
	local ret = {}
	ret[#ret + 1] = '{| style="width: 32em; background: transparent; margin: 0 auto 0.5em; text-align: center"'
	for _, link in ipairs(self.links) do
		ret[#ret + 1] = '\n| '
		ret[#ret + 1] = link
	end
	ret[#ret + 1] = '\n|}'
	return table.concat(ret)
end

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

local p = {}

local function getSubpageLink(offset, currentTitle)
	-- Get a formatted link to the subpage a certain distance away, or nil
	-- if that subpage does not exist. e.g. If the current subpage is
	-- /Archive 27, then getSubpageLink(3, currentTitle) returns a link to Archive 30.
	local subpageName
	local archiveNum = currentTitle.subpageText:match('^Archive ([1-9][0-9]*)$')
	archiveNum = tonumber(archiveNum)
	if archiveNum then
		subpageName = 'Archive ' .. (archiveNum + offset)
	elseif tonumber(currentTitle.subpageText) then
		subpageName = currentTitle.subpageText + offset
	else
		return nil  -- Couldn't parse out a subpage number
	end

	local subpageTitle = mw.title.new(currentTitle.baseText .. '/' .. subpageName, currentTitle.namespace)
	if subpageTitle.exists then
		return makeWikilink('/' .. subpageName, subpageName)
	else
		return nil
	end
end

local function getArchiveNums(current, highest, noLinks, allowRedLinks)
	-- Returns an array of the archive numbers to format.
	if not current or not highest then
		return {}
	end
	noLinks = noLinks or 7

	local nums = {}
	if noLinks >= highest then
		local lim
		if allowRedLinks then
			lim = noLinks
		else
			lim = highest
		end
		for i = 1, lim do
			nums[i] = i
		end
	end
end

local function foo(prefix)
	local highestArchive = require('Module:Highest archive number')._main(prefix)
end

local function getLinksText(args, currentTitle)
	local nbsp = '&nbsp;'
	local arrowSpacer, linkSpacer
	if mw.ustring.len(currentTitle.subpageText) <= 4 then
		-- If page names are short, we want more space.
		arrowSpacer = nbsp:rep(5)
		linkSpacer = nbsp:rep(7)
	else
		arrowSpacer = nbsp:rep(2)
		linkSpacer = nbsp:rep(4)
	end

	local ret = {}

	for offset = -5, -3 do
		local link = getSubpageLink(offset, currentTitle)
		if link then
			if offset == -3 then
				ret[#ret + 1] = link
				ret[#ret + 1] = linkSpacer
			else
				ret[#ret + 1] = link
				ret[#ret + 1] = ' ←'
				ret[#ret + 1] = arrowSpacer
			end
			break
		end
	end

	for offset = -2, -1 do
		local link = getSubpageLink(offset, currentTitle)
		if link then
			ret[#ret + 1] = link
			ret[#ret + 1] = linkSpacer
		end
	end

	ret[#ret + 1] = '<span style="font-size:115%;">'
	ret[#ret + 1] = makeWikilink(currentTitle.prefixedText, currentTitle.subpageText)
	ret[#ret + 1] = '</span>'

	for offset = 1, 2 do
		local link = getSubpageLink(offset, currentTitle)
		if link then
			ret[#ret + 1] = linkSpacer
			ret[#ret + 1] = link
		end
	end

	for offset = 5, 3, -1 do
		local link = getSubpageLink(offset, currentTitle)
		if link then
			if offset == 3 then
				ret[#ret + 1] = linkSpacer
				ret[#ret + 1] = link
			else
				ret[#ret + 1] = arrowSpacer
				ret[#ret + 1] = '→ '
				ret[#ret + 1] = link
			end
			break
		end
	end

	return table.concat(ret)
end

function p._aan(args, currentTitle)
	currentTitle = currentTitle or mw.title.getCurrentTitle()

	local image = args.image
	if not image then
		image = '[[File:' .. (args.icon or 'Replacement filing cabinet.svg') .. '|40x40px|alt=|link=]]'
	end

	local mbox = require('Module: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 = getLinksText(args, currentTitle) .. '\n' .. getMessage(args, currentTitle)
	})

	return mbox .. '__NONEWSECTIONLINK__ __NOEDITSECTION__'
end

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

setmetatable(p, {__index = function(t, k)
	return function(frame)
		local args = require('Module:Arguments').getArgs(frame, {
			wrappers = {
				'Template:Automatic archive navigator',
				'Template:Talk archive navigation'
			}
		})
		return p['_' .. k](args)
	end
end})

p.Navigator = Navigator
p.cfg = cfg

return p