Модуль:Песочница/Karibekov Vladislav Y./author

Материал из Википедии — свободной энциклопедии
Перейти к навигации Перейти к поиску
Документация
local q = {
	error_categories = {};		
	error_ids = {};
	message_tail = {};
	maintenance_cats = {};		
	properties_cats = {};
}

--[[--  ----  --]]-- 

--[[ 
  Создает сообщение. См. <Extension:Scribunto/Lua_reference_manual/ru#mw.message>
]]
function substitute( msg, args )
	return args and mw.message.newRawMessage( msg, args ):plain() or msg;
end

--[[ 
  Проверяет существование переменной
]]
function is_set( var )
	return not (var == nil or var == '');
end

--[[ 
  Проверяет наличие <needle> в массиве <haystack>. В случае нахождения, возвращает ключ элемента.
]]
function inArray( needle, haystack )
	if needle == nil then
		return false;
	end
	for n,v in ipairs( haystack ) do
		if v == needle then
			return n;
		end
	end
	return false;
end

--[[ 
  Проверяет есть ли точка в конце строки <str>. Если есть – отсекает
]]
function dotEnd( str )
	if (str==nil or str=='') then return false; end 
	if string.sub( mw.text.trim( str ), -1 ) == '.' then
		str = string.sub( str, 1, -2);
	end
	return str;
end

--[[ 
  Проверяет ссылку на "битость"
]]
function checkurl( url_str )
	return url_str:sub(1,2) == "//" or url_str:match( "^[^/]*:" ) ~= nil;
end

--[[ 
  Проверяет имя ссылки на "битость"
]]
function safeforurl( str )
	if str:match( "%[%[.-%]%]" ) ~= nil then 
		--[[ Если <str> содержит викиссылку, то выдаем ошибку ]]
		table.insert( q.message_tail, { seterror( 'wikilink_in_url', {}, true ) } );			
	end
		--[[ Заменяем скобки на HTML-код ]]
	return str:gsub( '[%[%]\n]', {	
		['['] = '&#91;',
		[']'] = '&#93;',
		['\n'] = ' ' } );
end

--[[ 
  Формирует внешнюю / внутренюю ссылку
]]
function externallink( URL, label, args )
	if not is_set( label ) then
		label = URL;
		error( cfg.messages["bare_url_no_origin"] ); -- URL без названия
	end
	if not checkurl( URL ) then
		error_str = seterror( 'bad_url', {args}, false, " " ); -- битый URL
	end
	return table.concat({ "[", URL, " ", safeforurl( label ), "]", error_str });	
end

--[[ 
  Формирует имя места по сокращению
]]
function indication_place( place )
 
	local place = mw.text.trim(place);
	local flag = whitelist.place_arguments[place];
 
	if is_set(flag) then 
		place = '<span style="border-bottom:1px dotted gray; cursor:default;" title="' .. flag .. '">' .. place .. '</span>'
	end
 
	return place
end

--[[ 
  Проверяет существование параметра <name> по базе <Whitelist>
]]
 function validate( name )
	local name = tostring( name );
	local state = whitelist.basic_arguments[ name ];
 
	if true == state then return true; end		
	if false == state then
		deprecated_parameter (); 		
		return true;
	end
 
	return false;							
end

--[[ 
  Выдает ошибку для устаревшего параметра
]]
function deprecated_parameter()
	if true ~= Page_in_deprecated_cat then
		Page_in_deprecated_cat=true;	
		table.insert( q.message_tail, { seterror( 'deprecated_params', {}, true ) } );
	end
end

--[[ 
  Генерирует текст ошибки в таблицу. Работает с таблицей <error_conditions>. Параметры:
  
  <error_id> - "имя ошибки" в таблице <error_conditions>
  <arguments> - 
  <raw> - 
  <prefix> - 
  <suffix> - 
  
]]
function seterror( error_id, arguments, raw, prefix, suffix )
	local error_state=cfg.error_conditions[ error_id ];
 
	prefix = prefix or "";
	suffix = suffix or "";
 
	if error_state == nil then
		error( cfg.messages['undefined_error'] ); -- Неизвестная ошибка
	elseif is_set( error_state.category ) then
		table.insert( q.error_categories, error_state.category ); -- Добавление скрытой категории ошибок
	end
 
	local message = substitute( error_state.message, arguments ); -- Создает сообщение
 
	message = message .. " ([[" .. cfg.messages['help page link'] .. 
		"#" .. error_state.anchor .. "|" ..
		cfg.messages['help page label'] .. "]])";
 
	q.error_ids[ error_id ] = true;
	
	--[[ Если ошибка URL заголовка или ошибка имени заголовка, или же если ошибка заголовка 
	     уже была обнаружена то пропускаем обработку ошибки ]]
	if inArray( error_id, { 'bare_url_missing_title', 'trans_missing_title' } )
			and q.error_ids['citation_missing_title'] then
		return '', false;
	end
 
	message = table.concat({ prefix, message, suffix }); -- Формируем окончательное сообщение об ошибке
 
	if raw == true then
		return message, error_state.hidden; -- Возвращаем сообщение в двух переменных
	end		
 
	return errorcomment( message, error_state.hidden ); -- Выводим сообщение
