Documentation for this module may be created at Մոդուլ:ձևույթ/doc

-- Модуль:морфо v1.1.3
-- 2016-03-31

local export = {}
local u = require("Module:utils")
local wu = require("Module:wiki-utils")

-- TODO: трансфиксы в арабском, и инфиксы в латыни // отменяется?
-- TODO: источники вынести в data-модуль // переносится на потом

local data = {}
local title
local morphemes = {}
local reference = ''
local categories = ''
local category_replacements = {}
local skip_categories = false

local DEBUG_CATEGORIES = false

local singular = {
	root = 'արմատ',
	prefixoid = 'նախածանցակերպ',
	prefix = 'նախածանց',
	suffix = 'վերջածանց',
	preposition = 'նախդիր',
	postfix = 'լրացուցիչ',
	suffixsoid = 'վերջածանցակերպ',
	interfix = 'միջածանց',
	interfix2 = 'հոդակապ',
	ending = 'վերջավորություն',
	verb_ending = 'բայական վերջավորություն',
}
local plural = {
	prefixoid = 'նախածանցակերպեր',
	prefix = 'նախածանցներ',
	preposition = 'նախդիրներ',
	suffix = 'վերջածանցներ',
	postfix = 'լրացուցիչ',
	suffixsoid = 'վերջածանցակերպեր',
	interfix = 'միջածանցներ',
	interfix2 = 'հոդակապներ',
	ending = 'վերջավորություններ',
	verb_ending = 'բայական վերջավորություններ',
}
local plural_key = {
	prefixoid = 'prefixoids',
	prefix = 'prefixes',
	preposition = 'prepositions',
	suffix = 'suffixes',
	postfix = 'postfixes',
	suffixsoid = 'suffixsoids',
	interfix = 'interfixes',
	interfix2 = 'interfixes2',
	ending = 'endings',
	verb_ending = 'verb_endings',
}
local instrumental = {
	prefixoid = 'նախածանցակերպով',
	prefix = 'նախածանցով',
	preposition = 'նախդիրով',
	suffix = 'վերջածանցով',
	postfix = 'լրացուցիչ',
	suffixsoid = 'վերջածանցակերպով',
	interfix = 'միջածանցով',
	interfix2 = 'հոդակապով',
}
local notation = {
	root = 'R',
	prefixoid = 'R',
	prefix = 'pr',
	suffix = 's',
	preposition = 'prep',
	postfix = 'pt',
	suffixsoid = 'R',
	interfix = 'i',
	interfix2 = 'i',
	ending = 'f',
	verb_ending = 'f',
}

-- Утилитная функция для формирования wiki-кода для категории
function set_category(name)
	return ' {{#ifeq:{{NAMESPACE}}|{{ns:0}}|[[Կատեգորիա:' .. name .. ']]}}'
end

function add_morpheme(m_type, m_value)
	table.insert(morphemes, {m_type=m_type, m_value=m_value})
end

function add_category(name)
	categories = categories .. set_category(name)
	if DEBUG_CATEGORIES then
		categories = categories .. wu.span_silver(' [Կատեգորիա:' .. name .. ']')
	end
end

function process_data()
	for _, values in pairs(data['category_replacements']) do
		category_replacements[values[1]] = values[2]
	end
end

