Module:ckb-conj

local export = {}

local lang = require("Module:languages").getByCode("ckb")

-- Auto-create subtables in "forms" for different parts of conjugation table -- (simple past, present, imperative, etc.). -- Each subtable contains up to six person-number forms. local forms = setmetatable({}, {	__index = function (self, key)		if type(key) == "string" then			local prefix = key:match("^%l+")			if prefix == "ps" or prefix == "pr" or prefix == "impr" then				local val = {}				self[key] = val				return val			end		end	end, })

-- Defines the order of person-number forms in the affixes supplied to add_affixes, -- and the keys that are used in the table returned by add_affixes. local person_number_combinations = { "1s", "2s", "3s", "1p", "2p", "3p" }

-- Adds a suffix (or prefix) or list of suffixes (or prefixes) -- to a stem or set of stems for one or more person-number forms (to_what) -- using a function (add_affix) -- and returns a new set of forms. local function add_affixes(to_what, affix, add_affix) local new_forms = {} local affix_is_table = type(affix) == 'table' -- If to_what consists of lowercase letters and _, it is the name of a subtable in "forms". if to_what:find('^[%l_]+$') then to_what = forms[to_what] or error("Field " .. to_what .. " not found in forms table.") -- Both to_what and affix are strings. They can just be concatenated. elseif not affix_is_table then error("No point using add_affixes to add unchangeable affix to unchangeable stem.") end local to_what_is_table = type(to_what) == "table" if not affix then error("affix is missing.") -- to_what already checked above. end local i = 0 for _, person_number in ipairs(person_number_combinations) do		i = i + 1 local stem = not to_what_is_table and to_what or to_what[person_number] local affix = not affix_is_table and affix or affix[i] if stem and affix then new_forms[person_number] = add_affix(stem, affix) end end return new_forms end

local function concat(a, b) return a .. b end local function reverse_concat(a, b) return b .. a end

local function add_prefixes(to_what, prefix) local add_prefix = reverse_concat return add_affixes(to_what, prefix, add_prefix) end

local function add_suffixes(to_what, suffix, use_suff_function) local add_suffix = use_suff_function and export.suf or concat return add_affixes(to_what, suffix, add_suffix) end

function export.main(frame) local PAGENAME = mw.title.getCurrentTitle.text local NAMESPACE = mw.title.getCurrentTitle.nsText local verb_type = frame.args["type"] or error('No value passed to the "type" parameter') local params = { ["pr-stem"] = {}, [1] = { alias_of = "pr-stem" }, ["infinitive"] = { default = PAGENAME }, [2] = { alias_of = "infinitive" }, ["ps-stem"] = {}, ["suf"] = { default = "" }, }	local args, unrecognized_args = require "Module:parameters".process(frame:getParent.args, params, true) if next(unrecognized_args) then mw.log("Unrecognized args: "			.. table.concat(require "Module:table".keysToList(unrecognized_args), ", ")) end

local infinitive = args["infinitive"] local ps_stem = args["ps-stem"] or mw.ustring.sub(infinitive, 1, -2) local pr_stem = args["pr-stem"] local suf = args["suf"] local pr_active_participle_nosuf = export.suf(ps_stem, 'وو') local pr_active_participle = pr_active_participle_nosuf .. suf local i = ''; if not export.isVowelStem(ps_stem) then i = 'ِ' end local ps_stem_i = ps_stem .. i

forms["infinitive"] = infinitive forms["ps_stem"] = ps_stem forms["pr_stem"] = pr_stem

if verb_type == "intransitive" then -- simple past forms["ps"] = add_suffixes(ps_stem, { 'ِم', 'یت', '', 'ین', 'ِن' }, true)

-- past habitual forms["ps_impf"] = add_prefixes("ps", 'دە')

-- present perfect forms["pr_pf"] = add_suffixes(pr_active_participle_nosuf,			{ 'ِم', 'یت', '', 'ین', 'ِن' }, true) forms["pr_pf"] = add_suffixes("pr_pf", 'ە')

if suf and suf ~= "" then forms["pr_pf"]["3s"] = forms["pr_pf"]["3s"] .. 'ت' forms["pr_pf"] = add_suffixes("pr_pf", suf) end

-- past perfect forms["ps_pf"] = add_suffixes(ps_stem_i, { 'بووم', 'بوویت', 'بوو', 'بووین', 'بوون' })

-- past subjunctive -- TODO: add forms for other dialects forms["ps_subj"] = add_suffixes(ps_stem_i, { 'بِم', 'بیت', 'بێت', 'بین', 'بِن' })

elseif verb_type == "transitive" then -- simple past forms["ps"] = add_suffixes(ps_stem, { 'ِم', 'ِت', 'ی', 'مان', 'تان', 'یان' }, true)

-- past habitual forms["ps_impf"] = add_prefixes(ps_stem, { 'دەم', 'دەت', 'دەی', 'دەمان', 'دەتان', 'دەیان' })

-- present perfect forms["pr_pf"] = add_suffixes(pr_active_participle_nosuf,			{ 'ِم', 'ِت', 'ی', 'مان', 'تان', 'یان' }, true)

