https://en.wikipedia.org/w/index.php?action=history&feed=atom&title=Module%3AArchive_list_alphaModule:Archive list alpha - Revision history2025-05-27T19:53:35ZRevision history for this page on the wikiMediaWiki 1.45.0-wmf.2https://en.wikipedia.org/w/index.php?title=Module:Archive_list_alpha&diff=1115482690&oldid=prevMusikBot II: Protected "Module:Archive list alpha": High-risk template or module: 930 transclusions (more info) ([Edit=Require autoconfirmed or confirmed access] (indefinite))2022-10-11T18:03:23Z<p>Protected "<a href="/wiki/Module:Archive_list_alpha" title="Module:Archive list alpha">Module:Archive list alpha</a>": <a href="/wiki/Wikipedia:High-risk_templates" title="Wikipedia:High-risk templates">High-risk template or module</a>: 930 transclusions (<a href="/wiki/User:MusikBot_II/TemplateProtector" title="User:MusikBot II/TemplateProtector">more info</a>) ([Edit=Require autoconfirmed or confirmed access] (indefinite))</p>
<table style="background-color: #fff; color: #202122;" data-mw="interface">
<tr class="diff-title" lang="en">
<td colspan="1" style="background-color: #fff; color: #202122; text-align: center;">← Previous revision</td>
<td colspan="1" style="background-color: #fff; color: #202122; text-align: center;">Revision as of 18:03, 11 October 2022</td>
</tr><tr><td colspan="2" class="diff-notice" lang="en"><div class="mw-diff-empty">(No difference)</div>
</td></tr></table>MusikBot IIhttps://en.wikipedia.org/w/index.php?title=Module:Archive_list_alpha&diff=1115473344&oldid=prevTerasail: Create from Module:Archive list2022-10-11T17:02:58Z<p>Create from <a href="/wiki/Module:Archive_list" title="Module:Archive list">Module:Archive list</a></p>
<p><b>New page</b></p><div>-- This module was created from [[Module:Archive list]] and only some<br />
-- lines were changes in order to search for alphabetical archives<br />
<br />
-- This module implements {{Archive list alpha}} in Lua, and adds a few<br />
-- new features.<br />
<br />
-- Converts the integer counter for an archive to an alphabetical string<br />
local function numToLetters(newInt)<br />
newInt = newInt - 1<br />
local modVal = newInt % 26<br />
local newLetter = string.char(string.byte('A') + modVal)<br />
if newInt >= 26 then<br />
return numToLetters(math.floor(newInt / 26)) .. newLetter<br />
end<br />
return newLetter<br />
end<br />
<br />
-- Process a numeric argument to make sure it is a positive<br />
-- integer.<br />
local function processNumArg( num )<br />
if num then<br />
num = tonumber( num )<br />
if type( num ) == 'number' then<br />
num = math.floor( num )<br />
if num >= 0 then<br />
return num<br />
end<br />
end<br />
end<br />
return nil<br />
end<br />
<br />
-- Checks whether a page exists, going through pcall<br />
-- in case we are over the expensive function limit.<br />
local function checkPageExists( title )<br />
if not title then<br />
error('No title passed to checkArchiveExists', 2)<br />
end<br />
local noError, titleObject = pcall(mw.title.new, title)<br />
if not noError then<br />
-- If we are over the expensive function limit then assume<br />
-- that the page doesn't exist.<br />
return false<br />
else<br />
if titleObject then<br />
return titleObject.exists<br />
else<br />
return false -- Return false if given a bad title.<br />
end<br />
end<br />
end<br />
<br />
-- Checks every nth archive to see if it exists, and returns the<br />
-- number of the first archive that doesn't exist. It is<br />
-- necessary to do this in batches because each check is an<br />
-- expensive function call, and we want to avoid making too many<br />
-- of them so as not to go over the expensive function limit.<br />
local function checkArchives( prefix, n, start )<br />
local i = start<br />
local exists = true<br />
while exists do<br />
--``exists = checkPageExists( prefix .. tostring( i ) )<br />
exists = checkPageExists( prefix .. numToLetters( i ) )<br />
if exists then<br />
i = i + n<br />
end<br />
end<br />
return i<br />
end<br />
<br />
-- Return the biggest archive number, using checkArchives()<br />
-- and starting in intervals of 1000. This should get us a<br />
-- maximum of 500,000 possible archives before we hit the<br />
-- expensive function limit.<br />
local function getBiggestArchiveNum( prefix, start, max )<br />
-- Return the value for max if it is specified.<br />
max = processNumArg( max )<br />
if max then<br />
return max<br />
end<br />
<br />
-- Otherwise, detect the largest archive number.<br />
start = start or 1<br />
local check1000 = checkArchives( prefix, 1000, start )<br />
if check1000 == start then<br />
return 0 -- Return 0 if no archives were found.<br />
end<br />
local check200 = checkArchives( prefix, 200, check1000 - 1000 )<br />
local check50 = checkArchives( prefix, 50, check200 - 200 )<br />
local check10 = checkArchives( prefix, 10, check50 - 50 )<br />
local check1 = checkArchives( prefix, 1, check10 - 10 )<br />
-- check1 is the first page that doesn't exist, so we want to<br />
-- subtract it by one to find the biggest existing archive.<br />
return check1 - 1<br />
end<br />
<br />
-- Get the archive link prefix (the title of the archive pages<br />
-- minus the number).<br />
local function getPrefix( root, prefix, prefixSpace )<br />
local ret = root or mw.title.getCurrentTitle().prefixedText<br />
ret = ret .. '/'<br />
if prefix then<br />
ret = ret .. prefix<br />
if prefixSpace == 'yes' then<br />
ret = ret .. ' '<br />
end<br />
else<br />
ret = ret .. 'Archive '<br />
end<br />
return ret<br />
end<br />
<br />
-- Get the number of archives to put on one line. Set to<br />
-- math.huge if there should be no line breaks.<br />
local function getLineNum( links, nobr, isLong )<br />
local linksToNum = tonumber( links )<br />
local lineNum<br />
if nobr == 'yes' or (links and not linksToNum) then<br />
lineNum = math.huge<br />
-- If links is a number, process it. Negative values and expressions<br />
-- such as links=8/2 produced some interesting values with the old<br />
-- template, but we will ignore those for simplicity.<br />
elseif type(linksToNum) == 'number' and linksToNum >= 0 then<br />
-- The old template rounded down decimals to the nearest integer.<br />
lineNum = math.floor( linksToNum )<br />
if lineNum == 0 then<br />
-- In the old template, values of links between 0 and 0.999<br />
-- suppressed line breaks.<br />
lineNum = math.huge<br />
end<br />
else<br />
if isLong==true then<br />
lineNum = 3 -- Default to 3 links on long<br />
else<br />
lineNum = 10 -- Default to 10 on short<br />
end<br />
end<br />
return lineNum<br />
end<br />
<br />
-- Gets the prefix to put before the archive links.<br />
local function getLinkPrefix( prefix, space, isLong )<br />
-- Get the link prefix.<br />
local ret = ''<br />
if isLong==true then ---- Default of old template for long is 'Archive '<br />
if type(prefix) == 'string' then<br />
if prefix == 'none' then -- 'none' overrides to empty prefix<br />
ret = ''<br />
else<br />
ret = prefix<br />
if space == 'yes' then<br />
ret = ret .. ' '<br />
end<br />
end<br />
else<br />
ret = 'Archive '<br />
end<br />
else --type is not long<br />
if type(prefix) == 'string' then<br />
ret = prefix<br />
if space == 'yes' then<br />
ret = ret .. ' '<br />
end<br />
end<br />
end<br />
return ret<br />
end<br />
<br />
-- Get the number to start listing archives from.<br />
local function getStart( start )<br />
start = processNumArg( start )<br />
if start then<br />
return start<br />
else<br />
return 1<br />
end<br />
end<br />
<br />
-- Get whether to leave a blank cell in the first row and column <br />
-- If links start at 1, and lineNum is a round number, this aligns the first <br />
-- column to start on a multiple of lineNum, which may be a nice round number <br />
local function getLeaveFirstCellBlank( leaveFirstCellBlank ) <br />
return leaveFirstCellBlank == 'yes' <br />
or leaveFirstCellBlank == 'y' <br />
or leaveFirstCellBlank == 1 <br />
end<br />
<br />
-- Process the separator parameter.<br />
local function getSeparator( sep )<br />
if sep and type(sep) == 'string' then<br />
if sep == 'dot' <br />
or sep =='pipe'<br />
or sep == 'comma'<br />
or sep == 'tpt-languages' then<br />
return mw.message.new( sep .. '-separator' ):plain()<br />
else<br />
return sep<br />
end<br />
else<br />
return nil<br />
end<br />
end<br />
<br />
-- Generates the list of archive links. glargs.max must be either zero (for<br />
-- no archives) or a positive integer value.<br />
local function generateLinks( glargs )<br />
if type( glargs ) ~= 'table' or not glargs.max or not glargs.prefix then<br />
error('insufficient arguments passed to generateLinks', 2)<br />
end<br />
-- If there are no archives yet, return a message and a<br />
-- link to create Archive one.<br />
if glargs.max == 0 then<br />
if glargs.isLong == true then<br />
glargs.max = 1 -- One archive redlink is displayed for Long format<br />
else -- Short error and a creat link is displayed for short<br />
--``return 'no archives yet ([[' .. glargs.prefix .. '1|create]])'<br />
return 'no archives yet ([[' .. glargs.prefix .. 'A|create]])'<br />
end<br />
end<br />
-- Return an html error if the start number is greater than the <br />
-- maximum number.<br />
local start = glargs.start or 1<br />
if start > glargs.max then<br />
return '<span class="error">Start value "' <br />
.. tostring( start ) <br />
.. '" is greater than the most recent archive number "' <br />
.. tostring( glargs.max ) <br />
.. '".</span>'<br />
end<br />
local linkPrefix = glargs.linkPrefix or ''<br />
local lineNum = glargs.lineNum or 10<br />
local sep = '' -- Long default separator is cell elements, short is ', '<br />
local lineSep = '' -- Long default linebreak is row elements short is '\n'<br />
if glargs.isLong==true then <br />
sep = glargs.sep or ''<br />
sep = sep .. '</td><td>'<br />
lineSep = glargs.lineSep or ''<br />
lineSep = lineSep .. '</td></tr><tr><td>'<br />
else<br />
sep = glargs.sep or mw.message.new( 'comma-separator' ):plain()<br />
lineSep = glargs.lineSep or '<br />'<br />
end<br />
-- Generate the archive links.<br />
local lineCounter = 1 -- The counter to see whether we need a line break or not.<br />
local ret = {} -- A table containing the strings to be returned.<br />
if glargs.isLong == true then --Long version is a table<br />
table.insert(ret, "<table style=\"width: 100%; padding: 0px; text-align: center; background-color: transparent;\"><tr><td>")<br />
end<br />
if glargs.leaveFirstCellBlank then <br />
-- An empty first cell aligns the first column on multiples of lineNum <br />
table.insert(ret, sep) <br />
lineCounter = lineCounter + 1<br />
end <br />
for archiveNum = start, glargs.max do<br />
local link = mw.ustring.format(<br />
'[[%s%s|%s%s]]',<br />
glargs.prefix, numToLetters(archiveNum), linkPrefix, numToLetters(archiveNum)<br />
)<br />
table.insert( ret, link )<br />
-- If we don't need a new line, output a comma. We don't need<br />
-- a comma after the last link. <br />
if lineCounter < lineNum and archiveNum < glargs.max then<br />
table.insert( ret, sep )<br />
lineCounter = lineCounter + 1<br />
-- Output new lines if needed. We don't need a new line after<br />
-- the last link.<br />
elseif lineCounter >= lineNum and archiveNum < glargs.max then<br />
table.insert( ret, lineSep )<br />
lineCounter = 1<br />
end<br />
end<br />
if glargs.isLong == true then --Long version is a table<br />
table.insert(ret, "</td></tr></table>")<br />
end<br />
return table.concat( ret )<br />
end<br />
<br />
-- Determine if format should be long<br />
local function findFormType( auto )<br />
if auto == nil or auto == '' then<br />
return false<br />
elseif auto == 'long' then<br />
return true<br />
else<br />
return false<br />
end<br />
end<br />
<br />
-- Get the archive data and pass it to generateLinks().<br />
local function _main( args )<br />
local isLong = findFormType( args.auto )<br />
local prefix = getPrefix( args.root, args.prefix, args.prefixspace )<br />
local lineNum = getLineNum( args.links, args.nobr, isLong )<br />
local linkPrefix = getLinkPrefix( args.linkprefix, args.linkprefixspace, isLong )<br />
local start = getStart( args.start )<br />
local max = getBiggestArchiveNum( prefix, start, args.max )<br />
local sep = getSeparator( args.sep )<br />
local lineSep = getSeparator( args.linesep )<br />
local leaveFirstCellBlank = getLeaveFirstCellBlank( args.leavefirstcellblank )<br />
local glargs = {<br />
start = start,<br />
max = max,<br />
prefix = prefix,<br />
linkPrefix = linkPrefix,<br />
isLong = isLong,<br />
sep = sep,<br />
lineNum = lineNum,<br />
lineSep = lineSep,<br />
leaveFirstCellBlank = leaveFirstCellBlank<br />
}<br />
return generateLinks( glargs )<br />
end<br />
<br />
-- A wrapper function to make getBiggestArchiveNum() available from<br />
-- #invoke.<br />
local function _count( args )<br />
local prefix = getPrefix( args.root, args.prefix, args.prefixspace )<br />
local archiveMax = getBiggestArchiveNum( prefix )<br />
return archiveMax<br />
end<br />
<br />
function makeWrapper( func )<br />
return function( frame )<br />
-- If we are being called from #invoke, get the args from #invoke<br />
-- if they exist, or else get the arguments passed to the parent<br />
-- frame. Otherwise, assume the arguments are being passed directly<br />
-- in from another module or from the debug console.<br />
local origArgs<br />
if frame == mw.getCurrentFrame() then<br />
origArgs = frame:getParent().args<br />
for k, v in pairs( frame.args ) do<br />
origArgs = frame.args<br />
break<br />
end<br />
else<br />
origArgs = frame<br />
end<br />
<br />
-- Ignore blank values for parameters other than "links",<br />
-- which functions differently depending on whether it is<br />
-- blank or absent.<br />
local args = {}<br />
for k, v in pairs( origArgs ) do<br />
if k == 'links' or v ~= '' then<br />
args[k] = v<br />
end<br />
end<br />
<br />
return func( args )<br />
end<br />
end<br />
<br />
return {<br />
main = makeWrapper( _main ),<br />
count = makeWrapper( _count )<br />
}</div>Terasail