function parse_morphemes(args)
	for key, value in pairs(args) do
		cleared_value = mw.ustring.gsub(value, '[()]', '')
		if type(key) == 'number' then
			if mw.ustring.match(value, "^%-%-") ~= nil then
				value = mw.ustring.sub(value, 2) 
				add_morpheme('suffixsoid', value)
			elseif mw.ustring.match(value, "%-%-$") ~= nil then
				value = mw.ustring.sub(value, 1, -2)
				add_morpheme('prefixoid', value)
			elseif mw.ustring.match(value, "^%+.*%+$") ~= nil then
				add_morpheme('interfix', value)
			elseif mw.ustring.match(value, "^%-.*%-$") ~= nil then
				add_morpheme('interfix2', value)
			elseif mw.ustring.match(value, "%-$") ~= nil then
				value = mw.ustring.sub(value, 1, -2)
				add_morpheme('prefix', value..'-')
			elseif mw.ustring.match(value, "%+$") ~= nil then
				value = mw.ustring.sub(value, 1, -2)
				add_morpheme('preposition', value..'+')
			elseif mw.ustring.match(value, "^%-") ~= nil then
				if u.contains(data['known_morphemes']['postfixes'], cleared_value) then
					add_morpheme('postfix', value)
				else
					add_morpheme('suffix', value)
				end
			elseif mw.ustring.match(value, "^%+") ~= nil then
				fix_value = '-'..mw.ustring.sub(value, 2)
				if u.contains(data['known_morphemes']['verb_endings'], cleared_value) then
					add_morpheme('verb_ending', fix_value)
				else
					add_morpheme('ending', fix_value)
				end
			elseif value ~= '' then
				add_morpheme('root', value)
			end
		else
			if key == 'и' then
				if value == 'т' then
					reference = '{{Тихонов}}'
				elseif value == 'т2' or value == 'т-ся' then
					if u.endswith(title, 'ся') then
						reference = '{{Тихонов|' .. mw.ustring.sub(title, 1, -3) .. '(ся)}}'
					else
						reference = '{{Тихонов|2=(ся)}}'
					end
				elseif value == 'т-сь' then
					if u.endswith(title, 'сь') then
						reference = '{{Тихонов|' .. mw.ustring.sub(title, 1, -3) .. '(сь)}}'
					else
						reference = '{{Тихонов|2=(сь)}}'
					end
				elseif u.startswith(value, 'т:') then
					reference = '{{Тихонов|' .. mw.ustring.sub(value, 3) .. '}}'
				elseif u.contains({'е'}, value) then
					reference = '{{Ефремова}}'
					skip_categories = true
				elseif u.contains({'к', 'ке', 'к,е', 'к, е'}, value) then
					reference = '{{Кузнецова и Ефремова}}'
					skip_categories = true
				else
					-- reference = wu.span_red('(неизвестный источник)')
					reference = ''
				end
			end
		end
	end
end

