Module:fr-verb/core

local export = {}

local m_conj = require("Module:fr-conj") local m_links = require("Module:links") local lang = require("Module:languages").getByCode("fr") local IPA = function(str) return require("Module:IPA").format_IPA(nil, str) end

local rmatch = mw.ustring.match local rsubn = mw.ustring.gsub

local pref_sufs = {} export.pref_sufs = pref_sufs

-- version of rsubn that discards all but the first return value local function rsub(term, foo, bar) local retval = rsubn(term, foo, bar) return retval end

local function verb_slot_to_accel(slot) return rsub(slot, "^([a-z_]+)_([123])([sp])$",		function(mood_tense, person, number)			local mood_tense_to_infl = {				["ind_p"] = "pres|indc",				["ind_i"] = "impf|indc",				["ind_ps"] = "phis",				["ind_f"] = "futr",				["cond_p"] = "cond",				["sub_p"] = "pres|subj",				["sub_pa"] = "impf|subj",				["imp_p"] = "impr"			}			return person .. "|" .. number .. "|" .. mood_tense_to_infl[mood_tense]		end	) end

local function map(seq, fun) if type(seq) == "table" then local ret = {} for _, s in ipairs(seq) do			-- Handle stem of the form {"STEM", RESPELLING="RESPELLING"} if type(s) == "table" then s = s[1] end -- store in separate var in case fun has multiple retvals local retval = fun(s) table.insert(ret, retval) end return ret else -- store in separate var in case fun has multiple retvals local retval = fun(seq) return retval end end

local function add(source, appendix) return map(source, function(s) return s .. appendix end) end

function export.make_ind_p_e(data, stem, stem2, stem3) stem2 = stem2 or stem stem3 = stem3 or stem

data.forms.ind_p_1s = add(stem, "e") data.forms.ind_p_2s = add(stem, "es") data.forms.ind_p_3s = add(stem, "e") data.forms.ind_p_3p = add(stem, "ent") data.forms.ind_p_1p = add(stem2, "ons") -- stem3 is used in -ger and -cer verbs data.forms.ind_p_2p = add(stem3, "ez")

export.make_ind_i(data, stem2, stem3) export.make_ind_ps_a(data, stem2, stem3) export.make_sub_p(data, stem, stem3) export.make_imp_p_ind(data) export.make_ind_f(data, add(stem, "er")) data.forms.ppr = add(stem2, "ant") end

function export.make_ind_p(data, stem, stem2, stem3) stem2 = stem2 or stem stem3 = stem3 or stem2 data.forms.ind_p_1s = add(stem, "s") data.forms.ind_p_2s = add(stem, "s") -- add t unless stem ends in -t (e.g. met), -d (e.g. vend, assied) or -- -c (e.g. vainc). data.forms.ind_p_3s = map(stem, function(s)		return add(s, rmatch(s, "[tdc]$") and "" or "t")	end) data.forms.ind_p_1p = add(stem2, "ons") data.forms.ind_p_2p = add(stem2, "ez") data.forms.ind_p_3p = add(stem3, "ent")

export.make_ind_i(data, stem2) export.make_sub_p(data, stem3, stem2) export.make_imp_p_ind(data) data.forms.ppr = add(stem2, "ant") end

function export.make_ind_i(data, stem, stem2) stem2 = stem2 or stem data.forms.ind_i_1s = add(stem, "ais") data.forms.ind_i_2s = add(stem, "ais") data.forms.ind_i_3s = add(stem, "ait") data.forms.ind_i_1p = add(stem2, "ions") data.forms.ind_i_2p = add(stem2, "iez") data.forms.ind_i_3p = add(stem, "aient") end

function export.make_ind_ps_a(data, stem, stem2) stem2 = stem2 or stem data.forms.ind_ps_1s = add(stem, "ai") data.forms.ind_ps_2s = add(stem, "as") data.forms.ind_ps_3s = add(stem, "a") data.forms.ind_ps_1p = add(stem, "âmes") data.forms.ind_ps_2p = add(stem, "âtes") data.forms.ind_ps_3p = add(stem2, "èrent")

