Модуль:Национальное имя (Bk;rl,&Ugenkugl,uky nbx)

Перейти к навигации Перейти к поиску
Документация

Модуль шаблона {{Национальное имя}}

local getArgs = require('Module:Arguments').getArgs
local p = {}
local specialCase = {}
local givenNoName = {}
local givenNoArgs = {}


--Список допустимых частей имени и их порядок по умолчанию для общего случая
local possiblePartsOfName = { 
	'имя',
	'среднее имя',
	'средние имена',
	'отчество',
	'фамилия',
	'вторая фамилия',
}

 
 --Таблица частных случаев, когда аргументы заданы, но нужна особая формулировка или трактовка аргументов
local specialCases = {
	['испанское'] = 'spanish',
	['азербайджанское'] = 'azerbaijani',
	['казахское'] = 'kazakh',
	['литовское'] = 'lithuanian',
	['корейское'] = 'korean',
	['китайское'] = 'chinese',
	['болгарское'] = 'bulgarian'
}

 --Таблица случаев, когда задана только национальная характеристика
 local noNamesGiven = {
 	['азербайджанское'] = 'azerbaijani',
 	['казахское'] = 'kazakh',
 	['испанское'] = 'spanish',
 	['китайское'] = 'chinese',
 	['болгарское'] = 'bulgarian'
 }


--Таблица случаев, когда аргументы не заданы
local noArgsGiven = {	
	['Q227'] = {'azerbaijan', 1920},
	['Q15180Q227'] = {'azerbaijan', 1920},
	['Q232'] = {'kazakhstan', 1920}, 
	['Q15180Q232'] = {'kazakhstan', 1920},
	['Q29'] = {'spanishWorld', 1920},
	['Q96'] = {'spanishWorld', 1920},
	['Q219'] = {'bulgaria',  1965}
	
}

 
--Список допустимых сокращений
local shirt = {
	['и'] = 'имя', ['си'] = 'среднее имя', ['сии'] = 'средние имена',
	['о'] = 'отчество', ['ф'] = 'фамилия', ['вф'] = 'вторая фамилия',
	['исп'] = 'испанское', ['азе'] = 'азербайджанское', ['каз'] = 'казахское',
	['лит'] = 'литовское', ['кит'] = 'китайское', ['кор'] = 'корейское',
	['бол'] = 'болгарское'
}


local function makeInvokeFunc(funcName)
	return function (frame)
		local args = getArgs(frame)
		return p[funcName](args)
	end
end
p.NameClarification = makeInvokeFunc('_NameClarification')
function p._NameClarification(args)
	return choose (args)
end


 --ЭТО РАСПРЕДЕЛЯЮЩАЯ ФУНКЦИЯ 
 --Если национальная характеристика задана, присутствует в таблице specialCases и задан ещё хотя бы один аргумент, вызывается соответствующая функция группы specialCase. Если национальная характеристика не задана или отсутствует в этой таблице, но хотябы один другой аргумент задан, вызывается функция generalCase. Если задана только национальная характеристика и она присутствует в таблице noNamesGiven, вызывается соответствующая функция группы givenNoNames. Если аргументы не заданы вообще, из Викиданных запрашивается гражданство и дата рождения и, если они соответствуют таблице NoArgsGiven, то вызывается соответствующая функция группы givenNoArgs.   
