Modul:Spisak arhiva

Izvor: Wikipedija
Prijeđi na navigaciju Prijeđi na pretragu

-- This module implements {{archive list}} in Lua, and adds a few
-- new features.

-- Process a numeric argument to make sure it is a positive
-- integer.
local function processNumArg( num )
    if num then
        num = tonumber( num )
        if type( num ) == 'number' then
            num = math.floor( num )
            if num >= 0 then
                return num
            end
        end
    end
    return nil
end

-- Checks whether a page exists, going through pcall
-- in case we are over the expensive function limit.
local function checkPageExists( title )
    if not title then
        error('Nije dostavljen naslov funkciji checkArchiveExists.', 2)
    end
    local noError, titleObject = pcall(mw.title.new, title)
    if not noError then
        -- If we are over the expensive function limit then assume
        -- that the page doesn't exist.
        return false
    else
        if titleObject then
            return titleObject.exists
        else
            return false -- Return false if given a bad title.
        end
    end
end

-- Checks every nth archive to see if it exists, and returns the
-- number of the first archive that doesn't exist. It is
-- necessary to do this in batches because each check is an
-- expensive function call, and we want to avoid making too many
-- of them so as not to go over the expensive function limit.
local function checkArchives( prefiks, n, pocetak )
    local i = pocetak
    local exists = true
    while exists do
        exists = checkPageExists( prefiks .. tostring( i ) )
        if exists then
            i = i + n
        end
    end
    return i
end

-- Return the biggest archive number, using checkArchives()
-- and starting in intervals of 1000. This should get us a
-- maximum of 500,000 possible archives before we hit the
-- expensive function limit.
local function getBiggestArchiveNum( prefiks, pocetak, kraj )
    -- Return the value for max if it is specified.
    kraj = processNumArg( kraj )
    if kraj then
        return kraj
    end
    
    -- Otherwise, detect the largest archive number.
    pocetak = pocetak or 1
    local check1000 = checkArchives( prefiks, 1000, pocetak )
    if check1000 == pocetak then
        return 0 -- Return 0 if no archives were found.
    end
    local check200 = checkArchives( prefiks, 200, check1000 - 1000 )
    local check50 = checkArchives( prefiks, 50, check200 - 200 )
    local check10 = checkArchives( prefiks, 10, check50 - 50 )
    local check1 = checkArchives( prefiks, 1, check10 - 10 )
    -- check1 is the first page that doesn't exist, so we want to
    -- subtract it by one to find the biggest existing archive.
    return check1 - 1
end

-- Get the archive link prefix (the title of the archive pages
-- minus the number).
local function getPrefix( osnova, prefiks, razmak_iza_prefiksa )
    local ret = osnova or mw.title.getCurrentTitle().prefixedText
    ret = ret .. '/'
    if prefiks then
        ret = ret .. prefiks
        if razmak_iza_prefiksa == 'da' then
            ret = ret .. ' '
        end
    else
        ret = ret .. 'Arhiva '
    end
    return ret
end

-- Get the number of archives to put on one line. Set to
-- math.huge if there should be no line breaks.
local function getLineNum( linkovi, bez_oznake_br, isLong )
    local linksToNum = tonumber( linkovi )
    local lineNum
    if bez_oznake_br == 'da' or (linkovi and not linksToNum) then
        lineNum = math.huge
    -- If links is a number, process it. Negative values and expressions
    -- such as links=8/2 produced some interesting values with the old
    -- template, but we will ignore those for simplicity.
    elseif type(linksToNum) == 'number' and linksToNum >= 0 then
        -- The old template rounded down decimals to the nearest integer.
        lineNum = math.floor( linksToNum )
        if lineNum == 0 then
            -- In the old template, values of links between 0 and 0.999
            -- suppressed line breaks.
            lineNum = math.huge
        end
    else
    	if isLong==true then
    		lineNum = 3 -- Default to 3 links on long
    	else
        	lineNum = 10 -- Default to 10 on short
        end
    end
    return lineNum
