Mine sisu juurde

Modul':CiteWeb

Мегавики-späi

local p = {};

require('strict'); local listRef = require('Module:Languages').list_ref; local boxDate = require('Module:Calendar').bxDate;

local error_cats = {

   ['noname_param'] = 'Kategorii:RUWIKI:Cite web (некорректное использование: непустой неименованный параметр)',
   ['empty_title'] = 'Kategorii:RUWIKI:Cite web (некорректное использование: не указан title)',
   ['empty_url'] = 'Kategorii:RUWIKI:Cite web (некорректное использование: не указан url)',
   ['bad_archive'] = 'Kategorii:RUWIKI:Cite web (некорректное использование: параметры архивации)',
   ['deadlink'] = 'Kategorii:RUWIKI:Cite web (недоступные ссылки без архивной копии)',
   -- ['bad_lang'] = 'Kategorii:RUWIKI:Cite web (неверный код языка)',
   ['empty_lang'] = 'Kategorii:RUWIKI:Cite web (не указан язык)',
   ['bad_url'] = 'Kategorii:RUWIKI:Cite web (некорректный url)',
   ['webcitation_no'] = 'Kategorii:RUWIKI:Cite web (заменить webcitation-архив: deadlink no)',
   ['webcitation_yes'] = 'Kategorii:RUWIKI:Cite web (заменить webcitation-архив: deadlink yes)',

} local errors = {

   ['noname_param'] = 'Skriptitõrge: Moodulit "Error" pole.',
   ['empty_title'] = 'Skriptitõrge: Moodulit "Error" pole.',
   ['empty_url'] = 'Skriptitõrge: Moodulit "Error" pole.',
   ['bad_archive'] = 'Skriptitõrge: Moodulit "Error" pole.',

} local replace_params = {

   ['accessdate'] = 'access-date',
   ['archivedate'] = 'archive-date',
   ['archiveurl'] = 'archive-url',
   ['authorlink'] = 'author-link',
   ['first1'] = 'first',
   ['last1'] = 'last',
   ['deadurl'] = 'deadlink',
   ['dead-url'] = 'deadlink',
   ['language'] = 'lang',
   ['datepublished'] = 'date',
   ['work'] = 'website',

}

-- проверка существования переменной. возврат её, или nil если пустая local function is(var)

   if (var ==  or var == nil) then return nil else return var end

end

-- замена устаревших аргументов на их аналоги local function prepareArgs(args)

   local bad_args = {};
   local new_args = {};
   for param, value in pairs(args) do
       if is(replace_params[param]) and not is(args[replace_params[param]]) then
           param = replace_params[param];
       end
       new_args[param] = value;
   end
   return new_args, bad_args

end

-- добавление скрытого языка local function hiddenRef(code)

   return ''

end

local function insertDot(str, small, insert)

   if insert == false then
       return
   end
   if small then
       table.insert(str, '.')
   else
       table.insert(str, '.')
   end

end

local function needDot(source_str)

   if mw.ustring.find(source_str, '[.?!:…]»?$') ~= nil then
       return false
   else
       return true
   end

end

local function nowiki(text)

   local frame = mw.getCurrentFrame();
   return frame:callParserFunction('#tag', { 'nowiki', text })

end

local function replace(source_str, pattern, replace)

   return mw.ustring.gsub(source_str, pattern, replace)

end

-- форматирование даты; в случае ошибки - возврат переданного значения без изменений local function formatDate(strFormat, txtDateIn, params)

   local txtDateOut, date, status = boxDate(txtDateIn, strFormat, params)
   if status.brk then
       return txtDateIn
   else
       return txtDateOut
   end

end

-- отрисовка ошибки по коду local function expandError(code)

   return mw.getCurrentFrame():preprocess(errors[code]) .. ' '

end

-- отрисовка всех категорий по их кодам local function expandCats(cats)

   local str = {};
   local frame = mw.getCurrentFrame();
   for _, cat in pairs(cats) do
       table.insert(str, '[[' .. error_cats[cat] .. ']]')
   end
   return frame:preprocess(table.concat(str))

end

-- разделение их local function splitBySlash(string)

   local args = {};
   local iterator = mw.ustring.gmatch(string, "[^/]+");
   for w in iterator do
       table.insert(args, w)
   end
   return args

end

