Модуль:Hatnote: различия между версиями

м
Замена текста — «Википедия:» на «ЭАНМ:»
imported>Grain of sand
(переработка вывода ошибок, новые отслеживаемые случаи, возможность заменить последний разделитель на «и»)
м (Замена текста — «Википедия:» на «ЭАНМ:»)
 
(не показано 57 промежуточных версий 9 участников)
Строка 1: Строка 1:
local _get_args = require('Module:Arguments').getArgs
local get_args = require('Module:Arguments').getArgs
local mError = require('Module:Error')
local mError
local yesno = require('Module:Yesno')
local yesno = function (v) return require('Module:Yesno')(v, true) end


local p = {}
local p, tr = {}, {}
local current_title = mw.title.getCurrentTitle()
local tracking_categories = {
local tracking_categories = {
no_prefix = 'ЭАНМ:Страницы с шаблоном Hatnote без указания префикса',
no_prefix = 'ЭАНМ:Страницы с модулем Hatnote без указания префикса',
no_links = 'ЭАНМ:Страницы с шаблоном Hatnote без ссылок',
no_links = 'ЭАНМ:Страницы с модулем Hatnote без ссылок',
red_link = 'ЭАНМ:Страницы с шаблоном Hatnote с красной ссылкой',
red_link = 'ЭАНМ:Страницы с модулем Hatnote с красной ссылкой',
unwanted_pipe = 'ЭАНМ:Страницы с шаблоном Hatnote с некорректно заполненными параметрами'
bad_format = 'ЭАНМ:Страницы с модулем Hatnote с некорректно заполненными параметрами',
unparsable_link = 'ЭАНМ:Страницы с модулем Hatnote с нечитаемой ссылкой',
formatted = 'ЭАНМ:Страницы с модулем Hatnote с готовым форматированием',
}
}


local function get_args(frame)
local function index(t1, t2)
    if type(frame.args) == 'table' then
return setmetatable(t1, {__index = t2})
        return _get_args(frame)
    else
        return frame
    end
end
end


Строка 23: Строка 22:
end
end


local function add_category(categories, type, nocat)
function tr.define_categories(tracked_cases)
if not nocat then
local categories = setmetatable({}, {
table.insert(categories, string.format('[[Категория:%s]]', categories[type] or tracking_categories[type]))
__tostring = function (self) return table.concat(self) end,
__concat = concat
})
 
function categories:add(element, nocat)
if not nocat then
local cat_name
if tracked_cases and tracked_cases[element] then
cat_name = tracked_cases[element]
else
cat_name = element
end
table.insert(self, string.format('[[Категория:%s]]', cat_name))
end
end
end
return categories
end
end


local function error(msg, categories, preview_only)
function tr.error(msg, categories, preview_only)
local current_frame = mw.getCurrentFrame()
local current_frame = mw.getCurrentFrame()
if not preview_only or current_frame:preprocess('{{REVISIONID}}') ~= '' then
local parent_frame = current_frame:getParent()
return mError.error{string.format('Ошибка в [[%s]]: %s', current_frame:getTitle(), msg)} .. categories
local res_frame_title = parent_frame and parent_frame:getTitle() ~= current_title.prefixedText and
parent_frame:getTitle() or
current_frame:getTitle()
if not preview_only or current_frame:preprocess('{{REVISIONID}}') == '' then
mError = require('Module:Error')
return mError.error{
tag = 'div',
string.format('Ошибка в [[%s]]: %s.'  
.. (preview_only and '<br><small>Это сообщение показывается только во время предпросмотра.</small>' or ''), res_frame_title, msg)
} .. categories
else  
else  
return categories
return categories
Строка 38: Строка 61:
end
end


function p.section_link(frame)
function p.parse_link(frame)
local args = get_args(frame)
local link = args[1]:gsub('\n', '')
local label
link = mw.text.trim(link:match('^%[%[([^%]]+)%]%]$') or link)
if link:sub(1, 1) == '/' then
label = link
link = current_title.prefixedText .. link
end
link = link:match(':?(.+)')
if link:match('|') then
link, label = link:match('^([^%|]+)%|(.+)$')
end
if not mw.title.new(link) then
return nil, nil
end
return link, label
end
 