forms["pr_pf"] = add_suffixes("pr_pf", 'ە' .. suf)

-- past perfect forms["ps_pf"] = add_suffixes(ps_stem_i, { 'بووم', 'بووت', 'بووی', 'بوومان', 'بووتان', 'بوویان' })

-- past subjunctive forms["ps_subj"] = add_suffixes(ps_stem_i,			{ 'بێتِم', 'بێتِت', 'بێتی', 'بێتمان', 'بێتتان', 'بێتیان' }, true) forms["ps_subj"] = add_suffixes("ps_subj", suf) else error('Indicate verb type (pass "transitive" or "intransitive" to the ' .. '"type" parameter)') end

-- past progressive forms["ps_prog"] = add_prefixes("ps_impf",		{ 'خەریک بووم ', 'خەریک بووی ', 'خەریک بوو ', 'خەریک بووین ', 'خەریک بوون ', 'خەریک بوون ' }) -- 3p, 'خەریک بوون ', will only be displayed in table for transitive verb.

forms["pr"] = add_suffixes(pr_stem, { 'ِم', 'یت', 'ێت', 'ین', 'ِن' }, true)

-- present subjunctive -- TODO: ب (bi) should be omitted in some compound verbs, optional in others forms["pr_subj"] = add_prefixes("pr", 'بِ') forms["pr_subj"] = add_suffixes("pr_subj", suf, true)

-- present -- TODO: ئە (a) for Sulaymani dialect forms["pr"] = add_prefixes("pr", 'دە') forms["pr"] = add_suffixes("pr", suf, true)

-- present progressive forms["pr_prog"] = add_prefixes("pr", { 'خەریکِم ', 'خەریکی ', 'خەریکە ', 'خەریکین ', 'خەریکِن ' })

-- imperative forms["impr"] = add_suffixes(pr_stem, { nil, nil, nil, 'ین', 'ِن' }, true) if mw.ustring.sub(ps_stem, -2) == 'وو' then forms["impr"]["2s"] = pr_stem .. 'ۆ' elseif mw.ustring.sub(infinitive, -3) == 'ردن' then forms["impr"]["2s"] = pr_stem else forms["impr"]["2s"] = export.suf(pr_stem, 'ە') end

forms["impr"] = add_prefixes("impr", 'بِ')

-- it is sometimes unpredictable if args["2s-impr"] then forms["impr"]["2s"] = args["2s-impr"] end

-- TODO: conditional mood local function pronouns(mood) local attributes = ('class="ku-Arab pronoun mood" lang="ckb"') :gsub('mood', mood) return ( من ! attributes | تۆ ! attributes | ئەو ! attributes | ئێمە ! attributes | ئێوە ! attributes | ئەوان ):gsub('attributes', attributes) end

local text = [=[ Conjugation ]=]

if verb_type == 'intransitive' then text = text:gsub('| } || }',			function (first_code, suffix)				if suffix == 'ps' or suffix == 'ps_impf' or suffix == 'ps_prog'						or suffix == 'ps_pf' or suffix == 'pr_pf'						or suffix == 'ps_subj' then					return ('| colspan="2" | '):format(first_code)				end			end) end text = text:gsub('}', export.link) return text .. mw.getCurrentFrame:extensionTag{ name = "templatestyles", args = { src = "Module:ckb-conj/style.css" } } end

function export.suf(word, suf) local last_letter = mw.ustring.sub(word, -1)

if export.isVowelStem(word) then if suf == 'ِم' then return word .. 'م' elseif suf == 'ِت' then return word .. 'ت' elseif suf == 'ێت' then if last_letter == 'ە' then return mw.ustring.sub(word, 1, -2) .. 'ات' elseif last_letter == 'ۆ' then return mw.ustring.sub(word, 1, -2) .. 'ات' elseif last_letter == 'ێ' then return word .. 'ت' else return word .. 'ێت' end elseif suf == 'ین' then return word .. 'ین' elseif suf == 'ِن' then return word .. 'ن' elseif suf == 'وو' and mw.ustring.sub(word, -2) ~= 'وو' then return word .. 'و' end end return word .. suf end

export.isVowelStem = require "Module:fun".memoize(function (word)	local last_letter = mw.ustring.sub(word, -1)

return last_letter == 'ا' or last_letter == 'ی' -- later or last_letter == 'و' -- later or last_letter == 'ێ' or last_letter == 'ۆ' or last_letter == 'ە' end)

function export.link(form_code) -- Parse a code such as 1s_ps into 1s and ps, and then retrieve forms["ps"]["1s"]. local number_person, tense_aspect_mood = form_code:match("^(%d%l)_(.+)$") local form if number_person and tense_aspect_mood then form = forms[tense_aspect_mood] and forms[tense_aspect_mood][number_person] else form = forms[form_code] end if not form then mw.log('Form ' .. form_code .. ' for ' .. tostring(forms.infinitive)			.. ' not found.') return '' end local auto_tr = (lang:transliterate(form)) return ' '		.. form .. ' ' .. auto_tr .. ' ' end

return export