export.make_sub_pa(data, add(stem, "a"))

data.forms.pp = data.forms.pp or add(stem2, "é") end

local function fix_circumflex(val) return rsub(val, "[aiïu]n?%^", {["a^"]="â", ["i^"]="î", ["ï^"]="ï", ["in^"]="în", ["u^"]="û"}) end

function export.make_ind_ps(data, stem) data.forms.ind_ps_1s = add(stem, "s") data.forms.ind_ps_2s = add(stem, "s") data.forms.ind_ps_3s = add(stem, "t") data.forms.ind_ps_1p = map(add(stem, "^mes"), fix_circumflex) data.forms.ind_ps_2p = map(add(stem, "^tes"), fix_circumflex) data.forms.ind_ps_3p = add(stem, "rent")

export.make_sub_pa(data, stem)

data.forms.pp = data.forms.pp or add(stem, "") end

function export.make_ind_f(data, stem) data.forms.ind_f_1s = add(stem, "ai") data.forms.ind_f_2s = add(stem, "as") data.forms.ind_f_3s = add(stem, "a") data.forms.ind_f_1p = add(stem, "ons") data.forms.ind_f_2p = add(stem, "ez") data.forms.ind_f_3p = add(stem, "ont")

export.make_cond_p(data, stem) end

function export.make_cond_p(data, stem) data.forms.cond_p_1s = add(stem, "ais") data.forms.cond_p_2s = add(stem, "ais") data.forms.cond_p_3s = add(stem, "ait") data.forms.cond_p_1p = add(stem, "ions") data.forms.cond_p_2p = add(stem, "iez") data.forms.cond_p_3p = add(stem, "aient") end

function export.make_sub_p(data, stem, stem2) stem2 = stem2 or stem data.forms.sub_p_1s = add(stem, "e") data.forms.sub_p_2s = add(stem, "es") data.forms.sub_p_3s = add(stem, "e") data.forms.sub_p_3p = add(stem, "ent") data.forms.sub_p_1p = add(stem2, "ions") data.forms.sub_p_2p = add(stem2, "iez") end

function export.make_sub_pa(data, stem) data.forms.sub_pa_1s = add(stem, "sse") data.forms.sub_pa_2s = add(stem, "sses") data.forms.sub_pa_3s = map(add(stem, "^t"), fix_circumflex) data.forms.sub_pa_1p = add(stem, "ssions") data.forms.sub_pa_2p = add(stem, "ssiez") data.forms.sub_pa_3p = add(stem, "ssent") end

function export.make_imp_p_ind(data) data.forms.imp_p_2s = map(data.forms.ind_p_2s, function(form)		return rsub(form, "([ae])s$", "%1")	end) -- Need to clone objects when copying forms, otherwise we get duplicated prefixes added in case of -- prefixed verbs. data.forms.imp_p_1p = mw.clone(data.forms.ind_p_1p) data.forms.imp_p_2p = mw.clone(data.forms.ind_p_2p) end

function export.clear_imp(data) data.forms.imp_p_2s = "—" data.forms.imp_p_1p = "—" data.forms.imp_p_2p = "—" end