function p.format_link(frame)
-- {{ссылка на раздел}}
-- {{ссылка на раздел}}
local args = get_args(frame)
local args = get_args(frame)
local link, section, label = args[1], args[2], nil
local link, section, label = args[1], args[2], args[3]
if not link then
if not link then
link = mw.title.getCurrentTitle().text
link = current_title.prefixedText
if section then
if section then
link = '#' .. section
link = '#' .. section
label = '§&nbsp;' .. section
label = label or '§&nbsp;' .. section
end
end
else
else
link = link:match('%[%[([^%]]+)%]%]') or link
local parsed_link, parsed_label = p.parse_link{link}
if link:match('|') then
if parsed_link then
link, label = link:match('^([^%|]+)%|(.+)$')
link = parsed_link
else
return link
end
end
if section and not link:match('#') then
if section and not link:match('#') then
link = link .. '#' .. section
link = link .. '#' .. section
if parsed_label then
parsed_label = parsed_label .. '#' .. section
end
end
end
label = (label or link):gsub('^([^#]-)#(.+)$', '%1 §&nbsp;%2')
label = (label or parsed_label or link):gsub('^([^#]-)#(.+)$', '%1 §&nbsp;%2')
end
end
return string.format('[[%s|%s]]', link, label or link)
if label and label ~= link then
return string.format('[[:%s|%s]]', link, label)
else
return string.format('[[:%s]]', link)
end
end
end


function p.remove_precision(frame)
function p.remove_precision(frame)
    -- {{без уточнения}}
-- {{без уточнения}}
    local args = get_args(frame)
local args = get_args(frame)
    local title = args.title or args[1]
local title = args[1]
   
    return title:match('^%s*(.+)%s+%b()%s*$') or title
return title:match('^(.+)%s+%b()$') or title
end
end


function p.is_disambig(frame)
function p.is_disambig(frame)
local args = get_args(frame)
local args = get_args(frame)
local title = args.title or args[1]
local title = args[1]
local page = mw.title.new(title)
local page = mw.title.new(title)
if not page.exists or mw.title.equals(page, mw.title.getCurrentTitle()) then
if not page or not page.exists or mw.title.equals(page, current_title) then
return false
return false
end
end
Строка 89: Строка 143:
end
end
end
end
    return false
return false
end
end


function p.list(frame)
function p.list(frame)
local args = get_args(frame)
local args = get_args(frame, {trim = false})
local list_sep = args.list_sep or args['разделитель списка'] or ', '
local list_sep = args.list_sep or args['разделитель списка'] or ', '
local last_list_sep = yesno(args.natural_join) ~= false and ' и ' or list_sep
local last_list_sep = yesno(args.natural_join) ~= false and ' и ' or list_sep
local links_ns = args.links_ns or args['ПИ ссылок']
local bold_links = yesno(args.bold_links or args['ссылки болдом'])
local bold_links = yesno(args.bold_links or args['ссылки болдом'])


local res = ''
local res_list = {}
local tracked = {
local tracked = {
red_link = false,
red_link = false,
unwanted_pipe = false
bad_format = false,
formatted = false,
unparsable_link = false
}
}
    local i = 1
 
local i = 1
while args[i] do
while args[i] do
local link = args[i]
local link = args[i]
local label = args['l' .. i] or link
local label = args['l' .. i]
        if link:match('|') then
local element = ''
        tracked.unwanted_pipe = true
