<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://capipedia.cap.gov/index.php?action=history&amp;feed=atom&amp;title=Module%3AAutomatic_archive_navigator</id>
	<title>Module:Automatic archive navigator - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://capipedia.cap.gov/index.php?action=history&amp;feed=atom&amp;title=Module%3AAutomatic_archive_navigator"/>
	<link rel="alternate" type="text/html" href="https://capipedia.cap.gov/index.php?title=Module:Automatic_archive_navigator&amp;action=history"/>
	<updated>2026-04-20T16:56:24Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.45.1</generator>
	<entry>
		<id>https://capipedia.cap.gov/index.php?title=Module:Automatic_archive_navigator&amp;diff=6935&amp;oldid=prev</id>
		<title>NMcLarty27: 1 revision imported</title>
		<link rel="alternate" type="text/html" href="https://capipedia.cap.gov/index.php?title=Module:Automatic_archive_navigator&amp;diff=6935&amp;oldid=prev"/>
		<updated>2024-01-23T18:24:17Z</updated>

		<summary type="html">&lt;p&gt;1 revision imported&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 14:24, 23 January 2024&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-notice&quot; lang=&quot;en&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(No difference)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>NMcLarty27</name></author>
	</entry>
	<entry>
		<id>https://capipedia.cap.gov/index.php?title=Module:Automatic_archive_navigator&amp;diff=6934&amp;oldid=prev</id>
		<title>en&gt;Xaosflux: ++__ARCHIVEDTALK__</title>
		<link rel="alternate" type="text/html" href="https://capipedia.cap.gov/index.php?title=Module:Automatic_archive_navigator&amp;diff=6934&amp;oldid=prev"/>
		<updated>2023-04-06T13:55:45Z</updated>

		<summary type="html">&lt;p&gt;++__ARCHIVEDTALK__&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;-------------------------------------------------------------------------------&lt;br /&gt;
