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

Материал из in.wiki
Перейти к навигации Перейти к поиску
(обновление для перевода всех нпN на единый модуль, см. ВП:ФТ#Общий модуль для шаблонов Не переведено и http://web.archive.org/web/20201019200559/https://ru.wikipedia.org/wiki/Шаблон:Не_переведено/тесты)
 
(не показано 36 промежуточных версий 8 участников)
Строка 1: Строка 1:
local getArgs = require('Module:Arguments').getArgs
 
 
local p = {}
 
local p = {}
 +
 +
local categories = {
 +
['error'] = 'Проект:Статьи с некорректно заполненным шаблоном Не переведено',
 +
['outdated'] = 'Проект:Статьи с неактуальным шаблоном Не переведено',
 +
['redirect'] = 'Проект:Запросы на замену перенаправлений переводами',
 +
['unknown'] = 'Проект:Статьи с неизвестными параметрами шаблонов серии Не переведено',
 +
['semiold'] = 'Проект:Статьи с полустарым синтаксисом в шаблонах серии Не переведено',
 +
['probably_wrong'] = 'Проект:Статьи с предположительно неверными параметрами в шаблонах серии Не переведено',
 +
['lang-not-exists'] = 'Проект:Статьи с шаблоном Не переведено 2, использующие несуществующий шаблон lang-XX',
 +
}
  
 
local function is_empty(param)
 
local function is_empty(param)
Строка 6: Строка 15:
 
end
 
end
  
local function wikilink(title, text, tooltip, lang)
+
local function is_wikidata(lang)
if lang ~= nil and lang ~= 'ru' then
+
return lang == 'd'
 +
end
 +
 
 +
local function getTitle(page, iw_title, is_wikidata_link)
 +
local success, result = pcall(function()
 +
if is_wikidata_link then
 +
local entity = mw.wikibase.getSitelink(iw_title)
 +
if entity ~= nil then
 +
return {
 +
title = entity,
 +
exists = true,
 +
-- предположение, что в Викиданных не перенаправление
 +
isRedirect = false,
 +
}
 +
end
 +
 +
return nil
 +
else
 +
local title = mw.title.new(page)
 +
return {
 +
title = page,
 +
exists = title.exists,
 +
isRedirect = title.isRedirect,
 +
}
 +
end
 +
end)
 +
 +
if success then
 +
return result
 +
end
 +
 +
return nil
 +
end
 +
 
 +
local function wikilink(title, text, tooltip, lang, style, is_redirect)
 +
if is_empty(text) then
 +
text = title
 +
end
 +
if not is_empty(lang) and lang ~= 'ru' then
 
title = string.format(':%s:%s', lang, title)
 
title = string.format(':%s:%s', lang, title)
 
end
 
end
if tooltip ~= nil then
+
if is_wikidata(lang) then
if is_empty(text) then
+
title = title .. '#sitelinks-wikipedia'
text = title
+
end
end
+
if not is_empty(tooltip) then
text = tostring(
+
text = string.format('<span title="%s">%s</span>', tooltip, text)
mw.html.create('span')
+
end
:attr('title', tooltip)
+
if not is_empty(style) then
:wikitext(text)
+
text = string.format('<span style="%s">%s</span>', style, text)
 +
end
 +
if is_redirect then
 +
return string.format(
 +
'<span class="plainlinks">[%s %s]</span>',
 +
tostring(mw.uri.fullUrl(title,'redirect=no')),
 +
text
 
)
 
)
 +
elseif text ~= title then
 +
return string.format('[[%s|%s]]', title, text)
 +
else
 +
return string.format('[[%s]]', title)
 
end
 
end
if not is_empty(text) and text ~= title then
+
end
title = title .. '|' .. text
+
 
 +
local function addMetadata(text, lang, article)
 +
return string.format(
 +
'<span data-interwiki-lang="%s" data-interwiki-article="%s">%s</span>',
 +
lang, article, text
 +
)
 +
end
 +
 
 +
local function throwError(text, category_code, allow_cat)
 +
local error = require('Module:Error').error
 +
if category_code and allow_cat then
 +
return error{text} .. '[[Category:' .. categories[category_code] .. ']]'
 +
else
 +
return error{text}
 
end
 
end
return string.format('[[%s]]', title)
 
 
end
 
end
  
local function italic(s)
+
function p._subst(mode, title, text, lang, iw_text)
return tostring(
+
-- Вывести выделение строки за её пределами
mw.html.create('span')
+
local selOffset = mw.ustring.find( text, "''" )
:css('font-style', 'italic')
+
local sel = ''
:wikitext(s)
+
if selOffset ~= nil and selOffset == 1 then
)
+
local oldText = text
 +
text = mw.text.trim( text, "'" )
 +
sel = mw.ustring.rep( "'", ( mw.ustring.len( oldText ) - mw.ustring.len( text ) ) / 2 )
 +
end
 +
local result = sel .. wikilink(title, text) .. sel
 +
 +
-- Вывести содержимое скобок в не переведено 2
 +
if mode == 2 then
 +
local iw_link = '{{lang-' .. lang .. '|' .. iw_text .. '}}'
 +
if is_empty(addition) then
 +
return string.format('%s (%s)', result, iw_link)
 +
else
 +
return string.format('%s (%s; %s)', result, iw_link, addition)
 +
end
 +
end
 +
 +
return result
 
end
 
end
  
 
function p.main(frame)
 
function p.main(frame)
 
local yesno = require('Module:Yesno')
 
local yesno = require('Module:Yesno')
local args = getArgs(frame)
+
local getArgs = require('Module:Arguments').getArgs
 
local languages = mw.loadData('Module:Languages/data')
 
local languages = mw.loadData('Module:Languages/data')
local error = require('Module:Error').error
 
 
local prepositional = require('Module:Languages')._transform_lang
 
local prepositional = require('Module:Languages')._transform_lang
  
local categories = ''
+
local args = getArgs(frame)
 +
 
 +
local categories_list = {}
 
local nocat = yesno(args['nocat'])
 
local nocat = yesno(args['nocat'])
local allow_cat = mw.title.getCurrentTitle().namespace == 0 and not nocat
+
local allow_cat = (mw.title.getCurrentTitle().namespace == 0
local orphan_categories = {
+
or mw.title.getCurrentTitle().namespace == 10) and not nocat
['error'] = '[[Категория:Википедия:Статьи с некорректно заполненным шаблоном Не переведено]]',
+
['outdated'] = '[[Категория:Википедия:Статьи с неактуальным шаблоном Не переведено]]',
+
-- определение какой из шаблонов "не переведено N"
['redirect'] = '[[Категория:Википедия:Запросы на замену перенаправлений переводами]]'
 
}
 
 
local mode = tonumber(args['mode'])
 
local mode = tonumber(args['mode'])
 +
mode = mode == 2 and 2 or 5
 +
local template_name = 'Не переведено'
 +
if mode ~= 5 then
 +
template_name = template_name .. ' ' .. tostring(mode)
 +
end
 +
 +
-- проверка на неизвестные параметры
 +
local redundant_params = {}
 +
local good_params = {'mode', 1, 2, 3, 4, 'l', 'leave', 'r', 'q', 'nocat'}
 +
if mode == 2 then
 +
table.insert(good_params, 5)
 +
table.insert(good_params, 'text')
 +
table.insert(good_params, 'текст')
 +
end
 +
for k, _ in pairs(args) do
 +
local is_good_param = false
 +
for _, v in pairs(good_params) do
 +
  if k == v then
 +
  is_good_param = true
 +
  end
 +
end
 +
if not is_good_param then
 +
table.insert(redundant_params, k)
 +
end
 +
end
 +
if #redundant_params > 0 then
 +
table.insert(categories_list, {'unknown', table.concat(redundant_params)})
 +
end
  
 +
-- получение параметров (кроме nocat)
 
local title = args[1]
 
local title = args[1]
 
local text = args[2]
 
local text = args[2]
Строка 56: Строка 169:
 
local iw_title = args[4]
 
local iw_title = args[4]
 
local iw_text = args[5]
 
local iw_text = args[5]
 
+
local quotes = yesno(args['q'])
if args[1]:match('^:[a-z-]+:') then
+
local addition = args['text'] or args['текст']
if allow_cat then
+
local leave_always = yesno(args['l']) or yesno(args['leave'])
categories = categories .. '[[Категория:Страницы с полустарым синтаксисом в шаблоне «не переведено»]]'
+
local leave_if_redirect = yesno(args['r'])
 +
 +
-- проверка правильности сырых параметров
 +
if not mw.isSubsting() then
 +
if is_empty(title) then
 +
return throwError('не указано название статьи', 'error', allow_cat)
 +
end
 +
if title:match('^:[a-z-]+:') then
 +
return throwError('шаблон не поддерживает такой синтаксис', 'semiold', allow_cat)
 +
end
 +
if is_empty(lang) and not is_empty(iw_title) and iw_title:match('^[a-z][a-z]$') then
 +
table.insert(categories_list, {'probably_wrong', nil})
 
end
 
end
return error{'шаблон не поддерживает такой синтаксис'} .. categories
 
end
 
 
if mw.isSubsting() and mode ~= 2 then
 
return wikilink(title, text)
 
 
end
 
end
 
 
if is_empty(title) then
+
-- приведение параметров к нужному виду
if allow_cat then
 
categories = categories .. orphan_categories['error']
 
end
 
return error{'не указано название статьи'} .. categories
 
end
 
 
if is_empty(text) then
 
if is_empty(text) then
 
text = title
 
text = title
Строка 79: Строка 193:
 
if is_empty(lang) then
 
if is_empty(lang) then
 
lang = 'en'
 
lang = 'en'
 +
else
 +
lang = mw.ustring.lower(lang)
 
end
 
end
local orig_iw_title = iw_title
 
 
if is_empty(iw_title) then
 
if is_empty(iw_title) then
 
iw_title = title
 
iw_title = title
Строка 87: Строка 202:
 
iw_text = iw_title
 
iw_text = iw_title
 
end
 
end
 
+
local ru_page = mw.title.new(title)
+
-- если используется с подстановкой, выбросить почти без обработки
if ru_page == nil then
+
if mw.isSubsting() then
if allow_cat then
+
return p._subst( mode, title, text, lang, iw_text )
categories = categories .. orphan_categories['error']
 
end
 
return error{'некорректные символы в названии статьи'} .. categories
 
 
end
 
end
 
 
local iw_page = mw.title.new(iw_title)
+
-- получение страницы, чтобы знать, существует ли она и является ли она перенаправлением
if iw_page == nil then
+
local isWikidataLink = is_wikidata(lang)
if allow_cat then
+
local considerAsExists
categories = categories .. orphan_categories['error']
+
local isRedirect
 +
local considerAsRedirect
 +
if leave_always then -- если задано |l=1, то ничего не проверять, потому что дорого
 +
considerAsExists = false
 +
isRedirect = false
 +
considerAsRedirect = false
 +
else
 +
-- дорогая функция, после 500 вызова крашится
 +
local titleObject = getTitle(title, iw_title, isWikidataLink)
 +
if titleObject then
 +
title = titleObject.title
 +
considerAsExists = titleObject.exists
 +
isRedirect = titleObject.isRedirect
 +
considerAsRedirect = isRedirect and not leave_if_redirect
 +
else -- после 500 вызова или если в названии есть некорректные символы
 +
considerAsExists = false
 +
isRedirect = false
 +
considerAsRedirect = false
 
end
 
end
return error{'некорректные символы в названии статьи'} .. categories
 
 
end
 
end
 
 
local leave_always = yesno(args['l']) or yesno(args['leave'])
+
-- проверка правильности обработанных параметров
local leave_if_redirect = yesno(args['r'])
+
if lang ~= 'd' and languages[lang] == nil then
if leave_if_redirect and not ru_page.isRedirect then
+
return throwError('некорректный ISO-код «' .. lang .. '»', 'error', allow_cat)
leave_if_redirect = false
+
end
 +
if mode == 2 and isWikidataLink then
 +
return throwError('шаблон Не переведено 2 не поддерживает Викиданные вместо языка')
 +
end
 +
if mode == 2 and not mw.title.new('Template:Lang-' .. lang).exists then -- дорогая функция
 +
return throwError('не найден шаблон ' .. frame:expandTemplate{ title = 'tl', args = { 'lang-' .. lang } },
 +
'lang-not-exists', allow_cat)
 
end
 
end
local exists = ru_page.exists and not ( leave_always or leave_if_redirect )
+
if leave_if_redirect and allow_cat then
+
if mode == 5 and considerAsRedirect then
categories = categories .. orphan_categories['redirect']
+
table.insert(categories_list, {'redirect', nil})
 +
elseif considerAsExists then
 +
table.insert(categories_list, {'outdated', nil})
 
end
 
end
 
 
 +
-- всплывающая подсказка к ссылке на иноязычную статью
 
local iw_tooltip
 
local iw_tooltip
 
local ucfirst_title = mw.getContentLanguage():ucfirst(title)
 
local ucfirst_title = mw.getContentLanguage():ucfirst(title)
if lang == 'd' then
+
if isWikidataLink then
if mode == 1 or mode == 2 then
+
iw_tooltip = string.format('Элемент статьи «%s» в Викиданных', ucfirst_title)
iw_tooltip = string.format('Элемент статьи «%s» в Викиданных', ucfirst_title)
 
elseif mode == 5 then
 
iw_tooltip = string.format('Страница статьи «%s» в Викиданных', ucfirst_title)
 
iw_title = iw_title .. '#sitelinks-wikipedia' -- осторожно, может сломать что-то
 
end
 
 
else
 
else
if mode == 1 or mode == 2 then
+
iw_tooltip = string.format('%s — версия статьи «%s» на %s', iw_title, ucfirst_title, prepositional(lang))
iw_tooltip = string.format('Версия статьи «%s» на %s', ucfirst_title, prepositional(lang))
 
elseif mode == 4 then
 
iw_tooltip = string.format('Эквивалент статьи «%s» на %s', ucfirst_title, prepositional(lang))
 
elseif mode == 5 then
 
local pref
 
if is_empty(orig_iw_title) then
 
pref = 'Версия статьи'
 
else
 
pref = string.format('%s — версия статьи', iw_title)
 
end
 
iw_tooltip = string.format('%s «%s» на %s', pref, ucfirst_title, prepositional(lang))
 
end
 
 
end
 
end
  
-- форматирование первой части - основной ссылки
+
-- формирование первой части - основной ссылки
 
local main_text
 
local main_text
if exists or mode == 1 or mode == 2 or mode == 5 then
+
if considerAsExists or mode == 1 or mode == 2 or mode == 5 then
if mode == 5 and ru_page.isRedirect then
+
main_text = wikilink(title, text, nil, nil, nil, isRedirect)
main_text = string.format('[%s %s]', tostring(mw.uri.fullUrl(title,'redirect=no')), text)
+
if not considerAsExists then
else
+
main_text = addMetadata(main_text, lang, iw_title)
main_text = wikilink(title, text)
 
end
 
if exists and not mw.isSubsting() and (mode == 1 or mode == 2 or mode == 3) then
 
main_text = tostring(
 
mw.html.create('span')
 
:css('background', '#ffff00')
 
:wikitext(main_text)
 
)
 
 
end
 
end
 
else
 
else
 
main_text = wikilink(iw_title, text, iw_tooltip, lang)
 
main_text = wikilink(iw_title, text, iw_tooltip, lang)
 
end
 
end
+
if mode == 4 and quotes then -- TODO: все шаблоны или отключить
-- форматирование второй части - языковой метки
+
main_text = '«' .. main_text .. '»'
local lang_text
 
local lang_title
 
if lang == 'd' then
 
lang_text = 'd'
 
elseif languages[lang] == nil then
 
if allow_cat then
 
categories = categories .. orphan_categories['error']
 
end
 
return error{'некорректный ISO-код «' .. lang .. '»'} .. categories
 
else
 
lang_text = languages[lang][1]
 
lang_title = languages[lang][2]
 
 
end
 
end
 
 
 +
-- формирование второй части - языковой метки
 
local post_text = ''
 
local post_text = ''
if (not exists and not mw.isSubsting()) or mode == 2 or (mode == 5 and ru_page.isRedirect) then
+
if not (considerAsExists and not (isRedirect and leave_if_redirect)) or mode == 2 or (mode == 5 and considerAsRedirect) then
 +
-- для шаблона "не переведено"
 
if mode == 1 then
 
if mode == 1 then
 +
local lang_text
 +
if isWikidataLink then
 +
lang_text = 'ВД'
 +
else
 +
lang_text = languages[lang][1]
 +
end
 +
 
local iw_link = wikilink(iw_title, lang_text, iw_tooltip, lang)
 
local iw_link = wikilink(iw_title, lang_text, iw_tooltip, lang)
post_text = tostring(
+
post_text = string.format(
mw.html.create('span')
+
'<span class="noprint" style="white-space: nowrap; font-size: 85%%;"> (%s)</span>',
:addClass('noprint')
+
iw_link
:css('white-space', 'nowrap')
 
:css('font-size', '85%')
 
:wikitext(' (' .. iw_link .. ')')
 
 
)
 
)
 +
 +
-- для шаблона "не переведено 2"
 
elseif mode == 2 then
 
elseif mode == 2 then
 
local iw_link = ''
 
local iw_link = ''
if lang == 'd' then
+
if considerAsExists then
return error{'шаблон Не переведено 2 не поддерживает Викиданные вместо языка'}
+
iw_link = frame:expandTemplate{ title = 'lang-' .. lang, args = { iw_text } }
 
else
 
else
local lang_template = mw.title.new('Template:Lang-' .. lang)
+
iw_link = frame:expandTemplate{ title = 'lang-' .. lang, args = { wikilink(iw_title, iw_text, iw_tooltip, lang) } }
if not lang_template.exists then
 
if allow_cat then
 
categories = categories .. '[[Категория:Википедия:Статьи с шаблоном Не переведено 2, использующие несуществующий шаблон lang-XX]]'
 
end
 
return error{'не найден шаблон ' .. frame:expandTemplate{ title = 'tl', args = { 'lang-' .. lang } } } .. categories
 
end
 
 
if mw.isSubsting() then
 
iw_link = '{{lang-' .. lang .. '|' .. iw_text .. '}}'
 
elseif exists then
 
iw_link = frame:expandTemplate{ title = 'lang-' .. lang, args = { iw_text } }
 
else
 
iw_link = frame:expandTemplate{ title = 'lang-' .. lang, args = { wikilink(iw_title, iw_text, iw_tooltip, lang) } }
 
end
 
 
end
 
end
 
 
local addition = args['text'] or args['текст']
+
if is_empty(addition) then
if not is_empty(addition) then
+
post_text = string.format(' (%s)', iw_link)
addition = '; ' .. addition
+
else
else  
+
post_text = string.format(' (%s; %s)', iw_link,  addition)
addition = ''
 
 
end
 
end
post_text = ' (' .. iw_link .. addition .. ')'
+
 +
-- для шаблона "не переведено 3"
 +
-- TODO: вынести всё это добро в TemplateStyles
 
elseif mode == 3 then
 
elseif mode == 3 then
local ref = frame:expandTemplate{ title = 'ref-' .. lang, args = {} }
+
local ref = string.format(
post_text = '<span style="white-space: nowrap"><span class="noprint" style="font-size:95%; '
+
-- неразрывный пробел на этой позиции предотвращает перенос перед элементом с display:inline-block в Хроме
.. 'position: relative; top: .4em;">' .. ref .. '</span><span class="link-ru metadata noprint" '
+
'<span style="font-size:117.6%%; margin-left:-0.43em; position:relative; top:0.28em;">%s</span>',
.. 'style="font-size:80%; margin-left:-1.7em; position: relative; top: -.4em;">'
+
frame:expandTemplate{
.. wikilink(title, 'русск.') .. '</span></span>'
+
title = 'ref-' .. (isWikidataLink and 'info' or lang),
 +
args = {
 +
isWikidataLink and 'ВД' or ''
 +
}
 +
}
 +
)
 +
local ru_link = wikilink(title, 'рус.')
 +
if not considerAsExists then
 +
ru_link = addMetadata(ru_link, lang, iw_title)
 +
end
 +
ru_link = string.format(
 +
-- position:absolute; позволяет точнее позиционировать пометку; иначе она «скачет», по крайней мере в Хроме
 +
'<span class="link-ru metadata" style="margin-left:-0.43em; position:absolute; left:0; z-index:1; margin-top:-0.35em;"><span style="visibility:hidden; margin-right:0.099em;">&nbsp;(</span>%s</span>',
 +
ru_link
 +
)
 +
post_text = string.format(
 +
-- размер шрифта и свойство display:inline-block указывается здесь из-за проблем с размерами шрифта в Хроме на Андроиде
 +
'&nbsp;<span style="display:inline-block; font-size:80%%; position:relative;">%s%s</span>',
 +
ref, ru_link
 +
)
 +
 +
-- для шаблона "не переведено 4"
 
elseif mode == 4 then
 
elseif mode == 4 then
 
local styles = ''
 
local styles = ''
Строка 228: Строка 344:
 
styles = 'margin-right:0.5em;'
 
styles = 'margin-right:0.5em;'
 
end
 
end
post_text = '<sup class="noprint" style="font-style:normal; margin-left:2px; position:relative; top:-1px;">'
+
.. wikilink(title, 'ru', 'Статья «' .. title .. '» в русском разделе отсутствует') .. '</sup>'
+
local ru_link = wikilink(title, 'ru', 'Статья «' .. title .. '» в русском разделе отсутствует')
.. '<sub class="noprint" style="font-style:normal; margin-left:-0.94em; ' .. styles .. '" title="По ссылке доступна статья на '
+
if not considerAsExists then
.. prepositional(lang) .. '">' .. lang .. '</sub>'
+
ru_link = addMetadata(ru_link, lang, iw_title)
 +
end
 +
ru_link = string.format(
 +
'<sup style="margin-left:2px; position:relative; top:-1px;">%s</sup>',
 +
ru_link
 +
)
 +
local ref = string.format(
 +
'<sub style="margin-left:-0.94em; %s" title="По ссылке доступна статья на %s">%s</sub>',
 +
styles, prepositional(lang), lang
 +
)
 +
post_text = string.format('%s%s', ru_link, ref)
 +
 +
-- для шаблона "не переведено 5"
 
else
 
else
post_text = '<sup class="iw__note noprint" style="font-style:normal; font-weight:normal;">'
+
local langText = '[???]'
.. string.format('[[:%s:%s|<span class="iw__tooltip" title="%s">[%s]</span>]]</sup>', lang, iw_title, iw_tooltip, lang)
+
if lang == 'd' then
 +
langText = '[вд]'
 +
else
 +
langText = '[' .. ( languages[ lang ] and languages[ lang ][ 1 ] or lang ) .. ']'
 +
end
 +
 +
post_text = string.format(
 +
'<sup class="noprint" style="font-style:normal; font-weight:normal;">%s</sup>',
 +
wikilink(iw_title, langText, iw_tooltip, lang)
 +
)
 
end
 
end
 
end
 
end
 
 
-- форматирование третьей части - уведомления о существовании страницы
+
-- формирование третьей части - уведомления о существовании страницы
 
local exist_message = ''
 
local exist_message = ''
if exists then
+
if considerAsExists and not (isRedirect and leave_if_redirect) then
if allow_cat and (mode ~= 5 or not ru_page.isRedirect) then
+
local exist_message_link
categories = categories .. orphan_categories['outdated']
+
if mode == 5 then
end
+
if considerAsRedirect then
if allow_cat and (mode == 5 and ru_page.isRedirect) then
+
exist_message_link = 'Шаблон:' .. template_name .. '#Если существует перенаправление'
categories = categories .. orphan_categories['redirect']
+
else
 +
exist_message_link = 'Шаблон:' .. template_name .. '#Если существует статья'
 +
end
 +
else
 +
exist_message_link = 'Шаблон:' .. template_name .. '#Действия после появления страницы'
 
end
 
end
 
 
if mode == 1 or mode == 2 or mode == 3 then
+
if mode == 5 and considerAsRedirect then
local exist_tooltip = ''
 
if mode == 1 or mode == 2 then
 
exist_tooltip = 'Пожалуйста, удалите шаблон, заменив «{{не переведено» на  «{{подст:не переведено»'
 
else
 
exist_tooltip = 'Пожалуйста, удалите шаблон, заменив «{{не переведено 3» на  «{{подст:переведено 3»'
 
end
 
 
local docname = 'Шаблон:Не переведено'
 
if mode == 2 or mode == 3 then
 
docname = docname .. ' ' .. mode
 
end
 
 
 
exist_message = string.format(
 
exist_message = string.format(
'&#91;\'\'%s\'\'&#93;',
+
'<sup class="noprint" style="margin:0 0 0 1px;">%s</sup>',
wikilink(
+
wikilink(exist_message_link, '*', 'Замените название перенаправления на название статьи либо уберите шаблон «' .. template_name .. '»', nil, 'color:red;')
docname .. '#Действия после появления страницы',  
 
'убрать шаблон',
 
exist_tooltip
 
)
 
 
)
 
)
exist_message = tostring(
+
else
mw.html.create('sup')
+
exist_message = string.format(
:addClass('noprint')
+
'<sup class="noprint">%s</sup>',
:wikitext(exist_message)
+
wikilink(exist_message_link, '?!', 'Уберите шаблон «' .. template_name .. '» из статьи и замените его простой вики-ссылкой', nil, 'color:red;')
 
)
 
)
elseif mode == 4 then
+
end
exist_message = '<sup class="noprint">[[Шаблон:Не переведено 4#Действия после появления страницы|'
+
.. '<span style="background:yellow; color:red; font-style:normal;" title="Пожалуйста, '
+
exist_message = string.format('<span style="font-style:normal; font-weight:bold;">%s</span>', exist_message)
.. 'замените шаблон «Не переведено 4» простой вики-ссылкой">\'\'\'?!\'\'\'</span>]]</sup>'
+
end
else
+
if ru_page.isRedirect then
+
local categories_text = ''
exist_message = '<sup class="iw__notice noprint" style="font-style:normal; font-weight:normal; margin:0 0 0 1px;">'
+
if allow_cat then
.. '[[Шаблон:Не переведено 5#Если существует перенаправление|'
+
for _, category_data in pairs(categories_list) do
.. '<span style="color:red; font-weight:bold;" title="Замените название перенаправления на название статьи либо уберите шаблон «Не переведено 5»">*</span>]]'
+
local category_name = categories[category_data[1]]
.. '</sup>'
+
if category_data[2] ~= nil then
else
+
category_name = category_name .. '|' .. category_data[2]
exist_message = '<sup class="iw__notice noprint">[[Шаблон:Не переведено 5#Если существует статья|'
 
.. '<span style="color:red; font-style:normal; font-weight:bold;" title="Уберите шаблон «Не переведено 5» из статьи '
 
.. 'и замените его простой вики-ссылкой">?!</span>]]</sup>'
 
 
end
 
end
 +
categories_text = categories_text .. '[[Category:' .. category_name .. ']]'
 
end
 
end
 
end
 
end
 
 
 
local result
 
local result
result = main_text .. post_text
+
if mode == 2 then
if not mw.isSubsting() then
+
result = main_text .. exist_message .. post_text .. categories_text
result = result .. exist_message .. categories
+
else
end
+
result = main_text .. post_text .. exist_message .. categories_text
if mode == 5 then
 
local langName = ''
 
if lang ~= 'd' then
 
langName = ' data-lang-name="' .. (languages[lang][1] and languages[lang][1] or '???') .. '"'
 
end
 
 
local class = (exists and (ru_page.isRedirect and ' iw--redirect' or ' iw--exists') or '')
 
result = string.format('<span class="iw%s plainlinks" data-title="%s" data-lang="%s"' .. langName .. '>', class, ucfirst_title, lang)
 
.. result .. '</span>'
 
 
end
 
end
 
 

Текущая версия от 21:32, 12 апреля 2025

Для документации этого модуля может быть создана страница Модуль:Не переведено/doc

local p = {}

local categories = {
	['error'] = 'Проект:Статьи с некорректно заполненным шаблоном Не переведено',
	['outdated'] = 'Проект:Статьи с неактуальным шаблоном Не переведено',
	['redirect'] = 'Проект:Запросы на замену перенаправлений переводами',
	['unknown'] = 'Проект:Статьи с неизвестными параметрами шаблонов серии Не переведено',
	['semiold'] = 'Проект:Статьи с полустарым синтаксисом в шаблонах серии Не переведено',
	['probably_wrong'] = 'Проект:Статьи с предположительно неверными параметрами в шаблонах серии Не переведено',
	['lang-not-exists'] = 'Проект:Статьи с шаблоном Не переведено 2, использующие несуществующий шаблон lang-XX',
}

local function is_empty(param)
	return param == nil or param == ''
end

local function is_wikidata(lang)
	return lang == 'd'
end

local function getTitle(page, iw_title, is_wikidata_link)
	local success, result = pcall(function()
		if is_wikidata_link then
			local entity = mw.wikibase.getSitelink(iw_title)
			if entity ~= nil then
				return {
					title = entity,
					exists = true,
					-- предположение, что в Викиданных не перенаправление
					isRedirect = false,
				}
			end
			
			return nil
		else
			local title = mw.title.new(page)
			return {
				title = page,
				exists = title.exists,
				isRedirect = title.isRedirect,
			}
		end
	end)
	
	if success then
		return result
	end
	
	return nil
end

local function wikilink(title, text, tooltip, lang, style, is_redirect)
	if is_empty(text) then
		text = title
	end
	if not is_empty(lang) and lang ~= 'ru' then
		title = string.format(':%s:%s', lang, title)
	end
	if is_wikidata(lang) then
		title = title .. '#sitelinks-wikipedia'
	end
	if not is_empty(tooltip) then
		text = string.format('<span title="%s">%s</span>', tooltip, text)
	end
	if not is_empty(style) then
		text = string.format('<span style="%s">%s</span>', style, text)
	end
	if is_redirect then
		return string.format(
			'<span class="plainlinks">[%s %s]</span>',
			tostring(mw.uri.fullUrl(title,'redirect=no')),
			text
		)
	elseif text ~= title then
		return string.format('[[%s|%s]]', title, text)
	else
		return string.format('[[%s]]', title)
	end
end

local function addMetadata(text, lang, article)
	return string.format(
		'<span data-interwiki-lang="%s" data-interwiki-article="%s">%s</span>',
		lang, article, text
		)
end

local function throwError(text, category_code, allow_cat)
	local error = require('Module:Error').error
	if category_code and allow_cat then
		return error{text} .. '[[Category:' .. categories[category_code] .. ']]'
	else
		return error{text}
	end
end

function p._subst(mode, title, text, lang, iw_text)
	-- Вывести выделение строки за её пределами
	local selOffset = mw.ustring.find( text, "''" )
	local sel = ''
	if selOffset ~= nil and selOffset == 1 then
		local oldText = text
		text = mw.text.trim( text, "'" )
		sel = mw.ustring.rep( "'", ( mw.ustring.len( oldText ) - mw.ustring.len( text ) ) / 2 )
	end
	local result = sel .. wikilink(title, text) .. sel
	
	-- Вывести содержимое скобок в не переведено 2
	if mode == 2 then
		local iw_link = '{{lang-' .. lang .. '|' .. iw_text .. '}}'
		if is_empty(addition) then
			return string.format('%s (%s)', result, iw_link)
		else
			return string.format('%s (%s; %s)', result, iw_link, addition)
		end
	end
	
	return result
end

function p.main(frame)
	local yesno = require('Module:Yesno')
	local getArgs = require('Module:Arguments').getArgs
	local languages = mw.loadData('Module:Languages/data')
	local prepositional = require('Module:Languages')._transform_lang

	local args = getArgs(frame)

	local categories_list = {}
	local nocat = yesno(args['nocat'])
	local allow_cat = (mw.title.getCurrentTitle().namespace == 0
		or mw.title.getCurrentTitle().namespace == 10) and not nocat
	
	-- определение какой из шаблонов "не переведено N"
	local mode = tonumber(args['mode'])
	mode = mode == 2 and 2 or 5
	local template_name = 'Не переведено'
	if mode ~= 5 then
		template_name = template_name .. ' ' .. tostring(mode)
	end
	
	-- проверка на неизвестные параметры
	local redundant_params = {}
	local good_params = {'mode', 1, 2, 3, 4, 'l', 'leave', 'r', 'q', 'nocat'}
	if mode == 2 then
		table.insert(good_params, 5)
		table.insert(good_params, 'text')
		table.insert(good_params, 'текст')
	end
	for k, _ in pairs(args) do
		local is_good_param = false
		for _, v in pairs(good_params) do
		  	if k == v then
		  		is_good_param = true
		  	end
		end
		if not is_good_param then
			table.insert(redundant_params, k)
		end
	end
	if #redundant_params > 0 then
		table.insert(categories_list, {'unknown', table.concat(redundant_params)})
	end

	-- получение параметров (кроме nocat)
	local title = args[1]
	local text = args[2]
	local lang = args[3]
	local iw_title = args[4]
	local iw_text = args[5]
	local quotes = yesno(args['q'])
	local addition = args['text'] or args['текст']
	local leave_always = yesno(args['l']) or yesno(args['leave'])
	local leave_if_redirect = yesno(args['r'])
	
	-- проверка правильности сырых параметров
	if not mw.isSubsting() then
		if is_empty(title) then
			return throwError('не указано название статьи', 'error', allow_cat)
		end
		if title:match('^:[a-z-]+:') then
			return throwError('шаблон не поддерживает такой синтаксис', 'semiold', allow_cat)
		end
		if is_empty(lang) and not is_empty(iw_title) and iw_title:match('^[a-z][a-z]$') then
			table.insert(categories_list, {'probably_wrong', nil})
		end
	end
	
	-- приведение параметров к нужному виду
	if is_empty(text) then
		text = title
	end
	if is_empty(lang) then
		lang = 'en'
	else
		lang = mw.ustring.lower(lang)
	end
	if is_empty(iw_title) then
		iw_title = title
	end
	if is_empty(iw_text) then
		iw_text = iw_title
	end
	
	-- если используется с подстановкой, выбросить почти без обработки
	if mw.isSubsting() then
		return p._subst( mode, title, text, lang, iw_text )
	end
	
	-- получение страницы, чтобы знать, существует ли она и является ли она перенаправлением
	local isWikidataLink = is_wikidata(lang)
	local considerAsExists
	local isRedirect
	local considerAsRedirect
	if leave_always then -- если задано |l=1, то ничего не проверять, потому что дорого
		considerAsExists = false
		isRedirect = false
		considerAsRedirect = false
	else
		-- дорогая функция, после 500 вызова крашится
		local titleObject = getTitle(title, iw_title, isWikidataLink)
		if titleObject then
			title = titleObject.title
			considerAsExists = titleObject.exists
			isRedirect = titleObject.isRedirect
			considerAsRedirect = isRedirect and not leave_if_redirect
		else -- после 500 вызова или если в названии есть некорректные символы
			considerAsExists = false
			isRedirect = false
			considerAsRedirect = false
		end
	end
	
	-- проверка правильности обработанных параметров
	if lang ~= 'd' and languages[lang] == nil then
		return throwError('некорректный ISO-код «' .. lang .. '»', 'error', allow_cat)
	end
	if mode == 2 and isWikidataLink then
		return throwError('шаблон Не переведено 2 не поддерживает Викиданные вместо языка')
	end
	if mode == 2 and not mw.title.new('Template:Lang-' .. lang).exists then -- дорогая функция
		return throwError('не найден шаблон ' .. frame:expandTemplate{ title = 'tl', args = { 'lang-' .. lang } },
			'lang-not-exists', allow_cat)
	end
	
	if mode == 5 and considerAsRedirect then
		table.insert(categories_list, {'redirect', nil})
	elseif considerAsExists then
		table.insert(categories_list, {'outdated', nil})
	end
	
	-- всплывающая подсказка к ссылке на иноязычную статью
	local iw_tooltip
	local ucfirst_title = mw.getContentLanguage():ucfirst(title)
	if isWikidataLink then
		iw_tooltip = string.format('Элемент статьи «%s» в Викиданных', ucfirst_title)
	else
		iw_tooltip = string.format('%s — версия статьи «%s» на %s', iw_title, ucfirst_title, prepositional(lang))
	end

	-- формирование первой части - основной ссылки
	local main_text
	if considerAsExists or mode == 1 or mode == 2 or mode == 5 then
		main_text = wikilink(title, text, nil, nil, nil, isRedirect)
		if not considerAsExists then
			main_text = addMetadata(main_text, lang, iw_title)
		end
	else
		main_text = wikilink(iw_title, text, iw_tooltip, lang)
	end
	if mode == 4 and quotes then -- TODO: все шаблоны или отключить
		main_text = '«' .. main_text .. '»'
	end
	
	-- формирование второй части - языковой метки
	local post_text = ''
	if not (considerAsExists and not (isRedirect and leave_if_redirect)) or mode == 2 or (mode == 5 and considerAsRedirect) then
		-- для шаблона "не переведено"
		if mode == 1 then
			local lang_text
			if isWikidataLink then
				lang_text = 'ВД'
			else
				lang_text = languages[lang][1]
			end
			
			local iw_link = wikilink(iw_title, lang_text, iw_tooltip, lang)
			post_text = string.format(
				'<span class="noprint" style="white-space: nowrap; font-size: 85%%;"> (%s)</span>',
				iw_link
			)
		
		-- для шаблона "не переведено 2"
		elseif mode == 2 then
			local iw_link = ''
			if considerAsExists then
				iw_link = frame:expandTemplate{ title = 'lang-' .. lang, args = { iw_text } }
			else
				iw_link = frame:expandTemplate{ title = 'lang-' .. lang, args = { wikilink(iw_title, iw_text, iw_tooltip, lang) } }
			end
			
			if is_empty(addition) then
				post_text = string.format(' (%s)', iw_link)
			else
				post_text = string.format(' (%s; %s)', iw_link,  addition)
			end
		
		-- для шаблона "не переведено 3"
		-- TODO: вынести всё это добро в TemplateStyles
		elseif mode == 3 then
			local ref = string.format(
				-- неразрывный пробел на этой позиции предотвращает перенос перед элементом с display:inline-block в Хроме
				'<span style="font-size:117.6%%; margin-left:-0.43em; position:relative; top:0.28em;">%s</span>',
				frame:expandTemplate{
					title = 'ref-' .. (isWikidataLink and 'info' or lang),
					args = {
						isWikidataLink and 'ВД' or ''
					}
				}
			)
			local ru_link = wikilink(title, 'рус.')
			if not considerAsExists then
				ru_link = addMetadata(ru_link, lang, iw_title)
			end
			ru_link = string.format(
				-- position:absolute; позволяет точнее позиционировать пометку; иначе она «скачет», по крайней мере в Хроме
				'<span class="link-ru metadata" style="margin-left:-0.43em; position:absolute; left:0; z-index:1; margin-top:-0.35em;"><span style="visibility:hidden; margin-right:0.099em;">&nbsp;(</span>%s</span>',
				ru_link
			)
			post_text = string.format(
				-- размер шрифта и свойство display:inline-block указывается здесь из-за проблем с размерами шрифта в Хроме на Андроиде
				'&nbsp;<span style="display:inline-block; font-size:80%%; position:relative;">%s%s</span>',
				ref, ru_link
			)
		
		-- для шаблона "не переведено 4"
		elseif mode == 4 then
			local styles = ''
			if lang == 'fr' then
				styles = 'margin-right:0.3em;'
			elseif lang == 'fi' then
				styles = 'margin-right:0.35em;'
			elseif lang == 'it' then
				styles = 'margin-right:0.5em;'
			end
			
			local ru_link = wikilink(title, 'ru', 'Статья «' .. title .. '» в русском разделе отсутствует')
			if not considerAsExists then
				ru_link = addMetadata(ru_link, lang, iw_title)
			end
			ru_link = string.format(
				'<sup style="margin-left:2px; position:relative; top:-1px;">%s</sup>',
				ru_link
			)
			local ref = string.format(
				'<sub style="margin-left:-0.94em; %s" title="По ссылке доступна статья на %s">%s</sub>',
				styles, prepositional(lang), lang
			)
			post_text = string.format('%s%s', ru_link, ref)
		
		-- для шаблона "не переведено 5"
		else
			local langText = '[???]'
			if lang == 'd' then
				langText = '[вд]'
			else
				langText = '[' .. ( languages[ lang ] and languages[ lang ][ 1 ] or lang ) .. ']'
			end
			
			post_text = string.format(
				'<sup class="noprint" style="font-style:normal; font-weight:normal;">%s</sup>',
				wikilink(iw_title, langText, iw_tooltip, lang)
			)
		end
	end
	
	-- формирование третьей части - уведомления о существовании страницы
	local exist_message = ''
	if considerAsExists and not (isRedirect and leave_if_redirect) then
		local exist_message_link
		if mode == 5 then
			if considerAsRedirect then
				exist_message_link = 'Шаблон:' .. template_name .. '#Если существует перенаправление'
			else
				exist_message_link = 'Шаблон:' .. template_name .. '#Если существует статья'
			end
		else
			exist_message_link = 'Шаблон:' .. template_name .. '#Действия после появления страницы'
		end
		
		if mode == 5 and considerAsRedirect then
			exist_message = string.format(
				'<sup class="noprint" style="margin:0 0 0 1px;">%s</sup>',
				wikilink(exist_message_link, '*', 'Замените название перенаправления на название статьи либо уберите шаблон «' .. template_name .. '»', nil, 'color:red;')
			)
		else
			exist_message = string.format(
				'<sup class="noprint">%s</sup>',
				wikilink(exist_message_link, '?!', 'Уберите шаблон «' .. template_name .. '» из статьи и замените его простой вики-ссылкой', nil, 'color:red;')
			)
		end
		
		exist_message = string.format('<span style="font-style:normal; font-weight:bold;">%s</span>', exist_message)
	end
	
	local categories_text = ''
	if allow_cat then
		for _, category_data in pairs(categories_list) do
			local category_name = categories[category_data[1]]
			if category_data[2] ~= nil then
				category_name = category_name .. '|' .. category_data[2]
			end
			categories_text = categories_text .. '[[Category:' .. category_name .. ']]'
		end
	end
	
	local result
	if mode == 2 then
		result = main_text .. exist_message .. post_text .. categories_text
	else
		result = main_text .. post_text .. exist_message .. categories_text
	end
	
	return result
end

return p