if link:match('<span') then -- TODO: переписать
local splitted = {}
tracked.formatted = true
for s in link:gmatch('[^|]+') do
element = link -- for {{не переведено}}
splitted[#splitted + 1] = s
else
local bad_format = (link:match('|') or link:match('[%[%]]')) ~= nil
local parsed_link, parsed_label = p.parse_link{link}
if parsed_link then
tracked.bad_format = tracked.bad_format or bad_format
if links_ns then
parsed_label = parsed_label or parsed_link
parsed_link = mw.site.namespaces[links_ns].name .. ':' .. parsed_link
end
local title = mw.title.new(parsed_link)
tracked.red_link = tracked.red_link or not (title.isExternal or title.exists)
element = p.format_link{parsed_link, nil, label or parsed_label}
else
tracked.unparsable_link = true
element = link
end
end
link, label = unpack(splitted)
end
end
       
        tracked.red_link = tracked.red_link or not mw.title.new(link).exists
if bold_links then
       
        local element = p.section_link{string.format('[[%s|%s]]', link, label)}
        if bold_links then
element = string.format('<b>%s</b>', element)
element = string.format('<b>%s</b>', element)
end
end
        if res ~= '' then
table.insert(res_list, element)
        if args[i] and not args[i + 1] then
i = i + 1
        res = res .. last_list_sep
    else
    res = res .. list_sep
        end
        end
       
res = res .. element
        i = i + 1
end
end
return setmetatable({res}, {
return setmetatable(res_list, {
__index = tracked,  
__index = tracked,
__tostring = function (self) return self[1] end,
__tostring = function (self) return mw.text.listToText(self, list_sep, last_list_sep) end,
__concat = concat
__concat = concat,
__pairs = function (self) return pairs(tracked) end
})
})
end
end
Строка 146: Строка 208:
function p.hatnote(frame)
function p.hatnote(frame)
local args = get_args(frame)
local args = get_args(frame)
local text = args.text or args[1]
local text = args[1]
local extraclasses = args.extraclasses or ''
local id = args.id
local extraclasses = args.extraclasses
local hide_disambig = yesno(args.hide_disambig)
local hide_disambig = yesno(args.hide_disambig)
local hatnote_class = 'rellink'
local res = mw.html.create('div')
:attr('id', id)
:addClass('hatnote')
:addClass('navigation-not-searchable')
:addClass(extraclasses)
:wikitext(text)
if hide_disambig then
if hide_disambig then
hatnote_class = 'dablink'
res:addClass('dabhide')
end
end
return mw.html.create('div')
return res
:addClass('hatnote')
:addClass(hatnote_class)
:addClass(extraclasses)
:wikitext(text)
end
end


function p.main(frame, categories)
function p.main(frame, _tracking_categories)
local args = get_args(frame)
local args = get_args(frame, {trim = false})
local prefix = args.prefix or args['префикс']
local prefix = args.prefix or args['префикс']
local prefix_plural = args.prefix_plural or args['префикс мн. ч.']
local prefix_plural = args.prefix_plural or args['префикс мн. ч.']
local sep = args.sep or args['разделитель'] or ' '
local sep = args.sep or args['разделитель'] or ' '
local hide_disambig = args.hide_disambig
local dot = yesno(args.dot or args['точка']) and '.' or ''
local dot = yesno(args.dot or args['точка']) and '.' or ''
local nocat = yesno(args.nocat)
local nocat = yesno(args.nocat)
local preview_error = yesno(args.preview_error)
local preview_error = yesno(args.preview_error)
local empty_list_message = args.empty_list_message or 'Не указано ни одной страницы'
categories = setmetatable(categories or {}, {
categories = tr.define_categories(index(_tracking_categories or {}, tracking_categories))
__tostring = function (self) return table.concat(self) end,
__concat = concat
})


if not prefix or prefix == '' then
if not prefix then
add_category(categories, 'no_prefix', nocat)
categories:add('no_prefix', nocat)
return error('Не указан префикс', categories)
return tr.error('Не указан префикс', categories)
end
end
if not args[1] then
if not args[1] then
add_category(categories, 'no_links', nocat)
categories:add('no_links', nocat)
return error('Не указано ни одной страницы', categories, preview_error)
return tr.error(empty_list_message, categories, preview_error)
end
end
Строка 192: Строка 254:
local list = p.list(args)
local list = p.list(args)
if list.red_link then
add_category(categories, 'red_link', nocat)
for k, v in pairs(list) do
end
if type(v) == 'boolean' and v then
if list.unwanted_pipe then
categories:add(k, nocat)
add_category(categories, 'unwanted_pipe', nocat)
end
end
end
return p.hatnote{prefix .. sep .. list .. dot, hide_disambig = hide_disambig} .. categories
return p.hatnote(index({prefix .. sep .. list .. dot}, args)) .. categories
end
end


return p
return index(p, tr)