function choose (args)
	for i, k in pairs (args) do if (shirt[i]) then args[shirt[i]] = k; args[i] = nil end if (i == 1 and shirt[k]) then args[i] = shirt[k] end end
	local numArgs, numParts = 0, 0
	local givenNation = args [1] or ''
	local names = {}
	for i, k in pairs (args) do numArgs = numArgs + 1 end
	for i, part in ipairs (possiblePartsOfName) do
		if (args [part]) then numParts = numParts + 1 ; names [part] = args [part] end
	end
	if (givenNation ~= '' and (numArgs >= 2) and specialCases [givenNation]) then
		return specialCase [specialCases [givenNation]] (args) or ''
	elseif (numParts > 0) then
		return generalCase (names, givenNation)
	elseif (givenNation ~= '' and (numArgs < 2) and noNamesGiven[givenNation]) then
		return givenNoName [noNamesGiven[givenNation]] () or ''
	elseif (numArgs == 0) then 		
		local countryCode, birth = '', 0
		local entity = mw.wikibase.getEntity ()
		if (entity and entity.claims and entity.claims.P27) then
			for j, k in ipairs (entity.claims.P27) do 
				if (k.mainsnak and k.mainsnak.datavalue and k.mainsnak.datavalue.value and k.mainsnak.datavalue.value.id) then
					countryCode	=countryCode .. k.mainsnak.datavalue.value.id 
				end
			end
			if (entity.claims.P569 and entity.claims.P569 [1] and entity.claims.P569 [1].mainsnak and entity.claims.P569 [1].mainsnak.datavalue and entity.claims.P569 [1].mainsnak.datavalue.value and entity.claims.P569 [1].mainsnak.datavalue.value['time']) then     
				 birth = tonumber(mw.ustring.match(entity.claims.P569 [1].mainsnak.datavalue.value['time']  ,'[%d]+')) or 0
			 end
		end
		if(countryCode ~= '' and birth ~= 0 and noArgsGiven[countryCode] and noArgsGiven[countryCode][1] and noArgsGiven[countryCode][2] and (noArgsGiven[countryCode][2] < birth)) then 
			return givenNoArgs[noArgsGiven[countryCode][1]]() or ''
		else
			return ''
		end
	else
		return ''
	end
 end


--ЭТО ФУНКЦИЯ ДЛЯ ОБЩЕГО СЛУЧАЯ
--Она может также вызываться из других функций.
function generalCase (names, givenNation)
	local name = {}