local function add_prefix_suffix(data, key, val, pref_v, pref_c, pron_v, pron_c, imp, pron_imp, join_imp_dash) if key == "pp" or rmatch(key, "_nolink") then return end local imp_joiner, imp_pron_joiner if join_imp_dash then imp_joiner = "-" imp_pron_joiner = "." else imp_joiner = "" imp_pron_joiner = "" end local pref, suf, pref_pron, suf_pron local function get_pref_suf(v) pref, suf, pref_pron, suf_pron = "", "", "", "" if not rmatch(key, "imp") then if rmatch(v, "^[aeéêiouhywjɑɛœø]") then pref, pref_pron = pref_v, pron_v else pref, pref_pron = pref_c, pron_c end else suf, suf_pron = imp_joiner .. imp, imp_pron_joiner .. pron_imp end end if key == "inf" or key == "ppr" then data.forms[key .. '_nolink'] = map(data.forms[key], function(val)				get_pref_suf(val)				return pref .. val .. suf			end) end data.forms[key] = map(val, function(v)		get_pref_suf(v)		return rsub(pref .. "" .. v .. "" .. suf, "%.h", "h")	end) if data.prons[key] then data.prons[key] = map(data.prons[key], function(v)			get_pref_suf(v)			return pref_pron .. v .. suf_pron		end) end end

pref_sufs["y"] = function(data, key, val) local imp = rmatch(key, "2s") and not rmatch(val, "s$") and "s-y" or "-y" add_prefix_suffix(data, key, val, "y ", "y ", "i.j‿", "i ", imp, ".zi", false) end

pref_sufs["en"] = function(data, key, val) local imp = rmatch(key, "2s") and not rmatch(val, "s$") and "s-en" or "-en" add_prefix_suffix(data, key, val, "en ", "en ", "ɑ̃.n‿", "ɑ̃ ", imp, ".zɑ̃", false) end

pref_sufs["yen"] = function(data, key, val) local imp = rmatch(key, "2s") and not rmatch(val, "s$") and "s-y en" or "-y-en" add_prefix_suffix(data, key, val, "y en ", "y en ", "i.j‿ɑ̃.n‿", "i.j‿ɑ̃ ", imp, ".zi.jɑ̃", false) end

pref_sufs["le"] = function(data, key, val) add_prefix_suffix(data, key, val, "l'", rmatch(key, "2p") and "le or la " or "le ", "l", "lə ", "-le", ".lə", false) end

pref_sufs["la"] = function(data, key, val) add_prefix_suffix(data, key, val, "l'", "la ", "l", "la ", "-la", ".la", false) end

pref_sufs["l"] = function(data, key, val) add_prefix_suffix(data, key, val, "l'", "l'", "l", "l", "-le or -la", ".lə or .la", false) end

pref_sufs["les"] = function(data, key, val) add_prefix_suffix(data, key, val, "les ", "les ", "le.z‿", "le", "-les", ".le", false) end

pref_sufs["l_y"] = function(data, key, val) add_prefix_suffix(data, key, val, "l'y ", "l'y ", "li.j‿", "li ", "-l'y", ".li", false) end

pref_sufs["l_en"] = function(data, key, val) data.aux = "l'en avoir" add_prefix_suffix(data, key, val, "l'en ", "l'en ", "lɑ̃.n‿", "lɑ̃ ", "l'en", "lɑ̃", true) end

pref_sufs["lesen"] = function(data, key, val) data.aux = "les en avoir" add_prefix_suffix(data, key, val, "les en ", "les en ", "le.z‿ɑ̃.n‿", "le.z‿ɑ̃ ", "-les-en", "le.zɑ̃", true) end

pref_sufs["lesy"] = function(data, key, val) add_prefix_suffix(data, key, val, "les y ", "les y ", "le.z‿i.j‿", "le.z‿i ", "-les-y", ".le.zi", false) end

pref_sufs["l_yen"] = function(data, key, val) data.aux = "l'y en avoir" add_prefix_suffix(data, key, val, "l'y en ", "l'y en ", "li.j‿ɑ̃.n‿", "li.j‿ɑ̃ ", "l'y-en", "li.jɑ̃", true) end

pref_sufs["lesyen"] = function(data, key, val) data.aux = "les y en avoir" add_prefix_suffix(data, key, val, "les y en ", "les y en ", "le.z‿i.j‿ɑ̃.n‿", "le.z‿i.j‿ɑ̃ ", "-les-y-en", "le.zi.jɑ̃", true) end