function prepare_output()
	if #morphemes == 0 then
		return "Корень: '''--'''." .. set_category('Нет сведений о составе слова/ru')
	end
	local items = {}
	local structure = {}
	local has_root = false
	local unknown_affix = false
	--local wrong_characters = false -- TODO
	local check_title = ''
	for i, morpheme in pairs(morphemes) do
		local m_type = morpheme['m_type']
		local m_value = morpheme['m_value']
		local m_cat_value = mw.ustring.lower(mw.ustring.gsub(m_value, '[()]', ''))
		--if mw.ustring.match(mw.ustring.lower(m_value), '^[-+ա-ֆևւj∅’()]*$') == nil and mw.ustring.match(m_value, '^-[A-Za-z]*-$') == nil then
			--wrong_characters = true
		--end
		local check_morpheme = mw.ustring.gsub(m_value, '[-+j∅]', '')
		check_morpheme = mw.ustring.gsub(check_morpheme, '%(.+%)', '')
		check_title = check_title .. check_morpheme
		local m_title = singular[m_type]
		if u.contains({'prefix', 'prefixoid', 'suffix', 'preposition', 'suffixoid', 'postfix', 'interfix', 'interfix2'}, m_type) then
			if category_replacements[m_cat_value] then
				m_cat_value = category_replacements[m_cat_value]
			end
		end
		-- local m_cat_value = mw.ustring.gsub(m_value, '%/.*', '')
		-- m_value = mw.ustring.gsub(m_value, '%/', '{{!}}')
		table.insert(structure, notation[m_type])
		if u.contains({'prefixoid', 'prefix', 'suffix', 'postfix', 'preposition', 'interfix', 'interfix2', 'suffixsoid'}, m_type) then
			if m_type ~= 'interfix' and not skip_categories then
				add_category('Հայերեն բառեր ' .. m_cat_value .. ' ' .. instrumental[m_type] )  -- категоризация по типам морфем
				m_value = '[[' .. m_cat_value .. '|' .. m_value .. ']]' -- добавление ссылки для морфемы
			end
			if i > 1 and morphemes[i-1]['m_type'] == m_type then
				m_title = ''  -- пропуск заголовка, если предыдущая морфема была того же типа
			elseif i < #morphemes and morphemes[i+1]['m_type'] == m_type then
				m_title = plural[m_type]  -- использование множественного числа, если несколько подряд морфем одного типа
			end
		end
		if u.contains({'prefixoid', 'prefix', 'suffix', 'postfix', 'preposition', 'interfix', 'interfix2', 'ending'}, m_type) and not skip_categories then
			key = plural_key[m_type]
			value = m_cat_value
			if m_type == 'ending' then
				value = mw.ustring.gsub(m_cat_value, '^%-', '+')
			elseif m_type == 'prefixoid' then
				value = mw.ustring.gsub(m_cat_value, '%-$', '--')
			end
			if not u.contains(data['known_morphemes'][key], value) then
				unknown_affix = true  -- категоризация неизвестных морфем
				m_value = m_value .. wu.span_red("<sup>?</sup>")  -- добавление красного вопросика
			end
		end
		if m_type == 'root' then
			has_root = true
		end
		if m_title ~= '' then
			item = m_title .. '՝ ' .. "'''" .. m_value .. "''',"
			table.insert(items, item)
		else
			if m_type == 'interfix' and mw.ustring.sub(items[#items], -5, -5) ~= '>' then
				items[#items] = mw.ustring.sub(items[#items], 1, -6) .. m_value .. "''',"
			else
				items[#items] = mw.ustring.sub(items[#items], 1, -5) .. m_value .. "''',"
			end
		end
	end
	if not skip_categories then
		add_category('Հայերեն բառեր ' .. table.concat(structure, '-') .. ' ձևույթային կառույցով')
		if unknown_affix then
			add_category('Սխալ ձևույթային կառույցում (սխալ ածանց)/hy')
		end
	end
	if not has_root then
		add_category('Սխալ ձևույթային կառույցում (արմատը  չկա)/hy')
	end
	--if wrong_characters then
		--add_category('Ошибка в морфемном разборе (недопустимые символы)/ru')
	--end
	--local title_without_hyphens = mw.ustring.gsub(title, '[-]', '')
	-- mw.log('"' .. title_without_hyphens .. '"')
	-- mw.log('"' .. check_title .. '"')
	--if check_title ~= title_without_hyphens then
		--add_category('Սխալ ձևույթային արժեք (չի համապատասխանում սկզբնական բառին)/hy')
	--end
	local output = table.concat(items, ' ')
	local result = mw.ustring.sub(u.capfirst(output), 1, -2)
	if reference ~= '' then
		result = result .. ' ' .. reference
	end
	result = result .. ':' .. categories
	return result
end

function generate_docs()
	result = ''
	for i, m_type in pairs({'prefix', 'prefixoid', 'interfix', 'interfix2', 'preposition', 'suffix', 'suffixsoid', 'ending', 'verb_ending', 'postfix'}) do
		result = result .. "===" .. u.capfirst(plural[m_type]) .. "===" .. '\n'
		result = result .. "{{col|5}}\n"
		values = data['known_morphemes'][plural_key[m_type]]
		empty = true
		for i, value in pairs(values) do
			empty = false
			value = mw.ustring.gsub(value, '%-%-', '-')
			value = mw.ustring.gsub(value, '%+', '-')
			if u.contains({'prefixoid', 'prefix', 'suffix', 'postfix', 'preposition', 'suffixsoid'}, m_type) then
				cat_name = 'Русские слова с ' .. instrumental[m_type] .. ' ' .. value
				result = result .. "# '''[[" .. value .. "]]'''" .. ' ([[:Կատեգորիա:' .. cat_name .. "|կատ]])\n"  -- {{PAGESINCAT:" .. cat_name .. "}}
			else
				result = result .. "# '''" .. value .. "'''\n"
			end
		end
		result = result .. "{{col-bottom}}\n"
		if empty then
			result = result .. "# ''դատարկ''\n"
		end
	end
	return result
end

-- Главная функция, которая вызывается в модуле.
function export.get(frame)
	local lang = frame.args['lang']
	local args = u.clone(frame:getParent().args)
	title = u.get_base()
	data = mw.loadData("Module:ձևույթ/data/" .. lang);
	process_data()
	parse_morphemes(args)
	return frame:preprocess(prepare_output())
end

-- Функция, для генерации документации дата-модуля.
function export.docs(frame)
	local lang = frame.args['lang']
	data = mw.loadData("Module:ձևույթ/data/" .. lang);
	return frame:preprocess(generate_docs())
end

return export