Модуль:Find country (Bk;rl,&Find country)

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

Использование

Для использования через Шаблон:Поиск страны. См. документацию там.

Список стран: Модуль:Find country/countries.json.

См. также

local getArgs = require('Module:Arguments').getArgs
local data = mw.loadJsonData('Module:Find_country/countries.json')
local p = {}

-- config
local nomatch = ""
local matchnum = 1
local default_case = "именительный" -- default case

-- function to escape patterns for string.match
local function escapePattern(pattern)
	return pattern:gsub("([%[%]%(%)%^%$%+%-%*%?])", "%%%1")
end

-- function to find country in string
function p.findcountryinstring(str, case)
	str = " " .. str:gsub("^%s*(.-)%s*$", "%1") .. " "

	-- Replace single quotes with typographic quotes
	str = str:gsub("'", "’")
	
	local matches = {}
	
	for _, group in ipairs(data) do
		for _, country in ipairs(group.countries) do
			for case_name, case_value in pairs(country.cases) do
				local escapedPattern = escapePattern(case_value)
				local sPos, ePos = string.find(str, escapedPattern)
				if sPos then
					local result
					if case_name == "unique" then
						result = case_value
						if case == "предлог" and country["предлог"] then
							result = country["предлог"] .. " " .. result
						end
					else
						if case == "предлог" and country.cases["предложный"] then
							result = country["предлог"] .. " " .. country.cases["предложный"]
						else
							result = country.cases[case] or country.cases[default_case]
						end
					end
					-- Add match to 'matches' with position
					table.insert(matches, {result = result, position = sPos})
					break -- Stop checking other cases for this country
				end
			end
		end
	end

	if #matches == 0 then
		return nomatch
	end

	-- Sort matches by position
	table.sort(matches, function(a, b) return a.position < b.position end)

	-- Get the correct match according to 'matchnum'
	if matchnum >= 1 and matchnum <= #matches then
		return matches[matchnum].result
	elseif matchnum < 0 and (-matchnum) <= #matches then
		return matches[#matches + matchnum + 1].result
	else
		return nomatch
	end
end

function p.main(frame)
	local args = getArgs(frame)
	return p._main(args)
end

function p._main(args)
	if (args['nomatch'] ~= nil) then
		nomatch = args['nomatch']
	end

	if (args['match'] ~= nil) then
		matchnum = tonumber(args['match'])
		if ((matchnum == nil) or (matchnum == 0)) then
			matchnum = 1
		end
	end

	local case = args['case'] or default_case -- get the case from args, use default_case if not provided

	local thisstring
	if ((args['string'] ~= nil) and (args['string'] ~= "")) then
		thisstring = args['string']
	else
		local thispage = mw.title.getCurrentTitle()
		thisstring = thispage.text
	end

	local result = p.findcountryinstring(thisstring, case)
	if (result == "") then
		return nomatch
	end
	return result
end

-- Function to list all countries
function p.listCountries()
	local countryList = {}
	for _, group in ipairs(data) do
		for _, country in ipairs(group.countries) do
			if country.cases["unique"] then
				table.insert(countryList, country.cases["unique"])
			else
				table.insert(countryList, country.cases[default_case])
			end
		end
	end
	return table.concat(countryList, ", ")
end

return p