Модуль:ФИО
Перейти к навигации
Перейти к поиску
Для документации этого модуля может быть создана страница Модуль:ФИО/doc
local p = {}
local global = mw.ext.luaglobal;
local tools = require( 'Модуль:Tools' )
global.strict( true )
local argus = { true, true, true, true, ['дополнение'] = '', ['сноска'] = '', ['источник'] = '', }
p[''] = function ( frame )
local args, tmp = tools.checkargs( frame:getParent().args, argus )
local ourPage = mw.title.getCurrentTitle().text
local errorAdvice = 'Используйте формат {{ ФИО | <var>Фамилия</var> | '
.. '<var>Имя</var> | <var>Отчество</var> | '
.. '<var>номер тезки в скобках при наличии</var> | '
.. 'дополнение = <var>текст</var> | сноска = <var>текст</var> | '
.. 'источник = <var>текст</var> }}'
if not args then
return tools.errorMsg( 'ФИО', 'Неизвестный параметр ' .. tmp, errorAdvice )
end
local fa, im, ot, idx
fa = args[1]
if not fa then
return tools.errorMsg( 'ФИО', 'Не указана фамилия', errorAdvice )
end
-- изменения:
-- * индекс обязателен даже у первого вызова (чтобы при переименованиях не потерялось)
-- * Вариант: {ф и о|индекс} убираем за бессмысленностью. Либо единое поле, либо поэлементно
if args[2] == '-' then -- старый способ указания корейца
fa = fa .. ', '
args[2] = nil
end
-- Если у нас единое поле, то надо разбить на fa-im-ot-idx
if #args == 1 then
-- прежде всего делим по запятой: до запятой фамилия
tmp = mw.text.split( fa .. ' ', ', ' ) -- пробел добавили для концевой запятой
if #tmp > 2 then
return tools.errorMsg( 'ФИО',
'Запятая используется только для отделения фамилии от имени-отчества',
errorAdvice )
end
tmp[#tmp] = mw.text.trim( tmp[#tmp] )
if #tmp == 2 then
fa = tmp[1]
tmp = mw.text.split( tmp[2], ' ' )
else
tmp = mw.text.split( tmp[1], ' ' )
fa = tmp[1]
table.remove( tmp, 1 )
end
idx = tmp[#tmp]
if string.match( idx, '^%([IVX]+%)$' ) then
tmp[#tmp] = nil
else
idx = nil
end
if #tmp > 2 then
return tools.errorMsg( 'ФИО',
'Если какая-то часть ФИО содержит несколько слов, разделяйте части символом «|» ' .. (fa or '—') .. '\n' .. mw.dumpObject(tmp),
errorAdvice )
end
im, ot = tmp[1], tmp[2]
if im == '' then
im = nil
end
else
im, ot, idx = args[2], args[3], args[4]
if idx and not string.match( idx, '%([IVX]+%)' ) then
return tools.errorMsg( 'ФИО',
'Номер тезки должен указываться в скобках римскими цифрами',
errorAdvice )
end
end
-- здесь у нас fa-im-ot-idx. Запятой нет, idx корректен, в остальном ФИО не проверено
-- Проверка корректности
local gFIO = global.get( 'gFIO' )
if not gFIO then
-- Перед дальнейшими преобразованиями сверимся с заголовком страницы
tmp = { fa .. ',' }
tmp[#tmp+1] = im
tmp[#tmp+1] = ot
tmp[#tmp+1] = idx
local tmp1 = table.concat( tmp, ' ' )
if not im and not ot then
tmp[1] = fa
tmp = table.concat( tmp, ' ' )
else
tmp = nil
end
if ourPage ~= tmp1 and ourPage ~= tmp then
return tools.errorMsg( 'ФИО',
'Первый вызов шаблона ФИО должен соответствовать заголовку страницы',
errorAdvice )
end
frame:callParserFunction{ name = 'DISPLAYTITLE',
args = tools.name( ourPage ) }
end
ot = ot or ''
im = im or ''
-- поверхностная проверка имени
if not mw.ustring.match( fa..im..ot, '^[А-Яа-я%- %.]+$' ) then
return tools.errorMsg( 'ФИО',
'Имя может содержать только русские буквы',
errorAdvice )
end
--@TODO проверка на кызы-оглы-заде, (нужна для псевдонимов, даже если она есть в newarticletext)
tmp = im .. ' ' .. ot
tmp = string.gsub( tmp, '%-%.', '' )
tmp = string.gsub( tmp, '%.%.%.', '' )
tmp = string.gsub( tmp, '%.', '' )
--@TODO заменить Ё на Е
local im2 = string.find( tmp .. ' ', ' ', 1, true )
local im1 = string.sub( tmp, 1, im2 - 1 )
im2 = string.sub( tmp, im2+1, -1)
local query = tools.cq(
'names_table',
'_pageName, lastN, firstN, middleN, disambig',
{
where = 'lastN="' .. fa .. '" AND firstN="' .. im1
.. '" AND middleN="' .. im2 .. '"',
}
)
local namesakes = {}
for _, row in pairs( query ) do
namesakes[row.disambig or '' ] = row
end
tmp = namesakes[idx or '']
if tmp and tmp._pageName ~= ourPage then
return tools.errorMsg( 'ФИО',
'Указанное имя персоналии относится к [[' .. tmp._pageName
.. '|другому лицу]]',
errorAdvice )
end
if idx and namesakes[''] then
return tools.errorMsg( 'ФИО',
'При наличии тезок [[' .. namesakes['']._pageName
.. '|соответствующее имя без указания номера]]'
.. ' должно относиться к странице разрешения неоднозначности',
errorAdvice )
end
if not idx and ( #query > 1 or ( #query == 1 and query[1].disamig ) ) then
return tools.errorMsg( 'ФИО',
'Указанное имя уже использовалось на других страницах с индексами.'
.. ' Поэтому без индекса его можно использовать только для страницы разрешения неоднозначности',
errorAdvice )
end
if not gFIO then
gFIO = {}
end
table.insert( gFIO, { l = fa, i = im, o = ot, d = idx, f = im1, m = im2,
a = args['дополнение'], r = args['сноска'], s = args['источник'], } )
global.set( 'gFIO', gFIO )
return frame:expandTemplate{ title = 'Cargo:Names', args = {
lastN = fa,
firstN = im1,
middleN = im2,
disambig = idx,
addendum = args['дополнение'],
porno = #gFIO, --@TODO если это убрать, то можно не проверять на дубликаты
} } .. '<i></i>'
--[=[
return '\n\nФИО: ( ' .. ( fa or '—' ) .. ' | ' .. ( im or '—' )
.. ' | ' .. ( ot or '—' ) .. ' | ' .. ( idx or '—' ) .. ' ) >> ( '
.. ( im1 or '—' ) .. ' | ' .. ( im2 or '—' ) .. ' )\n'
--]=]
--[====[
-- Варианты: {ф и о} {ф и о|индекс} {ф и о индекс} {ф|и|о} {ф|и|о|индекс}
local im = args[2]
local idx = ''
if string.sub( im, 1, 1 ) == '(' then
im, idx = '', im
end
local ot = args[3]
tmp = args[4]
if tmp ~= '' then
if string.sub( tmp, 1, 1 ) ~= '(' or idx ~= '' then
return tools.errorMsg( 'ФИО', 'Ошибка в номере тезки', errorAdvice )
end
idx = tmp
end
if im == '' then
tmp = mw.ustring.find( fa, '(', 1, true )
if tmp then
fa, idx = mw.text.trim( mw.ustring.sub( fa, 1, tmp-1 ) ), mw.ustring.sub( fa, tmp, -1 )
end
local fio = mw.text.split( fa, '[\t\r\n\f ]+', false )
if #fio > 3 then
return tools.errorMsg( 'ФИО',
'Если какая-то часть ФИО содержит несколько слов, разделяйте части символом «|»',
errorAdvice )
end
if #fio == 1 then
return tools.errorMsg( 'ФИО', 'Задана только фамилия. Если имени действительно нет, то поставьте вместо него знак «-»', errorAdvice )
end
if mw.ustring.sub( fio[1], -1, -1) == ',' then
fio[1] = mw.ustring.sub( fio[1], 1, -2)
end
fa, im, ot = fio[1], fio[2], fio[3]
end
if not mw.ustring.match( fa, '^[А-Яа-яЁё%- ]+$' ) then
return tools.errorMsg( 'ФИО', 'Недопустимые символы в фамилии', errorAdvice )
end
if not ( mw.ustring.match( im, '^[А-Яа-яЁё%- ]+$' )
or mw.ustring.match( im, '^[А-ЯЁ%-]%.$' ) ) then
return tools.errorMsg( 'ФИО', 'Недопустимые символы в имени', errorAdvice )
end
if not ( mw.ustring.match( ot, '^[А-Яа-яЁё%- ]*$' )
or mw.ustring.match( ot, '^[А-ЯЁ%-]%.$' ) ) then
return tools.errorMsg( 'ФИО', 'Недопустимые символы в отчестве', errorAdvice )
end
local fio
if im == '-' then
fio = fa -- китаец
im = ''
else
fio = mw.text.trim( fa .. ', ' .. im .. ' ' .. ot )
end
if not gFIO then
-- первый шаблон ФИО на странице. Может отличаться от заголовка только
-- отсутствием индекса тезки (чтобы при переименовании страницы для
-- добавления индекса не нужно было править содержимое страницы)
if ourPage ~= fio then
local pageIdx = mw.ustring.find( ourPage, '(', 1, true )
if pageIdx then
pageIdx = mw.ustring.sub( ourPage, pageIdx, -1 )
else
return tools.errorMsg( 'ФИО', errorPageName, errorAdvice )
end
if idx ~= '' and idx ~= pageIdx then
return tools.errorMsg( 'ФИО', errorPageName, errorAdvice )
end
idx = pageIdx
end
if idx ~= '' then
frame:callParserFunction{ name = 'DISPLAYTITLE',
args = fio .. ' <span class="nkvd-idx">' .. idx .. '</span>' }
end
--@TODO для псевдонимов надо проверять дублирование на самой странице!
end
--]====]
--[====[
-- Проверка тезок
local crA, crB, crC, crD
--
local namesakes = {}
-- tmp = frame:callParserFunction{ name = '#cargo_query', args = { '',
-- tables = 'names',
-- where = 'name="' .. fio .. '"',
-- fields = 'disambig, CONCAT(_pageName)=pn',
-- ['order_by'] = 'disambig',
-- limit = '999',
-- format = 'native',
-- } }
-- local qres = mw.ext.cargo.get()
local qres = tools.cq( 'names', 'disambig, _pageName', {
where = 'name="' .. fio .. '"',
orderBy = 'disambig',
limit = '999',
} )
if qres then
for _, namesake in ipairs( qres ) do
local id = namesake.disambig
namesakes[id] = namesake._pageName
if id ~= '' and id ~= idx then
crC = true
end
end
end
crA = namesakes[''] ~= nil
crB = ( namesakes[idx] or ourPage ) ~= ourPage
crD = mw.title.new( fio ).exists
local actionIdx = 0 -- 1 - укажите индекс, 2 - измените индекс
local actionAlt = 0 -- 1 - переименуйте страницу, 2 — отредактируйте страницу
local actionDis = 0 -- 1 — создайте страницу разрешения неоднозначностей
local debugFio = '(' .. ourPage .. '/' .. fio .. ':' .. idx .. ':' .. tostring( crA ) .. ' ' .. tostring( crB ) .. ' ' .. tostring( crC ) .. ' ' .. tostring( crD ) .. ') ' .. mw.dumpObject( qres ) .. '\n'
if idx == '' then
if not crB and not crC then
elseif not crB and crC then
actionIdx = 1
if not crD then
actionDis = 1
end
elseif crB and not crC then
if crD then
actionAlt = 2
else
actionAlt = 1
end
actionIdx = 1
actionDis = 1
else -- crB and crC then
error( 'Ошибка алгоритма' )
end
elseif not crA and not crB then
if not crD then
actionDis = 1
end
elseif not crA and crB then
actionIdx = 2
if not crD then
actionDis = 1
end
elseif crA and not crB and not crC then
if crD then
actionAlt = 2
else
actionAlt = 1
end
actionDis = 1
else
error( 'Ошибка алгоритма' )
end
local txtErr,txtAdv = '', ''
if actionIdx ~= 0 then
if actionIdx == 1 then
actionIdx = ''
else
actionIdx = 'другой (свободный) '
end
if gFIO then
txtErr = 'изменить вызов шаблона ФИО'
else
txtErr = 'переименовать данную страницу'
end
txtErr = 'Необходимо ' .. txtErr .. ', указав ' .. actionIdx
.. '«индекс тезки»'
if actionDis ~= 0 then
txtErr = txtErr .. ' — скорее всего, «(II)»'
end
if actionAlt ~= 0 then
txtAdv = 'После этого будет необходимо переименовать/отредактировать страницу тезки'
if actionDis ~= 0 then
txtAdv = txtAdv .. ' и создать страницу разрешения неоднозначностей'
end
elseif actionDis ~= 0 then
txtAdv = 'После этого будет необходимо создать страницу разрешения неоднозначностей'
end
elseif actionAlt == 2 then
txtErr = 'Необходимо перейти по этой [[Special:MovePage/' .. fio
.. '|ссылке]], чтобы переименовать ранее созданную страницу с именем «'
.. fio ..'» в «' .. fio ..' (I)»'
txtAdv = 'Страница «' .. fio
..'» будет использоваться как указатель для разрешения неоднозначности'
elseif actionAlt == 1 then
txtErr = 'Необходимо перейти на ['
.. tostring( mw.uri.fullUrl( namesakes[''], {
action = 'edit',
editintro = 'Template:Disambiguation_renumber_editnotice',
para = fio
} ) )
.. ' страницу], где имя «' .. fio ..'» указано в качестве псевдонима'
.. ' в одном из шаблонов ФИО, чтобы добавить к нему индекс тезки «(I)»'
if actionDis ~= 0 then
txtAdv = 'После этого будет необходимо создать страницу разрешения неоднозначностей'
end
elseif actionDis ~= 0 then
txtErr = 'Необходимо перейти по этой ['
.. tostring( mw.uri.fullUrl( fio, {
action = 'edit',
preload = 'Template:Disambiguation_pattern',
editintro = 'Template:Disambiguation_editnotice'
} ) )
.. ' ссылке], чтобы создать страницу разрешения неоднозначностей'
end
if txtErr ~= '' then
return tools.errorMsg ( 'ФИО', txtErr, txtAdv )
-- .. '\n' .. debugFio )
end
local addendum, comment, source =
args['дополнение'] or '', args['сноска'] or '', args['источник'] or ''
if not gFIO then
gFIO = {}
end
table.insert( gFIO, { fa, im, ot, idx, addendum, comment, source } )
global.set( 'gFIO', gFIO )
-- ставим вызов Cargo в return, чтобы не потерять сообщения об ошибках
return frame:expandTemplate{ title = 'Таблица ФИО', args = {
name = fio,
disambig = idx,
addendum = addendum,
} } .. '<i></i>'
--]====]
end
return p