Модуль:ФИО

Материал из Кадровый состав НКВД 1935-1939
Перейти к навигации Перейти к поиску

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

local global = mw.ext.luaglobal
if global.get( 'Новая персона' ) then
	return require( 'Модуль:^ФИО' )
end

local p = {}
local tools = require( 'Модуль:Tools' )
local cq = mw.ext.cargo.query

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, '%-%.', '' ) --TODO: Здесь мы зачем-то превращаем «-.» в nil
	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 or '' ) ~= ''  ) ) 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