https://en.wikipedia.org/w/index.php?action=history&feed=atom&title=Module%3AArchive_list_alpha Module:Archive list alpha - Revision history 2025-05-27T19:53:35Z Revision history for this page on the wiki MediaWiki 1.45.0-wmf.2 https://en.wikipedia.org/w/index.php?title=Module:Archive_list_alpha&diff=1115482690&oldid=prev MusikBot 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 &quot;<a href="/wiki/Module:Archive_list_alpha" title="Module:Archive list alpha">Module:Archive list alpha</a>&quot;: <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 II https://en.wikipedia.org/w/index.php?title=Module:Archive_list_alpha&diff=1115473344&oldid=prev Terasail: Create from Module:Archive list 2022-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(&#039;A&#039;) + modVal)<br /> if newInt &gt;= 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 ) == &#039;number&#039; then<br /> num = math.floor( num )<br /> if num &gt;= 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(&#039;No title passed to checkArchiveExists&#039;, 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&#039;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&#039;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&#039;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 .. &#039;/&#039;<br /> if prefix then<br /> ret = ret .. prefix<br /> if prefixSpace == &#039;yes&#039; then<br /> ret = ret .. &#039; &#039;<br /> end<br /> else<br /> ret = ret .. &#039;Archive &#039;<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 == &#039;yes&#039; 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) == &#039;number&#039; and linksToNum &gt;= 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 = &#039;&#039;<br /> if isLong==true then ---- Default of old template for long is &#039;Archive &#039;<br /> if type(prefix) == &#039;string&#039; then<br /> if prefix == &#039;none&#039; then -- &#039;none&#039; overrides to empty prefix<br /> ret = &#039;&#039;<br /> else<br /> ret = prefix<br /> if space == &#039;yes&#039; then<br /> ret = ret .. &#039; &#039;<br /> end<br /> end<br /> else<br /> ret = &#039;Archive &#039;<br /> end<br /> else --type is not long<br /> if type(prefix) == &#039;string&#039; then<br /> ret = prefix<br /> if space == &#039;yes&#039; then<br /> ret = ret .. &#039; &#039;<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 == &#039;yes&#039; <br /> or leaveFirstCellBlank == &#039;y&#039; <br /> or leaveFirstCellBlank == 1 <br /> end<br /> <br /> -- Process the separator parameter.<br /> local function getSeparator( sep )<br /> if sep and type(sep) == &#039;string&#039; then<br /> if sep == &#039;dot&#039; <br /> or sep ==&#039;pipe&#039;<br /> or sep == &#039;comma&#039;<br /> or sep == &#039;tpt-languages&#039; then<br /> return mw.message.new( sep .. &#039;-separator&#039; ):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 ) ~= &#039;table&#039; or not glargs.max or not glargs.prefix then<br /> error(&#039;insufficient arguments passed to generateLinks&#039;, 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 &#039;no archives yet ([[&#039; .. glargs.prefix .. &#039;1|create]])&#039;<br /> return &#039;no archives yet ([[&#039; .. glargs.prefix .. &#039;A|create]])&#039;<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 &gt; glargs.max then<br /> return &#039;&lt;span class=&quot;error&quot;&gt;Start value &quot;&#039; <br /> .. tostring( start ) <br /> .. &#039;&quot; is greater than the most recent archive number &quot;&#039; <br /> .. tostring( glargs.max ) <br /> .. &#039;&quot;.&lt;/span&gt;&#039;<br /> end<br /> local linkPrefix = glargs.linkPrefix or &#039;&#039;<br /> local lineNum = glargs.lineNum or 10<br /> local sep = &#039;&#039; -- Long default separator is cell elements, short is &#039;, &#039;<br /> local lineSep = &#039;&#039; -- Long default linebreak is row elements short is &#039;\n&#039;<br /> if glargs.isLong==true then <br /> sep = glargs.sep or &#039;&#039;<br /> sep = sep .. &#039;&lt;/td&gt;&lt;td&gt;&#039;<br /> lineSep = glargs.lineSep or &#039;&#039;<br /> lineSep = lineSep .. &#039;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&#039;<br /> else<br /> sep = glargs.sep or mw.message.new( &#039;comma-separator&#039; ):plain()<br /> lineSep = glargs.lineSep or &#039;&lt;br /&gt;&#039;<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, &quot;&lt;table style=\&quot;width: 100%; padding: 0px; text-align: center; background-color: transparent;\&quot;&gt;&lt;tr&gt;&lt;td&gt;&quot;)<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 /> &#039;[[%s%s|%s%s]]&#039;,<br /> glargs.prefix, numToLetters(archiveNum), linkPrefix, numToLetters(archiveNum)<br /> )<br /> table.insert( ret, link )<br /> -- If we don&#039;t need a new line, output a comma. We don&#039;t need<br /> -- a comma after the last link. <br /> if lineCounter &lt; lineNum and archiveNum &lt; glargs.max then<br /> table.insert( ret, sep )<br /> lineCounter = lineCounter + 1<br /> -- Output new lines if needed. We don&#039;t need a new line after<br /> -- the last link.<br /> elseif lineCounter &gt;= lineNum and archiveNum &lt; 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, &quot;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&quot;)<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 == &#039;&#039; then<br /> return false<br /> elseif auto == &#039;long&#039; 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 &quot;links&quot;,<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 == &#039;links&#039; or v ~= &#039;&#039; 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