Модуль, реализующий шаблон {{ФИО}}.


local get_args = require('Модуль:Arguments').getArgs
local mHatnote = require('Модуль:Hatnote')
local mOtheruses = require('Модуль:Другие значения')
local current_title = mw.title.getCurrentTitle().text

local p = {}
local templates = {
	'[сС]писок однофамильцев',
	'[сС]писок т[ёе]зок',
	'[сС]писок полных т[ёе]зок',
	'[сС]писок однофамильцев-т[eё]зок',
	'[сС]писок т[её]зок-однофамильцев'
}
local disambig_box_names = {
	'[нН]еоднозначность',
	'[мМ]ногозначность',
	'[dD]isambig'
}
local disambig_box_params = {
	'[фФ]амилии',
	'[оО]днофамильцы',
	'[тТ][ёе]зки',
	'[оО]днофамильцы-т[ёе]зки',
	'[пП]олные т[ёе]зки'
}
local tracking_categories = {
	bad_link = 'Викиучебник:Страницы с шаблоном ФИО со ссылкой на общие неоднозначности',
	no_links = 'Викиучебник:Страницы с шаблоном ФИО без ссылок'
}

function is_surname_disambig(title)
	local page = mw.title.new(title)
	
	if not page.exists or mw.title.equals(page, mw.title.getCurrentTitle()) then
		return false 
	end
	
	local page_content = page:getContent():gsub('<[^>]*>', '')
	for i, template in ipairs(templates) do
		if mw.ustring.match(page_content, '{{' .. template) then
			return true
		end
	end
	for i, name in ipairs(disambig_box_names) do
		for j, param in ipairs(disambig_box_params) do
			if mw.ustring.match(page_content, string.format('{{%s[^}]*%s', name, param)) then
				return true
			end
		end
	end
    return false
end
    
function get_items(title)
	title = mHatnote.remove_precision{title or current_title}
	local surname = title:match('^[^,]+')
	local surname_with_name = title:match('^[^,]+,%s[^%s]+')
	local full_name = title:match('^[^,]+,%s[^%s]+%s[^%s]+')

	return {surname, surname_with_name, full_name}
end

function find_disambig(title, categories)
	local disambig_page = ''
	local without = mHatnote.remove_precision{title or current_title}
	local with = without .. ' (значения)'
	
	if is_surname_disambig(without) then
		disambig_page = without
	elseif is_surname_disambig(with) then
		disambig_page = with
	elseif mw.title.new(with).exists then
		categories:add('bad_link')
		disambig_page = with
	elseif mHatnote.is_disambig{without} then
		categories:add('bad_link')
		disambig_page = without
	end
	
	return disambig_page, without
end

p['ФИО'] = function (frame)
	local args = get_args(frame)
	local title = args.title or args[1]
	local categories = mHatnote.make_categories(tracking_categories)
	
	local hatnote_args = {
		prefix = 'В Викиучебнике есть статьи о других людях с такой фамилией, см.',
		list_sep = '; ',
		hide_disambig = true,
		dot = true,
		preview_error = true,
		natural_join = false
	}
	local found = false
	local lNum = 0
	for i, v in ipairs(get_items(title)) do
		a,b = find_disambig(v, categories)
		if a~='' and a~=title and a~=current_title then
			lNum = lNum + 1
			hatnote_args[lNum], hatnote_args['l' .. lNum] = a,b
			found=true
		end
	end
	
	if found then
		return mHatnote.main(hatnote_args) .. categories
	else
		return ''
	end
end

function tgen(frame, type, num)
	return function (frame)
		local args = get_args(frame)
		local categories = mHatnote.make_categories(tracking_categories)
		local hatnote_args = {
			type = type,
			preview_error = true
		}
		
		local i = 1
		repeat
			local link, label = find_disambig(get_items(args[i])[num], categories)
			hatnote_args[i] = link or args[i]
			hatnote_args['l' .. i] = args['l' .. i] or label
			i = i + 1
		until not args[i]
		
		return mOtheruses.main(hatnote_args) .. categories
	end
end

p['однофамильцы'] = tgen(frame, 'фамилия', 1)
p['однофамильцы-тёзки'] = tgen(frame, 'имя и фамилия', 2)
p['полные тёзки'] = tgen(frame, 'фио', 3)

return p