local j = 0
	for i, part in ipairs (possiblePartsOfName) do 
		if (names[part]) then
			j = j + 1; name[j] = names[part] .. ' — ' .. part
			if ( part == 'имя') then name[j] = names[part] .. ' — личное имя' end 
			if (part == 'фамилия' and names['вторая фамилия']) then name[j] = names[part] .. ' — первая (основная) фамилия'   end 
		end
	end
	if (#name == 2 and names['имя'] and names ['фамилия']) then local temp = name[1]; name[1] = name[2]; name[2] = temp end
	local n = ''
	 j = 0	
	while j < #name do
		j = j + 1
		if (j > 1) then n = n .. ', ' end
		if (j == #name and j > 1 and j <= 3 ) then n = n .. 'а 'end
		n = n .. name[j]
	end
	if (n ~= '') then return 'Здесь '.. n .. ' этого человека'.. seeMoreAbout(givenNation) .. '.'end
	return ''
end


--ФУНКЦИИ ДЛЯ СЛУЧАЕВ, КОГДА АРГУМЕНТЫ ЗАДАНЫ, НО НУЖНА ОСОБАЯ ФОРМУЛИРОВКА ИЛИ ТРАКТОВКА АРГУМЕНТОВ

function specialCase.korean (args) --Корейское
	if (args[2] and (not args[3]) and (not args['фамилия']) and (not args['имя'])) then return 'Здесь фамилия (' .. args[2] .. ') стоит перед личным именем' .. seeMoreAbout (args[1]) .. '.' end
	if  (args[2] and args[3] and (not args['фамилия']) and (not args['имя'])) then args['фамилия'] = args[2]; args['имя'] = args[3] end
	return generalCase (args, args[1])
end

function specialCase.chinese (args) --Китайское
	if (args[2] and (not args[3]) and (not args['фамилия']) and (not args['имя'])) then return 'Здесь фамилия (' .. args[2] .. ') стоит перед личным именем' .. seeMoreAbout (args[1]) .. '.' end
	if  (args[2] and args[3] and (not args['фамилия']) and (not args['имя'])) then args['фамилия'] = args[2]; args['имя'] = args[3] end
	return generalCase (args, args[1])
end

function specialCase.lithuanian (args) --Литовское
	if (args[2] and args[3]) then return 'Здесь ' .. args[2] .. ' — женская форма фамилии ' .. args[3] .. '; см [[Литовское имя]].' end 
	local bc = getNameFromTitleBeforeComma ()
	if (args[2] and (bc ~= '')) then return 'Здесь ' .. bc .. ' — женская форма фамилии ' .. args[2] .. '; см [[Литовское имя]].' else return generalCase (args, args[1]) end
end

function specialCase.azerbaijani (args) --Азербайджанское
	if (not args['отчество'] and args[2]) then args['отчество'] = args[2] end
	return generalCase (args, args[1])
end

function specialCase.kazakh (args) --Казахское
	if (not args['отчество'] and args[2]) then args['отчество'] = args[2] end
	return generalCase (args, args[1])
end

function specialCase.spanish (args) --Испанское
	if (args[2] and (not args[3]) and (not args['фамилия']) and (not args['вторая фамилия']) and mw.ustring.match(getNameFromTitleBeforeComma (), '^[А-ЯЁ][а-яё][а-яё]+$')) then
		args['фамилия'] = getNameFromTitleBeforeComma (); args['вторая фамилия']	= args[2]
	end
	if (args[2] and args[3] and (not args['фамилия']) and (not args['вторая фамилия'])) then args['фамилия'] = args[2]; args['вторая фамилия']	= args[3] end
	return generalCase (args, args[1])
end

function  specialCase.bulgarian (args) -- Болгарское
	local bc = getNameFromTitleBeforeComma ()
	if (args[2] and (not args[3]) and (not args['фамилия']) and (not args['отчество']) and mw.ustring.match(bc, '^[А-ЯЁ][а-яё][а-яё]+$')) then args['фамилия'] = bc; args['отчество'] = args[2] end
	if (args[2] and args[3] and (not args['фамилия']) and (not args['отчество'])) then args['отчество'] = args[2]; args['фамилия']	= args[3] end
	return generalCase (args, args[1]) 
	end


--ФУНКЦИИ ДЛЯ СЛУЧАЕВ, КОГДА ЗАДАНА ТОЛЬКО НАЦИОНАЛЬНАЯ ХАРАКТЕРИСТИКА

function givenNoName.kazakh () --Казахское
	local pat, text
	local ac = getNameFromTitleAfterComma ()
	pat = mw.ustring.match (ac,'^[А-ЯЁ][а-яё][а-яё]+ ([А-ЯЁ][а-яё][а-яё]+улы)$') or mw.ustring.match (ac,'^[А-ЯЁ][а-яё][а-яё]+ ([А-ЯЁ][а-яё][а-яё]+кызы)$') 
	if (pat) then text = generalCase ({['отчество'] = pat}, 'казахское') end
	
	return text or ''
end

function givenNoName.azerbaijani () --Азербайджанское
	local pat, text
	local bc = getNameFromTitleBeforeComma ()
	local ac = getNameFromTitleAfterComma ()
	if (mw.ustring.match (bc,'^[А-ЯЁ][а-яё][а-яё]+[ое]ва?$') or mw.ustring.match (bc,'^[А-ЯЁ][а-яё][а-яё]+л[ыи]$')or mw.ustring.match (bc,'^[А-ЯЁ][а-яё][а-яё]+заде$')) then 
		pat = mw.ustring.match (ac,'^[А-ЯЁ][а-яё][а-яё]+ ([А-ЯЁ][а-яё][а-яё]+ огл[ыу])$') or mw.ustring.match (ac,'^[А-ЯЁ][а-яё][а-яё]+ ([А-ЯЁ][а-яё][а-яё]+ кызы)$') 
		if (not pat and mw.ustring.match (ac, '^[А-ЯЁ][а-яё][а-яё]+$') )then 
			local fn = getFullNameFromText ()
			pat = mw.ustring.match (fn, '^'..ac..' ([А-ЯЁ][а-яё][а-яё]+ огл[ыу]) '..bc..'$') or mw.ustring.match (fn, '^'..ac..' ([А-ЯЁ][а-яё][а-яё]+ кызы) '..bc..'$') or ''
		end
	end
	if (pat) then text = generalCase ({['отчество'] = pat}, 'азербайджанское') end
	return text or ''
end

function givenNoName.chinese () --Китайское
	local fn = getNameFromTitleIfNoComma ()
	sn = mw.ustring.match(fn, '^([Б-ДЖЗК-НП-ТФ-Ш]?[жз]?[уЮю]?[аоуыэяюиеАОУЫЭЯЕИЮ][йнору]?ь?) [Б-ДЖЗК-НП-ТФ-Ш]?[жз]?[уЮю]?[аоуыэяюиеАОУЫЭЯЕИЮ][йнору]?[ъь]?[б-джзк-нп-тф-ш]?[жз]?[ую]?[аоуыэяеию]?[йнору]?ь?$')
	if (sn) then return 'Здесь фамилия (' .. sn .. ') стоит перед личным именем' .. seeMoreAbout ('китайское') .. '.' else return '' end
end

function givenNoName.spanish () --Испанское
	local sf
	local bc = getNameFromTitleBeforeComma ()
	local fn = getFullNameFromText ()	
	if (mw.ustring.match (bc,'^[А-ЯЁ][а-яё][а-яё]+$')) then
		sf = mw.ustring.match (fn, '[А-ЯЁ][а-яё][а-яё][а-яё]+ ' .. bc .. ' ([А-ЯЁ][а-яё][а-яё][а-яё]+)$')
	end
	if (sf) then return generalCase ({['фамилия'] = bc, ['вторая фамилия'] = sf}, 'испанское') else return '' end
end

function givenNoName.bulgarian () --Болгарское
	local bc = getNameFromTitleBeforeComma ()
	local ac = getNameFromTitleAfterComma ()
	local fn = getFullNameFromText ()
	local pat
	if (mw.ustring.match(bc, '^[А-ЯЁ][а-яё][а-яё]+[ое]ва?$') or mw.ustring.match(bc, '^[А-ЯЁ][а-яё][а-яё]+ск[аи][яй]?$')) then
		if ( mw.ustring.match(ac, '^[А-ЯЁ][а-яё][а-яё]+$'))  then pat = mw.ustring.match (fn, '^' .. ac .. ' ([А-ЯЁ][а-яё][а-яё]+[ое]ва?) ' .. bc .. '$') end 
		if (mw.ustring.match(ac, '^[А-ЯЁ][а-яё][а-яё]+ [А-ЯЁ][а-яё][а-яё]+[ое]ва?$')) then pat = mw.ustring.match(ac,'[А-ЯЁ][а-яё]+$') end 
	end
	if (pat) then return generalCase({['отчество'] = pat, ['фамилия'] = bc}, 'болгарское') else return '' end
end


--ФУНКЦИИ ДЛЯ СЛУЧАЕВ, КОГДА АРГУМЕНТЫ НЕ ЗАДАНЫ

function givenNoArgs.kazakhstan () --Казахстан
	local pat 
	local bc = getNameFromTitleBeforeComma ()
	local ac = getNameFromTitleAfterComma ()
	if (mw.ustring.match(bc, '^[АБГ-ХШЫЬЯ][абг-хшыья][абг-хшыья][абг-хшыья][абг-хшыья]+в?а?$')) then 
		pat = ustring.match (ac, '^[АБГ-ХШЫЬЯ][абг-хшыья][абг-хшыья][абг-хшыья]+ ([АБГ-ХШЫЬЯ][абг-хшыья][абг-хшыья][абг-хшыья]+улы)$') or ustring.match (ac, '^[АБГ-ХШЫЬЯ][абг-хшыья][абг-хшыья][абг-хшыья]+ ([АБГ-ХШЫЬЯ][абг-хшыья][абг-хшыья][абг-хшыья]+кызы)$')  
	end
	if (pat) then return 'Здесь ' .. pat ..' — отчество этого человека; см [[Тюркское отчество]].' else return '' end 
end

function givenNoArgs.spanishWorld () --Испаноязычные страны
	local sf, ff
	local bc = getNameFromTitleBeforeComma ()
	local ac = getNameFromTitleAfterComma ()
	local fn = getFullNameFromText ()
	if (mw.ustring.match(bc, '^[А-ЯЁ][а-яё][а-яё][а-яё]+$')) then
		ff = bc
		if (mw.ustring.match(ac, '^[А-ЯЁ][а-яё][а-яё]+$')) then sf = mw.ustring.match (fn, '^' .. ac .. ' ' .. bc .. ' ([А-ЯЁ][а-яё][а-яё][а-яё]+)$') or  mw.ustring.match (fn, '^' .. ac .. ' [А-ЯЁ][а-яё][а-яё]+ ' .. bc .. ' ([А-ЯЁ][а-яё][а-яё][а-яё]+)$') end
		if (mw.ustring.match(ac, '^[А-ЯЁ][а-яё][а-яё]+ [А-ЯЁ][а-яё][а-яё]+$')) then sf = mw.ustring.match (fn, '^' .. ac .. ' ' .. bc .. ' ([А-ЯЁ][а-яё][а-яё][а-яё]+)$') end
	end
	if (sf and ff) then return generalCase ({['фамилия'] = ff, ['вторая фамилия'] = sf}, 'испанское') else return '' end
end

function givenNoArgs.azerbaijan () --Азербайджан
	local pat, text
	local bc = getNameFromTitleBeforeComma ()
	local ac = getNameFromTitleAfterComma ()
	local fn = getFullNameFromText ()
	if (mw.ustring.match (bc,'^[А-ЯЁ][а-яё][а-яё]+[ое]ва?$') or mw.ustring.match (bc,'^[А-ЯЁ][а-яё][а-яё]+л[ыи]$')or mw.ustring.match (bc,'^[А-ЯЁ][а-яё][а-яё]+заде$')) then 
		pat = mw.ustring.match (ac,'^[А-ЯЁ][а-яё][а-яё]+ ([А-ЯЁ][а-яё][а-яё]+ огл[ыу])$') or mw.ustring.match (ac,'^[А-ЯЁ][а-яё][а-яё]+ ([А-ЯЁ][а-яё][а-яё]+ кызы)$') 
		if (not pat and mw.ustring.match (ac, '^[А-ЯЁ][а-яё][а-яё]+$') )then 
			pat = mw.ustring.match (fn, '^'..ac..' ([А-ЯЁ][а-яё][а-яё]+ огл[ыу]) '..bc..'$') or mw.ustring.match (fn, '^'..ac..' ([А-ЯЁ][а-яё][а-яё]+ кызы) '..bc..'$') or ''
		end
	end

	if (pat) then text = 'Здесь ' .. pat ..' — отчество этого человека; см [[Тюркское отчество]].' end
	return text or ''
end

function givenNoArgs.bulgaria () --Болгария
	local pat
	local bc = getNameFromTitleBeforeComma ()
	local ac = getNameFromTitleAfterComma ()
	local fn = getFullNameFromText ()
	if (mw.ustring.match(bc, '^[А-ШЭ-Я][а-шыэ-я][а-шыэ-я][а-шыэ-я]?[а-шыэ-я]?[а-шыэ-я]?[а-шыэ-я]?[а-шыэ-я]?[а-шыэ-я]?[ое]ва?$') and mw.ustring.match(ac, '^[А-ШЭ-Я][ёа-шыэ-я][а-шыэ-я][а-шыэ-я][а-шыэ-я]?[а-шыэ-я]?[а-шыэ-я]?[а-шыэ-я]?[а-шыэ-я]?$')) then 
		pat = mw.ustring.match (fn, '^' .. ac .. ' ([А-ШЭ-Я][а-шыэ-я][а-шыэ-я][а-шыэ-я]?[а-шыэ-я]?[а-шыэ-я]?[а-шыэ-я]?[а-шыэ-я]?[а-шыэ-я]?[ое]ва?) ' .. bc) 
	end
	if (pat) then return generalCase({['отчество'] = pat, ['фамилия'] = bc}, 'болгарское') else return '' end
end
	


--ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ

function seeMoreAbout (givenNation) 
	if (givenNation and not (givenNation == '')) then 
		local title = mw.title.new(givenNation .. ' имя')
		if(title.exists) then return '; см. [[' .. title.text .. ']]' end 
	end
return '' 
end

function getNameFromTitleBeforeComma ()
	local titles = mw.title.getCurrentTitle ()
	local  title = titles.text
	title = mw.ustring.gsub (title, ' %(.+$', '')
	return mw.ustring.match (title, '(.+), ') or ''
end

function getNameFromTitleAfterComma ()
	local titles = mw.title.getCurrentTitle ()
	local  title = titles.text
	title = mw.ustring.gsub (title, ' %(.+$', '')
	return mw.ustring.match (title, ', (.+)') or ''
end

function getNameFromTitleIfNoComma ()
	local titles = mw.title.getCurrentTitle ()
	local  title = titles.text
	title = mw.ustring.gsub (title, ' %(.+$', '')
	if (mw.ustring.match(title, ',')) then title = '' end
	return title or ''
end

function getFullNameFromText () -- кавыч. сноски, скобки, поле полн. имя, дефисы, ап-фы
	local titles = mw.title.getCurrentTitle ()--new('Дос Сантос, Джовани')
	local text = titles:getContent(); text  = mw.ustring.gsub (text, '́', '')
	local title = titles.text
	local titleone = mw.ustring.match (title, '[А-ЯЁ]([А-Яа-яЁё]+)')
	local titletwo = mw.ustring.match (title, ' ([А-ЯЁ][А-Яа-яЁё]*)')
	local fullname
	if (titleone and titletwo) then fullname = mw.ustring.match (text, '\'\'\'([А-Яа-яЁё]*%s*[А-Яа-яЁё]*%s*[А-Яа-яЁё]*%s*[А-Яа-яЁё]*%s*[А-Яа-яЁё]*%s*'.. titletwo .. '%s*[А-Яа-яЁё]*%s*[А-Яа-яЁё]*%s*[А-Яа-яЁё]*%s*[А-Яа-яЁё]*%s*[А-Яа-яЁё]' ..titleone..  '%s*[А-Яа-яЁё]*%s*[А-Яа-яЁё]*%s*[А-Яа-яЁё]*%s*[А-Яа-яЁё]*%s*[А-Яа-яЁё]*)\'\'\'') or mw.ustring.match (text, '\'\'\'([А-Яа-яЁё]*%s*[А-Яа-яЁё]*%s*[А-Яа-яЁё]*%s*[А-Яа-яЁё]*%s*[А-Яа-яЁё]'.. titleone .. '%s*[А-Яа-яЁё]*%s*[А-Яа-яЁё]*%s*[А-Яа-яЁё]*%s*[А-Яа-яЁё]*%s*[А-Яа-яЁё]*%s*' ..titletwo..  '%s*[А-Яа-яЁё]*%s*[А-Яа-яЁё]*%s*[А-Яа-яЁё]*%s*[А-Яа-яЁё]*%s*[А-Яа-яЁё]*)\'\'\'') end
	return fullname or ''
end
	
return p