Module:ig-conj

From Wiktionary, the free dictionary
Jump to navigation Jump to search

local export = {}

local u = mw.ustring.char

local ACUTE =  u(0x0301)
local MACRON = u(0x0304)
local GRAVE =  u(0x0300)
local DOT =    u(0x0323)
local diacritics = ACUTE .. MACRON .. GRAVE .. DOT

function export.verb(frame) 
	return make_table(nil)
end

function export.infinitive(base)
	local decomposed = mw.ustring.toNFD(base)
	local inf_prefix
	if isATR(decomposed) then
		inf_prefix = "i" .. ACUTE
	else
		inf_prefix = "i" .. DOT .. ACUTE
	end
	
	local syllables = {}
	for syll in mw.ustring.gmatch(decomposed, "[^aeiou]*[aeiou]["..diacritics.."]*") do
		local i = mw.ustring.find(syll, "["..ACUTE..MACRON..GRAVE.."]")
		local tone = mw.ustring.sub(syll, i, i)
		local toneless_syll = mw.ustring.sub(syll, 1, i-1) .. mw.ustring.sub(syll, i+1)
		table.insert(syllables, {toneless_syll, tone})
	end
	
	-- Apply raising rule
	if #syllables >= 2 and syllables[1][2] == GRAVE and syllables[2][2] == GRAVE then
		syllables[1][2] = ACUTE
	end
	
	-- Apply rightward lowering rule
	local grave_index
	for i, syll in ipairs(syllables) do
		if syll[2] == GRAVE then
			grave_index = i
			break
		end
	end
	
	if grave_index then
		for i=grave_index+1, #syllables do
			if syllables[i][2] == ACUTE then
				syllables[i][2] = GRAVE
			end
		end
	end
	
	-- Apply downstep
	if syllables[1][2] == ACUTE then
		syllables[1][2] = MACRON
	end
	
	local combined = ""
	for _, syll in ipairs(syllables) do
		combined = combined .. table.concat(syll)
	end
	
	return mw.ustring.toNFC(inf_prefix .. combined)
end

function export.participle(base)
	local decomposed = mw.ustring.toNFD(base)
	local participle_prefix
	
	if isATR(decomposed) then
		participle_prefix = "e"
	else
		participle_prefix = "a"
	end
	
	local first_vowel = get_first_vowel(decomposed)
	
	if mw.ustring.find(first_vowel, ACUTE) then
		participle_prefix = participle_prefix .. GRAVE
	else
		participle_prefix = participle_prefix .. ACUTE
	end
	
	return mw.ustring.toNFC(participle_prefix .. decomposed)
end

--This function expects the form to already be in NFD form
function get_first_vowel(decomposed_base)
	local i, j = mw.ustring.find(decomposed_base, "[aeiou]["..DOT..ACUTE..GRAVE..MACRON.."]*")
	return mw.ustring.sub(decomposed_base, i, j)
end

--This function expects the form to already be in NFD form
function isATR(decomposed_base)
	local first_vowel = get_first_vowel(decomposed_base)
	return not mw.ustring.find(first_vowel, "[a"..DOT.."]")
end

function make_table(data)
	local wikicode = {}
	local rows = {
		"infinitive",
		"participle",
		"imperative",
		"subjunctive",
		"simple present",
		"indicative",
		"perfective"
	}
	table.insert(wikicode, "{| class=\"wikitable\"")
	table.insert(wikicode, "|+ Conjugation of ??")
	table.insert(wikicode, "|-")
	table.insert(wikicode, "!  !! Positive !! Negative")
	table.insert(wikicode, "|-")
	for _, row in ipairs(rows) do
		table.insert(wikicode, "! " .. row)
		table.insert(wikicode, "| ||")
		table.insert(wikicode, "|-")
	end
	table.insert(wikicode, "|}")

	return table.concat(wikicode, "\n")
end

return export