Jump to content

Modulus:grc-accent

E Victionario

Purpose

[+/-]

This template is used by Ancient Greek inflection tables to generate the correct accent on a root. It should not be used directly.


local export = {}

local m_utilities = require('Module:grc-utilities')
local m_data = mw.loadData("Module:grc-utilities/data")

local acute = '́'
local grave = '̀'
local circumflex = '͂'
local diaeresis = '̈'
local smooth = '̓'
local rough = '̔'
local macron = '̄'
local breve = '̆'
local subscript = 'ͅ'

local diacritics = m_data.all
local diacritics_tone = '['..acute..grave..circumflex..']'

local sub = mw.ustring.sub
local gsub = mw.ustring.gsub
local match = mw.ustring.match

function export.strip_accent(word)
	word = mw.ustring.toNFD(word)
	return gsub(word, diacritics, '')
end

function isvowel(token)
	return match(token,'[ΑΕΗΙΟΥΩαεηιουω]')
end

function isshort(token)
	if match(token,breve) then return true end
	return match(token,'[ΕΟεο]') and not match(token,'[ιυ]')
end

function export.strip_tone(word)
	local tokens = m_utilities.tokenize(word)
	local out = ''
	for i=1,#tokens do
		local t = tokens[i]
		if match(t,'^[αΑιΙυΥ]['..smooth..rough..diaeresis..']*'..circumflex..'$') then
			--give it a long mark
			t = sub(t,1,1)..macron..sub(t,2)
		end
		out = out .. gsub(t,diacritics_tone,'')
	end
	return out
end

function export.ult(word)
	word = mw.ustring.toNFD(word)
	if match(word,diacritics_tone) then return word end
	
	word = m_utilities.tokenize(word)
	for i = #word, 1, -1 do
		if isvowel(word[i]) then
			--fortunately accents go last in combining order
			word[i] = word[i] .. acute
			word[i] = gsub(word[i],subscript..acute,acute..subscript)
			break
		end
	end
	return table.concat(word,'')
end

--[[ WARNING: Given an unmarked α ι υ, this function will return a circmflex.
That said, if you ran into this situation in the first place, you probably
are doing something wrong. ]]--
function export.circ(word)
	word = mw.ustring.toNFD(word)
	if match(word,diacritics_tone) then return word end
	
	word = m_utilities.tokenize(word)
	for i = #word, 1, -1 do
		if isvowel(word[i]) then
			if isshort(word[i]) then
				word[i] = word[i]..acute
			else
				word[i] = word[i]..circumflex
				word[i] = gsub(word[i],subscript..circumflex,circumflex..subscript)
				word[i] = gsub(word[i],macron,'')
			end
			break
		end
	end
	return table.concat(word,'')
end

function export.penult(orig)
	word = mw.ustring.toNFD(orig)
	if match(word,diacritics_tone) then return word end
	
	word = m_utilities.tokenize(word)
	local syllables = 0
	for i = #word, 1, -1 do
		if word[i] == '-' then return orig end
		if isvowel(word[i]) then
			syllables = syllables + 1
			if syllables == 2 then
				word[i] = word[i] .. acute
				word[i] = gsub(word[i],subscript..acute,acute..subscript)
				return table.concat(word,'')
			end
		end
	end
	
	return export.circ(orig)
end

function export.pencirc(orig)
	word = mw.ustring.toNFD(orig)
	if match(word,diacritics_tone) then return word end
	
	word = m_utilities.tokenize(word)
	local syllables = 0
	local longult = false
	for i = #word, 1, -1 do
		if word[i] == '-' then return orig end
		if isvowel(word[i]) then
			syllables = syllables + 1
			if syllables == 1 and not isshort(word[i]) then
				longult = true
				if word[#word] == 'αι' or word[#word] == 'οι' then longult = false end
			elseif syllables == 2 then
				if isshort(word[i]) or longult then
					word[i] = word[i]..acute
					word[i] = gsub(word[i],subscript..acute,acute..subscript)
				else
					word[i] = word[i]..circumflex
					word[i] = gsub(word[i],subscript..circumflex,circumflex..subscript)
					word[i] = gsub(word[i],macron,'')
				end
				return table.concat(word,'')
			end
		end
	end
	
	return export.circ(orig)
end

function export.antepenult(orig)
	word = mw.ustring.toNFD(orig)
	if match(word,diacritics_tone) then return word end
	
	word = m_utilities.tokenize(word)
	local syllables = 0
	local longult = false
	for i = #word, 1, -1 do
		if word[i] == '-' then return orig end
		if isvowel(word[i]) then
			syllables = syllables + 1
			if syllables == 1 and not isshort(word[i]) then
				longult = true
				if word[#word] == 'αι' or word[#word] == 'οι' then longult = false end
			elseif syllables == 2 and longult then
				word[i] = word[i] .. acute
				word[i] = gsub(word[i],subscript..acute,acute..subscript)
				return table.concat(word,'')
			elseif syllables == 3 then
				word[i] = word[i] .. acute
				word[i] = gsub(word[i],subscript..acute,acute..subscript)
				return table.concat(word,'')
			end
		end
	end
	
	return export.pencirc(orig)
end

return export