end

--[[ 
  Формирует вывод ошибки в зависимости от параметра <hidden>. Использует таблицу <presentation>
]]
function errorcomment( content, hidden )
	return substitute( hidden and cfg.presentation['hidden-error'] or cfg.presentation['visible-error'], content );
end


--[[ 
  Выбирает нужный параметр из таблицы <aliases>.
]]
function selectone( args, possible, error_condition, index )
	local value = nil;
	local selected = '';
	local error_list = {};
 
	if index ~= nil then index = tostring(index); end
 
	if index == '1' then
		for _, v in ipairs( possible ) do
			v = v:gsub( "#", "" );
			if is_set(args[v]) then
				if value ~= nil and selected ~= v then
					table.insert( error_list, v );
				else
					value = args[v];
					selected = v;
				end
			end
		end		
	end
 
	for _, v in ipairs( possible ) do
		if index ~= nil then
			v = v:gsub( "#", index );
		end
		if is_set(args[v]) then
			if value ~= nil and selected ~=  v then
				table.insert( error_list, v );
			else
				value = args[v];
				selected = v;
			end
		end
	end
 
	if #error_list > 0 then
		local error_str = "";
		for _, k in ipairs( error_list ) do
			if error_str ~= "" then error_str = error_str .. cfg.messages['parameter-separator'] end
			error_str = error_str .. substitute( cfg.presentation['parameter'], {k} );
		end
		if #error_list > 1 then
			error_str = error_str .. cfg.messages['parameter-final-separator'];
		else
			error_str = error_str .. cfg.messages['parameter-pair-separator'];
		end
		error_str = error_str .. substitute( cfg.presentation['parameter'], {selected} );
		table.insert( q.message_tail, { seterror( error_condition, {error_str}, true ) } );
	end
 
	return value, selected;
end

--[[ 
  Формирует массив параметров, "запрошенных" в шаблоне. Работает с таблицами <aliases>, <messages> и <defaults>
]]
function argument_wrapper( args )
	local origin = {};
 
	return setmetatable({
		ORIGIN = function( self, k )
			local dummy = self[k];
			return origin[k];
		end
	},
	{
		__index = function ( tbl, k )
			if origin[k] ~= nil then
				return nil;
			end
 
			local args, list, v = args, cfg.aliases[k];
 
			if type( list ) == 'table' then
				v, origin[k] = selectone( args, list, 'redundant_parameters' );
				if origin[k] == nil then
					origin[k] = '';
				end
			elseif list ~= nil then
				v, origin[k] = args[list], list;
			else
				v, origin[k] = args[k], k;					   -- требо переделать
				error( cfg.messages['unknown_argument_map'] ); -- требо переделать
			end
 
			if v == nil then
				v = cfg.defaults[k] or '';
				origin[k] = '';
			end
 
			tbl = rawset( tbl, k, v );
			return v;
		end,
	});
end

--[[ ----------------------------------------------------------------------------- ]]