end

-- Gets the prefix to put before the archive links.
local function getLinkPrefix( prefiks, space, isLong )
    -- Get the link prefix.
    local ret = ''
    if isLong==true then ---- Default of old template for long is 'Archive '
    	if type(prefiks) == 'string' then
    		if prefiks == 'ne' then -- 'none' overrides to empty prefix
    			ret = ''
    		 else
    		 	ret = prefiks
    		 	if space == 'da' then
    		 		ret = ret .. ' '
    		 	end
		 	end
	 	else
	 		ret = 'Arhiva '
		end
	else --type is not long
		if type(prefiks) == 'string' then
        	ret = prefiks
        	if space == 'da' then
        	    ret = ret .. ' '
        	end
    	end
    end
    return ret
end

-- Get the number to start listing archives from.
local function getStart( pocetak )
    pocetak = processNumArg( pocetak )
    if pocetak then
        return pocetak
    else
        return 1
    end
end

-- Get whether to leave a blank cell in the first row and column 
-- If links start at 1, and lineNum is a round number, this aligns the first 
-- column to start on a multiple of lineNum, which may be a nice round number 
local function getLeaveFirstCellBlank( prazna_prva_celija ) 
    return prazna_prva_celija == 'da' 
       or prazna_prva_celija == 'd' 
       or prazna_prva_celija == 1 
end

-- Process the separator parameter.
local function getSeparator( razdjelnik )
    if razdjelnik and type(razdjelnik) == 'string' then
        if razdjelnik == 'dot' 
            or razdjelnik =='pipe'
            or razdjelnik == 'comma'
            or razdjelnik == 'tpt-languages' then
            return mw.message.new( razdjelnik .. '-separator' ):plain()
        else
            return razdjelnik
        end
    else
        return nil
    end
end

-- Generates the list of archive links. glargs.max must be either zero (for
-- no archives) or a positive integer value.
local function generateLinks( glargs )
    if type( glargs ) ~= 'table' or not glargs.kraj or not glargs.prefiks then
        error('Nije dostavljeno dovoljno argumenata funkciji  generateLinks.', 2)
    end
    -- If there are no archives yet, return a message and a
    -- link to create Archive one.
    if glargs.kraj == 0 then
    	if glargs.isLong == true then
    		glargs.kraj = 1 -- One archive redlink is displayed for Long format
    	else -- Short error and a creat link is displayed for short
        	return 'Još nema arhiva ([[' .. glargs.prefiks .. '1|napravi]])'
        end
    end
    -- Return an html error if the start number is greater than the 
    -- maximum number.
    local pocetak = glargs.pocetak or 1
    if pocetak > glargs.kraj then
        return '<span class="error">Početna vrijednost „' 
            .. tostring( pocetak ) 
            .. '” veća je od posljednjeg arhivskog broja „' 
            .. tostring( glargs.kraj ) 
            .. '”.</span>'
    end
    local prefiks_linka = glargs.prefiks_linka or ''
        local lineNum = glargs.lineNum or 10
    local razdjelnik = '' -- Long default separator is cell elements, short is ', '
    local razdjelnik_redova = '' -- Long default linebreak is row elements short is '\n'
    if glargs.isLong==true then 
    	razdjelnik = glargs.razdjelnik or ''
    	razdjelnik = razdjelnik .. '</td><td>'
    	razdjelnik_redova = glargs.razdjelnik_redova or ''
		razdjelnik_redova = razdjelnik_redova .. '</td></tr><tr><td>'
    else
    	razdjelnik = glargs.razdjelnik or mw.message.new( 'comma-separator' ):plain()
    	razdjelnik_redova = glargs.razdjelnik_redova or '<br />'
    end
    -- Generate the archive links.
    local lineCounter = 1 -- The counter to see whether we need a line break or not.
    local ret = {} -- A table containing the strings to be returned.
    if glargs.isLong == true then --Long version is a table
    	table.insert(ret, "<table style=\"width: 100%; padding: 0px; text-align: center; background-color: transparent;\"><tr><td>")
    end
    if glargs.prazna_prva_celija then 
       -- An empty first cell aligns the first column on multiples of lineNum 
       table.insert(ret, razdjelnik) 
       lineCounter = lineCounter + 1
    end 
    for archiveNum = pocetak, glargs.kraj do
        local link = mw.ustring.format(
            '[[%s%d|%s%d]]',
            glargs.prefiks, archiveNum, prefiks_linka, archiveNum
        )
        table.insert( ret, link )
        -- If we don't need a new line, output a comma. We don't need
        -- a comma after the last link. 
        if lineCounter < lineNum and archiveNum < glargs.kraj then
            table.insert( ret, razdjelnik )
            lineCounter = lineCounter + 1
        -- Output new lines if needed. We don't need a new line after
        -- the last link.
        elseif lineCounter >= lineNum and archiveNum < glargs.kraj then
            table.insert( ret, razdjelnik_redova )
            lineCounter = 1
        end
    end
    if glargs.isLong == true then --Long version is a table
    	table.insert(ret, "</td></tr></table>")
    end
    return table.concat( ret )