-- оборачиваем главную ссылку в span с указанным языком (может быть полезно для rtl) local function wrapLang(link, langs)

   local lang_code = 'und';
   if is(langs) then
       local args = splitBySlash(langs);
       if #args ~= 0 then
           lang_code = args[1];
       end
   end
   return '' .. link .. ''

end

-- обёртка в тег цитирования local function wrapCite(str, args)

   if is(args['ref']) then
       table.insert(str, 1, '');
       if is(args['date']) then
           table.insert(str, 2,
               '');
           table.insert(str, '');
       end
   else
       table.insert(str, 1, '');
   end
   table.insert(str, '');

end

-- генерирум список языков (аргумент - список языков через слеш) local function refLang(lang)

   local args = splitBySlash(lang);
   local frame = mw.getCurrentFrame();
   frame.args = args
   local lang_result = listRef(frame)
   local hidden = false;
   if #args == 1 and args[1] == 'ru' then
       hidden = true;
   end
   return lang_result, hidden

end

function p.render(frame)

   local str = {}
   local cats = {}
   local pFrame = frame:getParent();
   local args = mw.clone(pFrame.args);
   setmetatable(args, nil);
   args = prepareArgs(args);
   -- Проверки
   -- Проверка отсутствия неименованных параметров
   if is(args[1]) then
       table.insert(str, expandError('noname_param'));
       table.insert(cats, 'noname_param');
   end
   -- Проверка корректности заполнения параметров archiveurl и archivedate
   if (is(args['archive-date']) ~= nil and is(args['archive-url']) == nil) or
       (is(args['archive-date']) == nil and is(args['archive-url']) ~= nil) then
       table.insert(str, expandError('bad_archive'));
       table.insert(cats, 'bad_archive');
   end
   local urlstatus = 'dead';
   if args['deadlink'] == nil or args['deadlink'] ==  or args['deadlink'] == 'no' then
       urlstatus = 'live';
   end
   if is(args['archive-url']) then
       if mw.ustring.find(args['archive-url'], 'webcitation.org', 1, true) then
           if urlstatus == 'dead' then
               urlstatus = 'webcite_dead'
               table.insert(cats, 'webcitation_yes')
           else
               table.insert(cats, 'webcitation_no')
           end
       end
   else
       if urlstatus == 'dead' then
           table.insert(cats, 'deadlink')
       end
   end
   -- Проверка заполнения параметра url
   if is(args['url']) then
       if mw.ustring.find(args['url'], '^https?://', 1, false) ~= 1 and
           mw.ustring.find(args['url'], '^ftp://', 1, false) ~= 1 or mw.ustring.find(args['url'], ' ', 1, true) ~= nil then
           table.insert(cats, 'bad_url')
       end
   else
       table.insert(str, expandError('empty_url'));
       table.insert(cats, 'empty_url')
   end
   -- Проверка заполнения параметра title
   if not is(args['title']) then
       table.insert(str, expandError('empty_title'));
       table.insert(cats, 'empty_title')
   else
       if not is(args['lang']) and mw.ustring.find(args['title'], '^[0-9А-яЁё«»:;,…!?  %(%)%.—№%/%&%#+-]+$') == nil then
       	table.insert(cats, 'empty_lang')
   	end
   end
   -- Формирование вывода
   -- Автор
   if is(args['author']) or is(args['last']) then
       table.insert(str, '')
       local author = args['author'];
       if is(args['last']) then
           author = args['last']
           if is(args['first']) then
               author = author .. ', ' .. args['first']
           end
       elseif not is(args['last2']) and not is(args['coauthors']) then
           author = replace(author, '^(%[*)(.-[^%.%]])(%]*)$', '%1%2%3.')
       end
       if is(args['author-link']) then
           table.insert(str, '[[' .. args['author-link'] .. '|' .. author .. "]]")
       else
           table.insert(str, author)
       end
       -- Дополнительные сведения об авторах
       for i = 2, 5 do
           if is(args['last' .. i]) then
               local author = nowiki(';') .. ' ' .. args['last' .. i];
               if is(args['first' .. i]) then
                   author = author .. ', ' .. args['first' .. i]
               end
               table.insert(str, author)
           end
       end
       if is(args['coauthors']) then
           table.insert(str, nowiki(';') .. ' ' .. replace(args['coauthors'], '^(.-)%.?$', '%1.') .. ': ')
       end
       table.insert(str, ' ')
   end
   -- Редактор
   if is(args['editor']) then
       table.insert(str, ' ' .. args['editor'] .. ': ')
   end
   -- URL, заголовок
   local link;
   local title = replace(replace(args['title'] or , '%[', '['), '%]', ']');
   local dot = needDot(title);
   if urlstatus == 'dead' and is(args['archive-url']) then
       link = '[' .. (args['archive-url'] or ) .. ' ' .. title .. ']'
   else
       link = '[' .. (args['url'] or ) .. ' ' .. title .. ']'
   end
   table.insert(str, wrapLang(link, args['lang']))
   -- Подзаголовок
   if is(args['subtitle']) then
       insertDot(str, false, dot)
       table.insert(str, ' ' .. args['subtitle'] .. '')
       dot = needDot(args['subtitle']);
   end
   -- Отображение названия языка источника
   local langs;
   local hidden = false;
   if is(args['lang']) then
       langs, hidden = refLang(args['lang']);
   else
       langs = frame:expandTemplate { title = 'ref-und' };
       hidden = true;
   end
   if hidden == true then
       langs = hiddenRef(langs);
   else
       dot = true;
   end
   table.insert(str, langs)
   -- Формат источника
   if is(args['format']) then
       dot = true;
       table.insert(str, ' (' .. args['format'] .. ')')
   end
   -- Пометка о недоступности
   if (urlstatus == 'dead' and not is(args['archive-url'])) or urlstatus == 'webcite_dead' then
       dot = true;
       table.insert(str,
           frame:expandTemplate { title = 'ref-info',
               args = { 'недоступная ссылка — [//web.archive.org/web/*/' ..
                   args['url'] .. ' история]' } })
   end
   -- Название сайта или проекта
   if is(args['website']) then
       insertDot(str, is(args['subtitle']), dot)
       dot = true;
       table.insert(str, ' ' .. args['website'] .. '')
   end
   -- Страницы
   if is(args['pages']) then
       dot = true;
       table.insert(str, ' ' .. args['pages'])
   end
   -- Страница
   if is(args['page']) then
       dot = true;
       table.insert(str, ' ' .. args['page'])
   end
   -- Место, издательство
   if is(args['publisher']) then
       insertDot(str, is(args['subtitle']), dot)
       dot = true;
       table.insert(str, ' ');
       if is(args['location']) then
           table.insert(str, args['location'] .. ': ')
       end
       table.insert(str, args['publisher'])
   end
   -- Дата
   if is(args['date']) then
       dot = true;
       table.insert(str, ' (' .. formatDate('j xg Y', args['date']) .. ')')
   elseif is(args['year']) then
       dot = true;
       if is(args['month']) then
           table.insert(str, ' (' .. args['month'] .. ' ' .. args['year'] .. ')')
       else
           table.insert(str, ' (' .. args['year'] .. ')')
       end
   end
   -- Точка
   insertDot(str, is(args['subtitle']), dot)
   -- DOI
   if is(args['doi']) then
       table.insert(str,
           ' doi:[http://dx.doi.org/' ..
           args['doi'] .. ' ' .. args['doi'] .. '].')
   end
   -- Описание
   if is(args['description']) then
       table.insert(str, ' — ' .. args['description'])
       insertDot(str, true, needDot(args['description']))
   end
   -- Цитата
   if is(args['quote']) then
       table.insert(str, ' — «' .. args['quote'] .. '»')
       insertDot(str, true, needDot(args['quote']))
   end
   -- Дата обращения
   if is(args['access-date']) then
       table.insert(str, ' Дата обращения: ' ..
           formatDate('j xg Y', args['access-date']) .. '.')
   end
   -- Дата архивирования
   if is(args['archive-date']) and is(args['archive-url']) then
       if urlstatus == 'live' or urlstatus == 'webcite_dead' then
           table.insert(str,
               ' [' ..
               args['archive-url'] ..
               ' Архивировано] ' ..
               formatDate('j xg Y', args['archive-date']) .. ' года.')
       else
           table.insert(str,
               ' Архивировано из [' ..
               args['url'] ..
               ' оригинала] ' ..
               formatDate('j xg Y', args['archive-date']) .. ' года.')
       end
   end
   wrapCite(str, args);
   if #cats ~= 0 and mw.title.getCurrentTitle():inNamespace(0) then
       table.insert(str, expandCats(cats));
   end
   return table.concat(str)

end

return p;