Модуль:Добротные статьи

Материал из Википедии — свободной энциклопедии
Перейти к навигации Перейти к поиску
Документация
local p = {}

local statusInProgress = "inprogress"
local statusAccepted = "accepted"
local statusDeclined = "declined"
local prefix = 'Википедия:Кандидаты в добротные статьи/'
local htmlImageYes = '[[File:Yes_check.svg|15px|✔|link=]]';
local htmlImageNo = '[[File:Red x.svg|16px|link=|×]]';

function pairsByKeys (t, f)
	local a = {}
	for n in pairs(t) do table.insert(a, n) end
		table.sort(a, f)
		local i = 0
		local iter = function ()
			i = i + 1
			if a[i] == nil then
				return nil
			else
				return a[i], t[a[i]]
		end
	end
	return iter
end

function starts( src, template )
   return string.sub( src, 1, string.len(template) ) == template;
end

function p.formatList( frame )
	local parentArgs = frame:getParent().args
	local list = parentArgs.list;
	if (list == nil) then
		return 'no list passed'
	end

	if ( starts( list, '[[:Википедия:Добротные статьи/Список/' ) ) then
		return ''
	end

	return p.formatListImpl( list )
end

function p.formatListImpl( lines )
	local articles = {};
	while ( true ) do
		local nextBreak = mw.ustring.find ( lines, '\n', start, true)
		local line;
		if ( nextBreak == nil ) then
			line = mw.ustring.sub ( lines, start )
		else
			line = mw.ustring.sub ( lines, start, nextBreak - 1 )
		end
		table.insert( articles, line );
		if ( nextBreak == nil ) then
			break
		end
		start = nextBreak + 1
	end
	table.sort( articles );
	local result = ''
	for i, articleLink in pairsByKeys( articles ) do 
		if ( i == 1 ) then
			result = articleLink
		else
			result = result .. ' • ' .. articleLink .. ''
		end
	end
	return result;
end

function p.formatTable( frame )
	local parentArgs = frame:getParent().args
	local list = parentArgs.list;
	if (list == nil) then
		return 'no list passed'
	end
	local strike = parentArgs.strike ~= "0" and parentArgs.strike ~= "false";

	return p.formatTableImpl( list, strike )
end

function p.formatTableImpl( lines, strike )
	local start = 1;
	local groupByDate = {};
	local datesArray = {};
	local nowDateStr = nowDateString()

	while ( true ) do
		local nextBreak = mw.ustring.find ( lines, '\n', start, true)
		local line;
		if ( nextBreak == nil ) then
			line =  mw.ustring.sub ( lines, start )
		else
			line = mw.ustring.sub ( lines, start, nextBreak - 1 )
		end
		processLine ( datesArray, groupByDate, line );
		if ( nextBreak == nil ) then
			break
		end
		start = nextBreak + 1
	end

	local result = '{| class="wikitable" |\r\n' .. '|-\r\n' .. '! Начало обсуждения \r\n'.. '! Список кандидатов \r\n'
	for i, dateString in ipairs( datesArray ) do
		dateGroup = groupByDate[dateString]

		local list = ''
		local hasUnfinished = false;
		for articleTitle, articleStatus in pairsByKeys( dateGroup ) do 
			if ( articleStatus == statusInProgress ) then
				hasUnfinished = true;
				local item = '[[' .. articleTitle .. ']] [[' .. prefix .. dateString .. '#' .. articleTitle .. '|(обс.)]]';
				list = list .. ' <span style="white-space:nowrap;">' .. item .. '</span> • '
			end
		end
		for articleTitle, articleStatus in pairsByKeys( dateGroup ) do 
			local item = '[[' .. articleTitle .. ']] [[' .. prefix .. dateString .. '#' .. articleTitle .. '|(обс.)]]';
			
			if ( strike ) then
				if ( articleStatus == statusAccepted ) then
					list = list .. ' <span style="white-space:nowrap;">' .. htmlImageYes .. ' <s>' .. item .. '</s></span> • '
				end
				if ( articleStatus == statusDeclined ) then
					list = list .. ' <span style="white-space:nowrap;">' .. htmlImageNo .. ' <s>' .. item .. '</s></span> • '
				end
			else
				if ( articleStatus == statusAccepted ) then
					list = list .. ' <span style="white-space:nowrap;">' .. htmlImageYes .. ' ' .. item .. '</span> • '
				end
				if ( articleStatus == statusDeclined ) then
					list = list .. ' <span style="white-space:nowrap;">' .. htmlImageNo .. ' ' .. item .. '</span> • '
				end
			end
		end
		result = result .. '|-\r\n' .. '| style="white-space:nowrap;" | [[' .. prefix .. dateString .. '|' .. dateString .. ']]'
		if (not hasUnfinished and strike and dateString ~= nowDateStr) then
			result = result .. '<span class="ruWikiQualityCandatatesToArchivButton" data-date="'.. dateString ..'">&nbsp;</span>'
		end
		result = result .. '\r\n| ' .. list
		result = result .. '\r\n'
	end
	result = result .. '|}\r\n'
	return result;
end

function processLine ( datesArray, groupByDate, line )
	local break1 = mw.ustring.find ( line, '|', 1, true)
	if ( break1 == nil ) then
		-- error
		return
	end
	local break2 = mw.ustring.find ( line, '|', break1 + 1, true)
	if ( break2 == nil ) then
		-- error
		return
	end
	local dateString = mw.ustring.sub ( line, 1, break1 - 1 );
	local articleTitle = mw.ustring.sub ( line, break1 + 1, break2 - 1 );
	local articleStatus = mw.ustring.sub ( line, break2 + 1 );

	if ( groupByDate[ dateString ] ) then
		local existedGroup = groupByDate[ dateString ];
		existedGroup [ articleTitle ] = articleStatus;
	else
		local newGroup = {};
		newGroup[ articleTitle ] = articleStatus;
		groupByDate[ dateString ] = newGroup;
		datesArray[#datesArray + 1] = dateString
	end
end

local genitivusMonths = {'января', 'февраля', 'марта', 'апреля', 'мая', 'июня',
    'июля', 'августа', 'сентября', 'октября', 'ноября', 'декабря'}

-- TODO: Move it to [[Модуль:Dates]]
function nowDateString()
	local t = os.date("*t")
	local nd = t.day;
	local nm = t.month;
	local ny = t.year;
	return string.format( "%d %s %d", nd, genitivusMonths[nm], ny)
end

return p