--                       Automatic archive navigator&lt;br /&gt;
--&lt;br /&gt;
-- This module produces a talk archive banner, together with an automatically-&lt;br /&gt;
-- generated list of navigation links to other archives of the talk page in&lt;br /&gt;
-- question. It implements {{Automatic archive navigator}} and&lt;br /&gt;
-- {{Talk archive navigation}}.&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
local yesno = require(&amp;#039;Module:Yesno&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Helper functions&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
local function makeWikilink(page, display)&lt;br /&gt;
	if display then&lt;br /&gt;
		return string.format(&amp;#039;[[%s|%s]]&amp;#039;, page, display)&lt;br /&gt;
	else&lt;br /&gt;
		return string.format(&amp;#039;[[%s]]&amp;#039;, page)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function escapePattern(s)&lt;br /&gt;
	-- Escape punctuation in a string so it can be used in a Lua pattern.&lt;br /&gt;
	s = s:gsub(&amp;#039;%p&amp;#039;, &amp;#039;%%%0&amp;#039;)&lt;br /&gt;
	return s&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Navigator class&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
local Navigator = {}&lt;br /&gt;
Navigator.__index = Navigator&lt;br /&gt;
&lt;br /&gt;
function Navigator.new(args, cfg, currentTitle)&lt;br /&gt;
	local obj = setmetatable({}, Navigator)&lt;br /&gt;
	&lt;br /&gt;
	-- Set inputs&lt;br /&gt;
	obj.args = args&lt;br /&gt;
	obj.cfg = cfg&lt;br /&gt;
	obj.currentTitle = currentTitle&lt;br /&gt;
&lt;br /&gt;
	-- Archive prefix&lt;br /&gt;
	-- Decode HTML entities so users can enter things like &amp;quot;Archive&amp;amp;#32;&amp;quot; from&lt;br /&gt;
	-- wikitext.&lt;br /&gt;
	obj.archivePrefix = obj.args.prefix or obj:message(&amp;#039;archive-prefix&amp;#039;)&lt;br /&gt;
	obj.archivePrefix = mw.text.decode(obj.archivePrefix)&lt;br /&gt;
&lt;br /&gt;
	-- Current archive number&lt;br /&gt;
	do&lt;br /&gt;
		local pattern = string.format(&lt;br /&gt;
			&amp;#039;^%s([1-9][0-9]*)$&amp;#039;,&lt;br /&gt;
			escapePattern(obj.archivePrefix)&lt;br /&gt;
		)&lt;br /&gt;
		obj.currentArchiveNum = obj.currentTitle.subpageText:match(pattern)&lt;br /&gt;
		obj.currentArchiveNum = tonumber(obj.currentArchiveNum)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Highest archive number&lt;br /&gt;
	obj.highestArchiveNum = require(&amp;#039;Module:Highest archive number&amp;#039;)._main(&lt;br /&gt;
		 obj.currentTitle.nsText ..&lt;br /&gt;
		 	&amp;#039;:&amp;#039; .. &lt;br /&gt;
			obj.currentTitle.baseText .. &lt;br /&gt;
			&amp;#039;/&amp;#039; .. &lt;br /&gt;
			obj.archivePrefix&lt;br /&gt;
	)&lt;br /&gt;
&lt;br /&gt;
	return obj&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Navigator:message(key, ...)&lt;br /&gt;
	local msg = self.cfg[key]&lt;br /&gt;
	if select(&amp;#039;#&amp;#039;, ...) &amp;gt; 0 then&lt;br /&gt;
		return mw.message.newRawMessage(msg, ...):plain()&lt;br /&gt;
	else&lt;br /&gt;
		return msg&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Navigator:makeBlurb()&lt;br /&gt;
	local args = self.args&lt;br /&gt;
	if args[1] == &amp;#039;1&amp;#039; then&lt;br /&gt;
		-- The old template used &amp;quot;|1&amp;quot; to suppress the blurb.&lt;br /&gt;
		return &amp;#039;&amp;#039;&lt;br /&gt;
	else&lt;br /&gt;
		local ret&lt;br /&gt;
		if args.text then&lt;br /&gt;
			ret = args.text&lt;br /&gt;
		else&lt;br /&gt;
			local talkPage = self.currentTitle.nsText ..&lt;br /&gt;
				&amp;#039;:&amp;#039; ..&lt;br /&gt;
				self.currentTitle.baseText&lt;br /&gt;
			if args.period then&lt;br /&gt;
				ret = self:message(&amp;#039;blurb-period&amp;#039;, talkPage, args.period)&lt;br /&gt;
			else&lt;br /&gt;
				ret = self:message(&amp;#039;blurb-noperiod&amp;#039;, talkPage)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		return ret&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Navigator:makeMessageBox()&lt;br /&gt;
	local args = self.args&lt;br /&gt;
	&lt;br /&gt;
	local image&lt;br /&gt;
	if args.image then&lt;br /&gt;
		image = args.image&lt;br /&gt;
	else&lt;br /&gt;
		local icon = args.icon or self:message(&amp;#039;default-icon&amp;#039;)&lt;br /&gt;
		image = string.format(&lt;br /&gt;
			&amp;#039;[[File:%s|%s|alt=|link=]]&amp;#039;,&lt;br /&gt;
			icon,&lt;br /&gt;
			self:message(&amp;#039;image-size&amp;#039;)&lt;br /&gt;
		)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local mbox = require(&amp;#039;Module:Message box&amp;#039;).main(&amp;#039;tmbox&amp;#039;, {&lt;br /&gt;
		image = image,&lt;br /&gt;
		imageright = args.imageright,&lt;br /&gt;
		style = args.style or &amp;#039;&amp;#039;,&lt;br /&gt;
		textstyle = args.textstyle or &amp;#039;text-align:center&amp;#039;,&lt;br /&gt;
		text = self:makeBlurb()&lt;br /&gt;
	})&lt;br /&gt;
&lt;br /&gt;
	return mbox&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Navigator:getArchiveNums()&lt;br /&gt;
	-- Returns an array of the archive numbers to format.&lt;br /&gt;
	local noLinks = tonumber(self.args.links) or self:message(&amp;#039;default-link-count&amp;#039;)&lt;br /&gt;
	noLinks = math.floor(noLinks)&lt;br /&gt;
	-- If |noredlinks is &amp;quot;yes&amp;quot;, true or absent, don&amp;#039;t allow red links. If it is &lt;br /&gt;
	-- &amp;#039;no&amp;#039; or false, allow red links.&lt;br /&gt;
	local allowRedLinks = yesno(self.args.noredlinks) == false&lt;br /&gt;
	&lt;br /&gt;
	local current = self.currentArchiveNum&lt;br /&gt;
	local highest = self.highestArchiveNum&lt;br /&gt;
&lt;br /&gt;
	if not current or not highest or noLinks &amp;lt; 1 then&lt;br /&gt;
		return {}&lt;br /&gt;
	elseif noLinks == 1 then&lt;br /&gt;
		return {current}&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local function getNum(i, current)&lt;br /&gt;
		-- Gets an archive number given i, the position in the array away from&lt;br /&gt;
		-- the current archive, and the current archive number. The first two&lt;br /&gt;
		-- offsets are consecutive; the third offset is rounded up to the&lt;br /&gt;
		-- nearest 5; and the fourth and subsequent offsets are rounded up to&lt;br /&gt;
		-- the nearest 10. The offsets are calculated in such a way that archive&lt;br /&gt;
		-- numbers will not be duplicated.&lt;br /&gt;
		if -2 &amp;lt;= i and i &amp;lt;= 2 then&lt;br /&gt;
			return current + i&lt;br /&gt;
		elseif -3 &amp;lt;= i and i &amp;lt;= 3 then&lt;br /&gt;
			return current + 2 - (current + 2) % 5 + (i / 3) * 5&lt;br /&gt;
		elseif 4 &amp;lt;= i then&lt;br /&gt;
			return current + 7 - (current + 7) % 10 + (i - 3) * 10&lt;br /&gt;
		else&lt;br /&gt;
			return current + 2 - (current + 2) % 10 + (i + 3) * 10&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local nums = {}&lt;br /&gt;
&lt;br /&gt;
	-- Archive nums lower than the current page.&lt;br /&gt;
	for i = -1, -math.floor((noLinks - 1) / 2), -1 do&lt;br /&gt;
		local num = getNum(i, current)&lt;br /&gt;
		if num &amp;lt;= 1 then&lt;br /&gt;
			table.insert(nums, 1, 1)&lt;br /&gt;
			break&lt;br /&gt;
		else&lt;br /&gt;
			table.insert(nums, 1, num)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Current page.&lt;br /&gt;
	if nums[#nums] &amp;lt; current then&lt;br /&gt;
		table.insert(nums, current)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Higher archive nums.&lt;br /&gt;
	for i = 1, math.ceil((noLinks - 1) / 2) do&lt;br /&gt;
		local num = getNum(i, current)&lt;br /&gt;
		if num &amp;lt;= highest then&lt;br /&gt;
			table.insert(nums, num)&lt;br /&gt;
		elseif allowRedLinks and (i &amp;lt;= 2 or i &amp;lt;= 3 and num == nums[#nums] + 1) then&lt;br /&gt;
			-- Only insert one red link, and only if it is consecutive.&lt;br /&gt;
			table.insert(nums, highest + 1)&lt;br /&gt;
			break&lt;br /&gt;
		elseif nums[#nums] &amp;lt; highest then&lt;br /&gt;
			-- Insert the highest archive number if it isn&amp;#039;t already there.&lt;br /&gt;
			table.insert(nums, highest)&lt;br /&gt;
			break&lt;br /&gt;
		else&lt;br /&gt;
			break&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return nums&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Navigator:makeArchiveLinksWikitable()&lt;br /&gt;
	local lang = mw.language.getContentLanguage()&lt;br /&gt;
	local nums = self:getArchiveNums()&lt;br /&gt;
	local noLinks = #nums&lt;br /&gt;
	if noLinks &amp;lt; 1 then&lt;br /&gt;
		return &amp;#039;&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Make the table of links.&lt;br /&gt;
	local links = {}&lt;br /&gt;
	local isCompact = noLinks &amp;gt; 7&lt;br /&gt;
	local currentIndex&lt;br /&gt;
	for i, num in ipairs(nums) do&lt;br /&gt;
		local subpage = self.archivePrefix .. tostring(num)&lt;br /&gt;
		local display&lt;br /&gt;
		if isCompact then&lt;br /&gt;
			display = tostring(num)&lt;br /&gt;
		else&lt;br /&gt;
			display = self:message(&amp;#039;archive-link-display&amp;#039;, num)&lt;br /&gt;
		end&lt;br /&gt;
		local link = makeWikilink(&amp;#039;../&amp;#039; .. subpage, display)&lt;br /&gt;
		if num == self.currentArchiveNum then&lt;br /&gt;
			link = string.format(&amp;#039;&amp;lt;span style=&amp;quot;font-size:115%%;&amp;quot;&amp;gt;%s&amp;lt;/span&amp;gt;&amp;#039;, link)&lt;br /&gt;
			currentIndex = i&lt;br /&gt;
		end&lt;br /&gt;
		table.insert(links, link)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Add the arrows.&lt;br /&gt;
	-- We must do the forwards arrow first as we are adding elements to the&lt;br /&gt;
	-- links table. If we did the backwards arrow first the index for the&lt;br /&gt;
	-- current archive would be wrong.&lt;br /&gt;
	currentIndex = currentIndex or math.ceil(#links / 2)&lt;br /&gt;
	for i = currentIndex + 1, #links do&lt;br /&gt;
		if nums[i] - nums[i - 1] &amp;gt; 1 then&lt;br /&gt;
			table.insert(links, i, lang:getArrow(&amp;#039;forwards&amp;#039;))&lt;br /&gt;
			break&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	for i = currentIndex - 1, 1, -1 do&lt;br /&gt;
		if nums[i + 1] - nums[i] &amp;gt; 1 then&lt;br /&gt;
			table.insert(links, i + 1, lang:getArrow(&amp;#039;backwards&amp;#039;))&lt;br /&gt;
			break&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Output the wikitable.&lt;br /&gt;
	local ret = {}&lt;br /&gt;
	local width&lt;br /&gt;
	if noLinks &amp;lt;= 3 then&lt;br /&gt;
		width = string.format(&amp;#039;%dem&amp;#039;, noLinks * 10)&lt;br /&gt;
	elseif noLinks &amp;lt;= 7 then&lt;br /&gt;
		width = string.format(&amp;#039;%dem&amp;#039;, (noLinks + 3) * 5)&lt;br /&gt;
	else&lt;br /&gt;
		width = &amp;#039;50em&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
	ret[#ret + 1] = string.format(&lt;br /&gt;
		&amp;#039;{| style=&amp;quot;width:%s;background:transparent;&amp;#039; ..&lt;br /&gt;
			&amp;#039;margin:0 auto 0.5em;text-align:center&amp;quot;&amp;#039;,&lt;br /&gt;
		width&lt;br /&gt;
	)&lt;br /&gt;
	for i, s in ipairs(links) do&lt;br /&gt;
		if i % 20 == 1 then&lt;br /&gt;
			ret[#ret + 1] = &amp;#039;\n|-&amp;#039;&lt;br /&gt;
		end&lt;br /&gt;
		ret[#ret + 1] = &amp;#039;\n| &amp;#039;&lt;br /&gt;
		ret[#ret + 1] = s&lt;br /&gt;
	end&lt;br /&gt;
	ret[#ret + 1] = &amp;#039;\n|}&amp;#039;&lt;br /&gt;
	return table.concat(ret)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Navigator:__tostring()&lt;br /&gt;
	return self:makeMessageBox() ..&lt;br /&gt;
		&amp;#039;\n&amp;#039; .. &lt;br /&gt;
		self:makeArchiveLinksWikitable() .. &lt;br /&gt;
		&amp;#039; __NONEWSECTIONLINK__ __NOEDITSECTION__ __ARCHIVEDTALK__&amp;#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Exports&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
function p._exportClasses()&lt;br /&gt;
	return {&lt;br /&gt;
		Navigator = Navigator&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p._aan(args, cfg, currentTitle)&lt;br /&gt;
	cfg = cfg or mw.loadData(&amp;#039;Module:Automatic archive navigator/config&amp;#039;)&lt;br /&gt;
	currentTitle = currentTitle or mw.title.getCurrentTitle()&lt;br /&gt;
	local aan = Navigator.new(args, cfg, currentTitle)&lt;br /&gt;
	return tostring(aan)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.aan(frame)&lt;br /&gt;
	local args = require(&amp;#039;Module:Arguments&amp;#039;).getArgs(frame, {&lt;br /&gt;
		wrappers = &amp;#039;Template:Automatic archive navigator&amp;#039;,&lt;br /&gt;
	})&lt;br /&gt;
	return p._aan(args)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>en&gt;Xaosflux</name></author>
	</entry>
</feed>