--[[--  Тело  --]]-- 
function q.telo( config, args )
	local Archive;
	local Band;
	local Lang;
	local Pages;
	local Place_Year;
	local Pre_Issue;
	local PPP;
	local Volume;
 
	local A = argument_wrapper( args ); -- Загружаем параметры
 
	local ArXiv = A['ArXiv'];
	local ArchiveDate = A['ArchiveDate'];
	local ArchiveURL = A['ArchiveURL'];
	local Authors = A['Authors'];
	local Author_Publication = A['Author_Publication'];
	local Band = A['Band'];
	local BIBCODE = A['BIBCODE'];
	local DOI = A['DOI'];
	local ISBN = A['ISBN'];
	local ISSN = A['ISSN'];
	local Issue = A['Issue'];
	local Language = A['Language'];
	local Limit_Authors = A['Limit_Authors'];
	local Original = A['Original'];
	local Pages_en = A['Pages_en'];
	local Pages_ru = A['Pages_ru'];
	local Pages_seite = A['Pages_seite'];
	local Place = A['Place'];
	local PMID = A['PMID'];
	local Publishing_house = A['Publishing_house'];
	local Publication = A['Publication'];
	local Ref = A['Ref'];
	local Responsible = A['Responsible'];
	local Separator = A['Separator'];
	local Title = A['Title'];
	local Type = A['Type'];
	local URL = A['URL'];
	local Volume_bd = A['Volume_bd'];
	local Volume_en = A['Volume_en'];
	local Volume_ru = A['Volume_ru'];
	local Year = A['Year'];
	
	-- Заголовок --
	if	not is_set(Title) then
		table.insert( q.message_tail, { seterror( 'citation_missing_title', {}, true ) } );
	end
	
	Title = dotEnd( Title );
	
	if is_set(Title) and is_set(URL) then 
		Title = externallink( URL, Title, 'url' );
	end
	
	-- Оригинал --
	if not is_set(Original) then
		Original = ""
	else
		Original = '&#32;= ' .. dotEnd( Original )		
	end
	
	-- Автор_Издания и Издание --
	if is_set(Author_Publication) and is_set(Publication) then
		Publication = "&#32;// <i>" .. dotEnd( Author_Publication ) .. "</i>. " .. dotEnd( Publication )
	elseif not is_set(Author_Publication) and is_set(Publication) then
		Publication = "&#32;// " .. dotEnd( Publication )
	elseif is_set(Author_Publication) and not is_set(Publication) then
		Publication = "&#32;// <i>" .. Author_Publication .. "/<i>."
	else
		Publication = '';
	end
	
	-- Тип --
	if is_set(Type) then
		Type = "&#32;: " .. dotEnd( Type )
	end
	
	-- Ответственный --
	if is_set(Responsible) then
		Responsible = "&#32; / " .. dotEnd( Responsible )
	end
	
	-- Проверка на необходимость в разделителе --
	if is_set(Original) or is_set(Author_Publication) or is_set(Publication) or is_set(Type) or is_set(Responsible) then
		PPP = '.'
	else 
		PPP = ''
	end
	
	-- Место, Издатель и Год --
	if is_set(Place) then
		Place = indication_place(Place);
	end
	
	if is_set(Place) and is_set(Publishing_house) and is_set(Year) then
		Place_Year = "&nbsp;— " .. Place .. ": " .. Publishing_house .. ", " .. Year .. "."
	elseif is_set(Place) and is_set(Publishing_house) and not is_set(Year) then
		Place_Year = "&nbsp;— " .. Place .. ": " .. Publishing_house .. "."
	elseif is_set(Place) and not is_set(Publishing_house) and is_set(Year) then
		Place_Year = "&nbsp;— " .. Place .. ", " .. Year .. "."
	elseif not is_set(Place) and is_set(Publishing_house) and is_set(Year) then
		Place_Year = "&nbsp;— " .. Publishing_house .. ", " .. Year .. "."
	elseif is_set(Place) and not is_set(Publishing_house) and not is_set(Year) then
		Place_Year = "&nbsp;— " .. Place .. "."
	elseif not is_set(Place) and is_set(Publishing_house) and not is_set(Year) then
		Place_Year = "&nbsp;— " .. Publishing_house .. "."
	elseif not is_set(Place) and not is_set(Publishing_house) and is_set(Year) then
		Place_Year = "&nbsp;— " .. Year .. "."
	else
		Place_Year = '';
	end
	
	text = '<span style="color:red">Это временный шаблон:</span><br/><span class="citation"'..Ref..'>' .. Authors .. ' ' .. Title .. ' ' .. Original..Publication..Type..Responsible..PPP..Place_Year..Volume_en..Band..Issue..Pages_en..ISBN..ISSN..DOI..BIBCODE..ArXiv..PMID..'</span>'
 
	if (text == ' ') then
		q.error_categories = {};
		text = seterror('empty_citation');
		q.message_tail = {};
	end
 
 
	if #q.message_tail ~= 0 then
		text = text .. " ";
		for i,v in ipairs( q.message_tail ) do
			if is_set(v[1]) then
				if i == #q.message_tail then
					text = text .. errorcomment( v[1], v[2] );
				else
					text = text .. errorcomment( v[1] .. "; ", v[2] );
				end
			end
		end
	end
 
	return text
	
 end
 
--[[--  Запуск  --]]-- 
function q.citation(frame)
	local pframe = frame:getParent()
 
	cfg = mw.loadData( 'Модуль:Песочница/Karibekov Vladislav Y./Configuration' );
	whitelist = mw.loadData( 'Модуль:Песочница/Karibekov Vladislav Y./Whitelist' );
	--dates = require('Модуль:Песочница/Karibekov Vladislav Y./Date_validation').dates
 
	local args = {};
	local config = {};
	local suggestions = {};
	local error_text, error_state;
 
	for k, v in pairs( frame.args ) do
		args[k] = v;
		config[k] = v;	
	end	
 
	for k, v in pairs( pframe.args ) do
		if v~='' then
			if not validate( k ) then
				error_text="Error";
				if type( k )~= 'string' then
					if v:match("%S+")~= nil then
						error_text, error_state = seterror( 'text_ignored', {v}, true );
					end
				else
					--[[ Пробуем исправить некорректные параметры по таблице <suggestions> ]]
					if #suggestions == 0 then
						suggestions = mw.loadData( 'Модуль:Песочница/Karibekov Vladislav Y./Suggestions' );
					end
					if suggestions[ k:lower() ] ~= nil then
						error_text, error_state = seterror( 'parameter_ignored_suggest', {k, suggestions[ k:lower() ]}, true );
					else
						error_text, error_state = seterror( 'parameter_ignored', {k}, true );
					end
				end
				if error_text ~= '' then
					table.insert( q.message_tail, {error_text, error_state} );
				end
			end	
			args[k]=v;
		elseif args[k]~=nil or ( k == 'et al') then -- Надо довести до ума... --
			args[k] = v;
		end
	end
 
	return q.telo( config, args )
 
end
 
return q