end

-- Determine if format should be long
local function findFormType( automatski )
	if automatski == nil or automatski == '' then
		return false
	elseif automatski == 'dugo' then
			return true
	else
		return false
	end
end

-- Get the archive data and pass it to generateLinks().
local function _glavno( args )
	local isLong = findFormType( args.automatski )
    local prefiks = getPrefix( args.osnova, args.prefiks, args.razmak_iza_prefiksa )
    local lineNum = getLineNum( args.linkovi, args.bez_oznake_br, isLong )
    local prefiks_linka = getLinkPrefix( args.prefiks_linka, args.razmak_iza_prefiksa_linka, isLong )
    local pocetak = getStart( args['početak'] )
    local kraj = getBiggestArchiveNum( prefiks, pocetak, args.kraj )
    local razdjelnik = getSeparator( args.razdjelnik )
    local razdjelnik_redova = getSeparator( args.razdjelnik_redova )
    local prazna_prva_celija = getLeaveFirstCellBlank( args['prazna_prva_ćelija'] )
    local glargs = {
        pocetak = pocetak,
        kraj = kraj,
        prefiks = prefiks,
        prefiks_linka = prefiks_linka,
        isLong = isLong,
        razdjelnik = razdjelnik,
        lineNum = lineNum,
        razdjelnik_redova = razdjelnik_redova,
        prazna_prva_celija = prazna_prva_celija
    }
    return generateLinks( glargs )
end

-- A wrapper function to make getBiggestArchiveNum() available from
-- #invoke.
local function _brojac( args )
    local prefiks = getPrefix( args.osnova, args.prefiks, args.razmak_iza_prefiksa )
    local archiveMax = getBiggestArchiveNum( prefiks )
    return archiveMax
end

function makeWrapper( func )
    return function( frame )
        -- If we are being called from #invoke, get the args from #invoke
        -- if they exist, or else get the arguments passed to the parent
        -- frame. Otherwise, assume the arguments are being passed directly
        -- in from another module or from the debug console.
        local origArgs
        if frame == mw.getCurrentFrame() then
            origArgs = frame:getParent().args
            for k, v in pairs( frame.args ) do
                origArgs = frame.args
                break
            end
        else
            origArgs = frame
        end
        
        -- Ignore blank values for parameters other than "links",
        -- which functions differently depending on whether it is
        -- blank or absent.
        local args = {}
        for k, v in pairs( origArgs ) do
            if k == 'linkovi' or v ~= '' then
                args[k] = v
            end
        end
        
        return func( args )
    end
end

return {
    glavno = makeWrapper( _glavno ),
    ['brojač'] = makeWrapper( _brojac )
}