Module:accel/grc

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

This module contains new entry creation rules for Ancient Greek; see WT:ACCEL for an overview, and Module:accel for information on creating new rules.


-- To do: add dialect labels, at least for non-Attic dialects.
-- Ideally, dialectal lemmas and non-lemma forms should be in different
-- categories, but no infrastructure for that exists yet.
-- Fix acceleration of second-declension adjectives: feminine is missing.
-- [[Special:Diff/50392096]]
local function chars(content) return "{{subst:chars|grc|" .. content .. "}}" end

local function accent_recessively(form)
	local m_accent = require "Module:grc-accent"
	return m_accent.add_accent(m_accent.strip_tone(form), -3)
end

local function get_participle_information(masculine)
	local decl, feminine, neuter

	if masculine:find("ος$") then
		decl = "1&2"
		feminine = accent_recessively(masculine:gsub("ος$", "η"))
		neuter = masculine:gsub("ς$", "ν")
	else
		decl = "1&3"

		local m_utilities_data = require "Module:grc-utilities/data"
		-- Warning! This pattern will not work if there's a vowel before the
		-- participle ending, as in τεθνεώς, perfect active participle of
		-- θνῄσκω.
		local ending = mw.ustring.match(mw.ustring.toNFD(masculine),
										m_utilities_data.vowel .. "[^" ..
											m_utilities_data.vowels .. "]+$")

		if ending then
			local m_accent = require "Module:grc-accent"
			ending = m_accent.strip_tone(ending)

			local accent_pos, accent_type = m_accent.detect_accent(masculine)

			if ending == "ων" then -- recessive, oxytone, properispomenon
				local stem = mw.ustring.gsub(mw.ustring.toNFD(masculine),
											 "ω[" ..
												 m_utilities_data.diacritics
													 .acute ..
												 m_utilities_data.diacritics
													 .circum .. "]?ν$", "")
				feminine = stem .. "ουσᾰ"
				if accent_type == "circumflex" then
					-- τῑμῶν, τῑμῶσᾰ, τῑμῶν
					neuter = target
				else
					-- λέγων, λέγουσα, λέγον
					-- λαβών, λαβοῦσᾰ, λαβόν
					neuter = stem .. "ον"
				end
			elseif ending == "ᾱς" then -- recessive except in athematic verbs
				stem = mw.ustring.gsub(mw.ustring.toNFD(masculine),
									   "α" ..
										   m_utilities_data.diacritics.macron ..
										   m_utilities_data.diacritics.acute ..
										   "?ς", "")
				feminine = stem .. "ᾱσᾰ"
				neuter = stem .. "ᾰν"

				-- Aorist passive or athematic; always oxytone?
			elseif ending == "εις" then
				stem = masculine:gsub("είς", "")
				feminine = stem .. "εῖσᾰ"
				neuter = stem .. "έν"
			elseif ending == "ως" then -- Perfect active; always oxytone?
				stem = masculine:gsub("ώς", "")
				feminine = stem .. "υῖᾰ"
				neuter = stem .. "ός"

				-- Present active, δεικνῡ́ς and such
			elseif ending == "ῡς" then
				stem = masculine:gsub("ῡ́ς", "")
				feminine = stem .. "ῦσᾰ"
				neuter = stem .. "ῠ́ν"
			end

			if feminine and neuter then
				feminine, neuter = m_accent.add_accent(feminine, accent_pos),
								   m_accent.add_accent(neuter, accent_pos)
			end
		end
	end

	return decl, feminine, neuter
end

-- Determine lemma (masculine nominative singular form)
local function get_participle_lemma(feminine_or_neuter)
	local lemma

	if mw.ustring.find(feminine_or_neuter, "μ[εέ]ν[ηο]ν?$") then
		local stem = mw.ustring.match(feminine_or_neuter,
									  "^(.+μ[εέ]ν)[ηο]ν?$")
		lemma = accent_recessively(stem .. "ος")
	else
		local m_utilities_data = require "Module:grc-utilities/data"
		local stem, ending = mw.ustring.match(mw.ustring.toNFD(
												  feminine_or_neuter),
											  "^(.-)([αεουω][ιυ]?" ..
												  m_utilities_data.diacritic ..
												  "*[σςν]?α?" ..
												  m_utilities_data.diacritics
													  .breve .. "?)$")

		ending = mw.ustring.toNFC(ending)

		-- [αεοω][ιυ]?[accents][σςν]?ᾰ??
		if ending == "εῖσᾰ" or ending == "έν" then
			lemma = stem .. "είς"
		elseif ending == "ῶσᾰ" or ending == "ῶν" then
			lemma = stem .. "ῶν"
		elseif ending == "ᾶσᾰ" then
			lemma = stem .. "ᾱ́ς"
			-- Need to distinguish contracted present-tense verbs
			-- from second aorists! δούς can maybe be neglected.
		elseif ending == "οῦσᾰ" or ending == "όν" then
			lemma = stem .. "ών"
		elseif ending == "ουσᾰ" or ending == "ον" then
			lemma = stem .. "ων"
		elseif ending == "υῖᾰ" or ending == "ός" then
			lemma = stem .. "ώς"
		elseif ending == "ῦσᾰ" or ending == "ῠ́ν" then
			lemma = stem .. "ῡ́ς"
		end
	end

	return lemma
