Модуль:ФИО: различия между версиями
Перейти к навигации
Перейти к поиску
StasR (обсуждение | вклад) Нет описания правки |
StasR (обсуждение | вклад) Нет описания правки |
||
(не показано 10 промежуточных версий этого же участника) | |||
Строка 1: | Строка 1: | ||
local | local p = {} | ||
local global = mw.ext.luaglobal; | local global = mw.ext.luaglobal; | ||
local tools = require( 'Модуль:Tools' ) | local tools = require( 'Модуль:Tools' ) | ||
local cq = mw.ext.cargo.query | |||
global.strict( true ) | global.strict( true ) | ||
local argus = { true, | local argus = { true, true, true, true, ['дополнение'] = '', ['сноска'] = '', ['источник'] = '', } | ||
p[''] = function ( frame ) | |||
local args, tmp = tools.checkargs( frame:getParent().args, argus ) | local args, tmp = tools.checkargs( frame:getParent().args, argus ) | ||
local ourPage = mw.title.getCurrentTitle().text | local ourPage = mw.title.getCurrentTitle().text | ||
Строка 13: | Строка 14: | ||
.. 'дополнение = <var>текст</var> | сноска = <var>текст</var> | ' | .. 'дополнение = <var>текст</var> | сноска = <var>текст</var> | ' | ||
.. 'источник = <var>текст</var> }}' | .. 'источник = <var>текст</var> }}' | ||
if not args then | |||
if not args then | |||
return tools.errorMsg( 'ФИО', 'Неизвестный параметр ' .. tmp, errorAdvice ) | return tools.errorMsg( 'ФИО', 'Неизвестный параметр ' .. tmp, errorAdvice ) | ||
end | end | ||
local fa = args[1] | local fa, im, ot, idx | ||
fa = args[1] | |||
if not fa then | if not fa then | ||
return tools.errorMsg( 'ФИО', 'Не указана фамилия', errorAdvice ) | return tools.errorMsg( 'ФИО', 'Не указана фамилия', errorAdvice ) | ||
end | end | ||
-- изменения: | |||
-- * индекс обязателен даже у первого вызова (чтобы при переименованиях не потерялось) | |||
-- | -- * Вариант: {ф и о|индекс} убираем за бессмысленностью. Либо единое поле, либо поэлементно | ||
if args[2] == '-' then -- старый способ указания корейца | |||
fa = fa .. ', ' | |||
args[2] = nil | |||
end | end | ||
-- Если у нас единое поле, то надо разбить на fa-im-ot-idx | |||
if #args == 1 then | |||
-- прежде всего делим по запятой: до запятой фамилия | |||
tmp = mw.text.split( fa .. ' ', ', ' ) -- пробел добавили для концевой запятой | |||
return tools.errorMsg( 'ФИО', ' | if #tmp > 2 then | ||
return tools.errorMsg( 'ФИО', | |||
'Запятая используется только для отделения фамилии от имени-отчества', | |||
errorAdvice ) | |||
end | 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 | end | ||
if # | if #tmp > 2 then | ||
return tools.errorMsg( 'ФИО', | return tools.errorMsg( 'ФИО', | ||
'Если какая-то часть ФИО содержит несколько слов, разделяйте части символом «|»', | 'Если какая-то часть ФИО содержит несколько слов, разделяйте части символом «|» ' .. (fa or '—') .. '\n' .. mw.dumpObject(tmp), | ||
errorAdvice ) | errorAdvice ) | ||
end | end | ||
im, ot = tmp[1], tmp[2] | |||
if im == '' then | |||
im = nil | |||
end | end | ||
else | 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 | ||
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 | if not im and not ot then | ||
tmp[1] = fa | |||
tmp = table.concat( tmp, ' ' ) | |||
else | |||
tmp = nil | |||
end | end | ||
if ourPage ~= tmp1 and ourPage ~= tmp then | |||
if | return tools.errorMsg( 'ФИО', | ||
'Первый вызов шаблона ФИО должен соответствовать заголовку страницы', | |||
errorAdvice ) | |||
end | 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 | 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 = mw.text.trim( string.sub( tmp, im2+1, -1) ) -- если отчества не было, а имя двойное, то может быть пробел в конце | |||
local query = 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].disambig ~= '' ) ) then | |||
return tools.errorMsg( 'ФИО', | |||
'Указанное имя уже использовалось на других страницах с индексами.' | |||
.. ' Поэтому без индекса его можно использовать только для страницы разрешения неоднозначности', | |||
errorAdvice ) | |||
.. | |||
end | |||
if | |||
return tools.errorMsg ( 'ФИО', | |||
end | end | ||
if not gFIO then | if not gFIO then | ||
gFIO = {} | gFIO = {} | ||
end | end | ||
table.insert( gFIO, { fa, im, ot, idx, | 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 ) | global.set( 'gFIO', gFIO ) | ||
return frame:expandTemplate{ title = ' | return frame:expandTemplate{ title = 'Cargo:Names', args = { | ||
lastN = fa, | |||
disambig = idx, | firstN = im1, | ||
addendum = | middleN = im2, | ||
} } .. '<i></i>' | disambig = idx, | ||
addendum = args['дополнение'], | |||
porno = #gFIO, --TODO: если это убрать, то можно не проверять на дубликаты | |||
} } .. '<i></i>' | |||
--[[ | |||
.. '<i class="nkvd-hide-link">[ «' .. fa .. '» | «' | |||
.. ( im or '—' ) .. '» : «' .. ( ot or '—' ) .. '» | «' | |||
.. ( im1 or '—' ) .. '» : «' .. ( im2 or '—' ).. '» | «' | |||
.. ( idx or '—' ) .. '» ] </i>' | |||
--]] | |||
end | end | ||
return | return p |
Версия от 20:13, 27 января 2018
Для документации этого модуля может быть создана страница Модуль:ФИО/doc
local p = {}
local global = mw.ext.luaglobal;
local tools = require( 'Модуль:Tools' )
local cq = mw.ext.cargo.query
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 = mw.text.trim( string.sub( tmp, im2+1, -1) ) -- если отчества не было, а имя двойное, то может быть пробел в конце
local query = 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].disambig ~= '' ) ) 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>'
--[[
.. '<i class="nkvd-hide-link">[ «' .. fa .. '» | «'
.. ( im or '—' ) .. '» : «' .. ( ot or '—' ) .. '» | «'
.. ( im1 or '—' ) .. '» : «' .. ( im2 or '—' ).. '» | «'
.. ( idx or '—' ) .. '» ] </i>'
--]]
end
return p