-- Add reflexive prefixes and suffixes to verb forms. KEY is the form to add to, and VAL is the value -- without prefixes and suffixes. PREF_V is the prefix to add to non-imperative forms that begin with a -- vowel, and PREF_C is the corresponding prefix for non-imperative forms beginning with a consonant. -- PRON_V is the prefix to add to the pronunciation of non-imperative forms that begin with a vowel, and -- PRON_C is the corresponding prefix for pronunciations beginning with a consonant. IMP is the suffix to -- add to imperative forms, and PRON_IMP is the corresponding suffix to add to the pronunciation of -- imperative forms. All prefixes and suffixes are added directly, without an intervening space. -- -- Since the prefixes and suffixes vary depending on the person and number, the specified prefixes and -- suffixes should contain "%c" and/or "%v" specs in them. "%c" represents the appropriate pronominal -- form to add before a consonant (or when nothing follows, in the case of suffixes), and "%v" represents -- the corresponding form to add before a vowel. The actual forms substituted depend on both the person -- and number of KEY and the type of prefix (i.e. whether it's a spelled prefix, pronunciation prefix, -- spelled imperative suffix or pronunciation imperative suffix). For example, if key contains "2s" -- (i.e. it represents a second person singular form), a "%v" in a spelled prefix will be replaced with -- "t'" and a "%c" in a pronounced prefix will be replaced with "tə ". Note that it's not always the -- case that %c should occur in a pre-consonant prefix/suffix and correspondingly for %v. For example, -- if the prefix occurs before "en" or "y" you should use %v in both the pre-vowel and pre-consonant -- prefixes. local function add_refl_prefix_suffix(data, key, val, pref_v, pref_c, pron_v, pron_c, imp, pron_imp) local sub_pref_v, sub_pref_c, sub_pron_v, sub_pron_c local sub_imp_v, sub_imp_c, sub_pron_imp_v, sub_pron_imp_c = "", "", "", "" if rmatch(key, "1s") then sub_pref_v, sub_pref_c, sub_pron_v, sub_pron_c = "m'", "me ", "m", "mə " elseif rmatch(key, "2s") then sub_pref_v, sub_pref_c, sub_pron_v, sub_pron_c = "t'", "te ", "t", "tə " sub_imp_v, sub_imp_c, sub_pron_imp_v, sub_pron_imp_c = "t'", "toi", "t", "twa" elseif rmatch(key, "1p") then sub_pref_v, sub_pref_c, sub_pron_v, sub_pron_c = "nous ", "nous ", "nu.z‿", "nu " sub_imp_v, sub_imp_c, sub_pron_imp_v, sub_pron_imp_c = "nous-", "nous", "nu.z", "nu" elseif rmatch(key, "2p") then sub_pref_v, sub_pref_c, sub_pron_v, sub_pron_c = "vous ", "vous ", "vu.z‿", "vu " sub_imp_v, sub_imp_c, sub_pron_imp_v, sub_pron_imp_c = "vous-", "vous", "vu.z", "vu" else sub_pref_v, sub_pref_c, sub_pron_v, sub_pron_c = "s'", "se ", "s", "sə " end local function dosub(spec, dotype) if type(spec) == "table" then local sing, plur = spec[1], spec[2] if rmatch(key, "[12]p") then spec = plur else spec = sing end end spec = rsub(spec, "%%v",			dotype == "pron" and sub_pron_v or			dotype == "imp" and sub_imp_v or			dotype == "pron-imp" and sub_pron_imp_v or			sub_pref_v		) spec = rsub(spec, "%%c",			dotype == "pron" and sub_pron_c or			dotype == "imp" and sub_imp_c or			dotype == "pron-imp" and sub_pron_imp_c or			sub_pref_c		) return spec end add_prefix_suffix(data, key, val, dosub(pref_v), dosub(pref_c), dosub(pron_v, "pron"), dosub(pron_c, "pron"),		dosub(imp, "imp"), dosub(pron_imp, "pron-imp"), true) end

pref_sufs["refl"] = function(data, key, val) data.aux = "s'être" add_refl_prefix_suffix(data, key, val, "%v", "%c", "%v", "%c", "%c", "%c") end

pref_sufs["reflen"] = function(data, key, val) data.aux = "s'en être" add_refl_prefix_suffix(data, key, val, "%ven ", "%ven ", "%vɑ̃.n‿", "%vɑ̃ ", "%ven", "%vɑ̃") end

pref_sufs["refly"] = function(data, key, val) data.aux = "s'y être" add_refl_prefix_suffix(data, key, val, "%vy ", "%vy ", "%vi.j‿", "%vi ", "%vy", "%vi") end

pref_sufs["reflyen"] = function(data, key, val) data.aux = "s'y en être" add_refl_prefix_suffix(data, key, val, "%vy en ", "%vy en ", "%vi.j‿ɑ̃.n‿", "%vi.j‿ɑ̃ ", "%v'y-en", "%vi.jɑ̃") end

pref_sufs["reflle"] = function(data, key, val) data.aux = "se l'être" add_refl_prefix_suffix(data, key, val, "%cl'", "%cle ", "%cl", "%clə ", "le-%c", "lə.%c") end

pref_sufs["refll"] = function(data, key, val) data.aux = "se l'être" add_refl_prefix_suffix(data, key, val, "%cl'", "%cl'", "%cl", "%cl", "le-%c or -la-%c", "lə.%c or .la.%c") end

pref_sufs["reflla"] = function(data, key, val) data.aux = "se l'être" add_refl_prefix_suffix(data, key, val, "%cl'", "%cla ", "%cl", "%cla ", "la-%c", "la.%c") end

pref_sufs["reflles"] = function(data, key, val) data.aux = "se les être" add_refl_prefix_suffix(data, key, val, "%cles ", "%cles ", "%cle.z‿", "%cle ", "les-%c", "le.%c") end

pref_sufs["reflly"] = function(data, key, val) data.aux = "se l'y être" add_refl_prefix_suffix(data, key, val, "%cl'y ", "%cl'y ", "%cli.j‿", "%cli ", "le-%cy or -la-%cy", "lə.%ci or .la.%ci") end

pref_sufs["refllesy"] = function(data, key, val) data.aux = "se les y être" add_refl_prefix_suffix(data, key, val, "%cles y ", "%cles y ", "%cle.z‿i.j‿", "%cle.z‿i ", "les-%cy", "le.%ci") end

function export.link(data) for key, val in pairs(data.forms) do		if type(val) ~= "table" then val = {val} end -- don't destructively modify data.forms[key][i] because it might -- be shared among different keys local newval = {} -- Keep track of forms seen so we don't duplicate them. This must be done before adding accelerators, so we use a separate set. local seen_forms = {} for i, form in ipairs(val) do			if rmatch(form, "—") then form = "—" end if not seen_forms[form] then seen_forms[form] = true if not rmatch(key, "nolink") and form ~= "—" then form = m_links.full_link({term = form, lang = lang,						accel = { form = verb_slot_to_accel(key) }					}) end table.insert(newval, form) end end data.forms[key] = table.concat(newval, " or ") end for key, val in pairs(data.prons) do		if not rmatch(key, "nolink") then if type(val) ~= "table" then val = {val} end -- don't destructively modify data.forms[key][i] because it might -- be shared among different keys local newprons = {} for i, form in ipairs(val) do				if not rmatch(form, "—") then table.insert(newprons, IPA('/' .. form .. '/'))				end end if #newprons > 0 and data.forms[key] ~= "—" then data.forms[key] = data.forms[key] .. ' ' .. table.concat(newprons, " or ") .. ' '			end end end end

-- not sure if it's still used by something so I'm leaving a stub function instead of removing it entirely function export.make_table(data) return m_conj.make_table(data) end

return export