Модуль:Песочница/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]', {
['['] = '[',
[']'] = ']',
['\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 = ' = ' .. dotEnd( Original )
end
-- Автор_Издания и Издание --
if is_set(Author_Publication) and is_set(Publication) then
Publication = " // <i>" .. dotEnd( Author_Publication ) .. "</i>. " .. dotEnd( Publication )
elseif not is_set(Author_Publication) and is_set(Publication) then
Publication = " // " .. dotEnd( Publication )
elseif is_set(Author_Publication) and not is_set(Publication) then
Publication = " // <i>" .. Author_Publication .. "/<i>."
else
Publication = '';
end
-- Тип --
if is_set(Type) then
Type = " : " .. dotEnd( Type )
end
-- Ответственный --
if is_set(Responsible) then
Responsible = "  / " .. 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 = " — " .. Place .. ": " .. Publishing_house .. ", " .. Year .. "."
elseif is_set(Place) and is_set(Publishing_house) and not is_set(Year) then
Place_Year = " — " .. Place .. ": " .. Publishing_house .. "."
elseif is_set(Place) and not is_set(Publishing_house) and is_set(Year) then
Place_Year = " — " .. Place .. ", " .. Year .. "."
elseif not is_set(Place) and is_set(Publishing_house) and is_set(Year) then
Place_Year = " — " .. Publishing_house .. ", " .. Year .. "."
elseif is_set(Place) and not is_set(Publishing_house) and not is_set(Year) then
Place_Year = " — " .. Place .. "."
elseif not is_set(Place) and is_set(Publishing_house) and not is_set(Year) then
Place_Year = " — " .. Publishing_house .. "."
elseif not is_set(Place) and not is_set(Publishing_house) and is_set(Year) then
Place_Year = " — " .. 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