end

return {
	generate = function(params, entry)
		local target = (params.target ~= params.target_pagename and "|" ..
						   params.target or "")
		entry.head = "{{grc-" .. params.pos .. " form" .. target .. "}}"

		-- Comparatives and superlatives don't use {{grc-adjective form}}, but
		-- rather the lemma templates ({{grc-adj-1&2}}, {{grc-adj-3rd}}) with the
		-- parameter |deg=comp or |deg=super, because they have inflected forms
		-- (neuter if they are in the third declension, or feminine and  neuter if
		-- they are in the first and second declension).
		if params.form == "comparative" or params.form == "superlative" then
			local decl, stem, feminine, neuter

			-- Comparatives and superlatives always have recessive accent.
			if params.target_pagename:find("ος$") then
				decl = "1&2"
				stem = params.target:gsub("ος$", "")
				-- Feminine could have ᾱ or η. Add default based on ειρ rule.
				-- This will often be incorrect for dialects without the ᾱ-to-η
				-- shift, like Doric and Aeolic.
				feminine = accent_recessively(stem ..
												  (mw.ustring
													  .find(stem, "[ειρ]$") and
													  "ᾱ" or "η"))

				neuter = params.target:gsub("ς$", "ν")
			elseif params.target_pagename:find("ων$") then
				decl = "3rd"
				stem = params.target:gsub("ων$", "")
				-- Add ending -ον and accent recessively.
				-- This will not generate the correct accent if a macron was omitted
				-- in the masculine form.
				neuter = accent_recessively(params.target:gsub("ων$", "ον"))
			else
				error(
					"Could not determine declension for the " .. params.form ..
						" adjective " .. params.target .. ".")
			end

			local degree_abbrev = params.form == "comparative" and "comp" or
									  "super"

			entry.head = "{{grc-adj-" .. decl .. target

			-- Place feminine and neuter forms in {{chars}} so that editor can easily
			-- correct any errors before saving.
			if feminine then
				entry.head = entry.head .. "|" .. chars(feminine)
			end

			entry.head = entry.head .. "|" .. chars(neuter) .. "|deg=" ..
							 degree_abbrev .. "}}"

			entry.declension = "{{grc-adecl|" ..
								   (decl == "3rd" and neuter or params.target ..
									   "|" .. feminine) .. "|deg=" ..
								   degree_abbrev .. "}}"

			-- Inflected forms of a comparative or superlative.
		else
			local last_code = params.form:match("|(%l+)$")
			if last_code == "comparative" or last_code == "superlative" then
				local degree_abbrev = last_code == "comparative" and "comp" or
										  "super"

				entry.head = "{{grc-" .. params.pos .. " form" .. target ..
								 "|deg=" .. degree_abbrev .. "}}"

				-- Remove |comparative or |superlative from {{inflection of}}
				entry.def = entry.def:gsub("|" .. last_code, "")
			end
		end

		if params.pos == "verb" then
			if params.form:find "%f[^%z|]part%f[%z|]" then -- participle
				entry.pos_header = "Participle"

				local gender = params.form:match "%f[^%z|][mfn]%f[%z|]"

				if gender == "m" then -- masculine (lemma)
					local decl, feminine, neuter =
						get_participle_information(params.target)

					entry.head = "{{grc-part-" .. decl .. target .. "|" ..
									 (feminine or chars "") .. "|" ..
									 (neuter or chars "") .. "}}"
					entry.declension = "{{grc-adecl|" .. params.target .. "|" ..
										   (feminine or chars "") .. "}}"
					-- Remove gender from inflection-of template, as the masculine
					-- is a pseudo-lemma.
					entry.def = entry.def:gsub("%f[^%z|]m|", "")

				elseif gender == "f" or gender == "n" then
					local lemma = get_participle_lemma(params.target)

					if lemma then
						entry.head = "{{grc-participle form" .. target .. "}}"
						entry.def = "{{inflection of|grc|" .. lemma .. "||" ..
										gender .. "|nom|s" .. "}}"
					end
				end
			end
		end

		entry.pronunc = "{{grc-IPA" .. target .. "}}"

	end
}