Module:Sandbox/Bababloka/bababloka-conj

local m_utilities = require("Module:utilities")

local m_table = require("Module:table")

-- FIXME, port remaining functions to Module:table and use it instead

local ut = require("Module:utils")

local m_links = require("Module:links")

local make_link = m_links.full_link

local m_la_headword = require("Module:la-headword")

local m_la_utilities = require("Module:la-utilities")

local m_para = require("Module:parameters")

-- TODO:

-- 1. (DONE) detect_decl_and_subtypes doesn't do anything with perf_stem or supine_stem.

-- 2. (DONE) Should error on bad subtypes.

-- 3. Make sure Google Books link still works.

-- 4. (DONE) Add 4++ that has alternative perfects -īvī/-iī.

-- 5. (DONE) If sup but no perf, allow passive perfect forms unless no-pasv-perf.

-- 6. (DONE) Remove no-actv-perf.

-- 7. (DONE) Support plural prefix/suffix and plural passive prefix/suffix

--

-- If enabled, compare this module with new version of module to make

-- sure all conjugations are the same.

local test_new_la_verb_module = false

local export = {}

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

local title = mw.title.getCurrentTitle()

local NAMESPACE = title.nsText

local PAGENAME = title.text

-- Conjugations are the functions that do the actual

-- conjugating by creating the forms of a basic verb.

-- They are defined further down.

local conjugations = {}

-- Check if this verb is reconstructed

-- i.e. the pagename is Reconstruction:Latin/...

local reconstructed = NAMESPACE == "Reconstruction" and PAGENAME:find("^Latin/")

-- Forward functions

local postprocess

local make_pres_1st

local make_pres_2nd

local make_pres_3rd

local make_pres_3rd_io

local make_pres_4th

local make_perf_and_supine

local make_perf

local make_deponent_perf

local make_supine

local make_table

local make_indc_rows

local make_subj_rows

local make_impr_rows

local make_nonfin_rows

local make_vn_rows

local make_footnotes

local override

local checkexist

local checkirregular

local flatten_values

local link_google_books

local rsplit = mw.text.split

local rfind = mw.ustring.find

local rmatch = mw.ustring.match

local rsubn = mw.ustring.gsub

-- 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 cfind(str, text)

-- Constant version of :find()

return str:find(text, nil, true)

end

local function form_is_empty(form)

return not form or form == "" or form == "-" or form == "—" or form == "—" or (

type(form) == "table" and (form[1] == "" or form[1] == "-" or form[1] == "—" or form[1] == "—")

)

end

local function initialize_slots()

local generic_slots = {}

local non_generic_slots = {}

local function handle_slot(slot, generic)

if generic then

table.insert(generic_slots, slot)

else

table.insert(non_generic_slots, slot)

end

end

for _, v in ipairs({"actv", "pasv"}) do

local function handle_tense(t, mood)

local non_pers_slot = t .. "_" .. v .. "_" .. mood

handle_slot(non_pers_slot, true)

for _, p in ipairs({"1s", "2s", "3s", "1p", "2p", "3p"}) do

handle_slot(p .. "_" .. non_pers_slot, false)

end

end

for _, t in ipairs({"pres", "impf", "futr", "perf", "plup", "futp"}) do

handle_tense(t, "indc")

end

for _, t in ipairs({"pres", "impf", "perf", "plup"}) do

handle_tense(t, "subj")

end

for _, t in ipairs({"pres", "futr"}) do

handle_tense(t, "impr")

end

end

for _, f in ipairs({"inf", "ptc"}) do

for _, t in ipairs({"pres_actv", "perf_actv", "futr_actv", "pres_pasv", "perf_pasv", "futr_pasv"}) do

handle_slot(t .. "_" .. f, false)

end

end

for _, n in ipairs({"ger_gen", "ger_dat", "ger_acc", "ger_abl", "sup_acc", "sup_abl"}) do

handle_slot(n, false)

end

return non_generic_slots, generic_slots

end

local non_generic_slots, generic_slots = initialize_slots()

local potential_lemma_slots = {

"1s_pres_actv_indc", -- regular

"3s_pres_actv_indc", -- impersonal

"1s_perf_actv_indc", -- coepī

"3s_perf_actv_indc", -- doesn't occur?

}

-- Iterate over all the "slots" associated with a verb declension, where a slot

-- is e.g. 1s_pres_actv_indc (a non-generic slot), pres_actv_indc (a generic slot),

-- or linked_1s_pres_actv_indc (a linked slot). Only include the generic and/or linked

-- slots if called for.

local function iter_slots(include_generic, include_linked)

-- stage == 1: non-generic slots

-- stage == 2: generic slots

-- stage == 3: linked slots

local stage = 1

local slotnum = 0

local max_slotnum = #non_generic_slots

local function iter()

slotnum = slotnum + 1

if slotnum > max_slotnum then

slotnum = 1

stage = stage + 1

if stage == 2 then

if include_generic then

max_slotnum = #generic_slots

else

stage = stage + 1

end

end

if stage == 3 then

if include_linked then

max_slotnum = #potential_lemma_slots

else

stage = stage + 1

end

end

if stage > 3 then

return nil

end

end

if stage == 1 then

return non_generic_slots[slotnum]

elseif stage == 2 then

return generic_slots[slotnum]

else

return "linked_" .. potential_lemma_slots[slotnum]

end

end

return iter

end

local function ine(val)

if val == "" then

return nil

else

return val

end

end

local function track(page)

require("Module:debug").track("la-verb/" .. page)

return true

end

-- For a given form, we allow either strings (a single form) or lists of forms,

-- and treat strings equivalent to one-element lists.

local function forms_equal(form1, form2)

if type(form1) ~= "table" then

form1 = {form1}

end

if type(form2) ~= "table" then

form2 = {form2}

end

return m_table.deepEquals(form1, form2)

end

local function concat_vals(val)

if type(val) == "table" then

return table.concat(val, ",")

else

return val

end

end

-- Construct a one- or two-part link. For reasons I don't understand, if we're in

-- the reconstructed namespace (e.g. for the page Reconstruction:Latin/nuo), we

-- need to construct a special type of link; full_link() doesn't handle this

-- correctly (although it tries ...). Ideally we should fix full_link() instead of

-- doing this.

local function make_raw_link(page, display)

if reconstructed then

display = display or page

page = lang:makeEntryName(page)

return "" .. display .. ""

elseif display then

return "" .. display .. ""

else

return "" .. page .. ""

end

end

local function split_prefix_and_base(lemma, main_verbs)

for _, main in ipairs(main_verbs) do

local prefix = rmatch(lemma, "^(.*)" .. main .. "$")

if prefix then

return prefix, main

end

end

error("Argument " .. lemma .. " doesn't end in any of " .. table.concat(main_verbs, ","))

end

-- Given an ending (or possibly a full regex matching the entire lemma, if

-- a regex group is present), return the base minus the ending, or nil if

-- the ending doesn't match.

local function extract_base(lemma, ending)

if ending:find("%(") then

return rmatch(lemma, ending)

else

return rmatch(lemma, "^(.*)" .. ending .. "$")

end

end

-- Given ENDINGS_AND_SUBTYPES (a list of pairs of endings with associated

-- subtypes, where each pair consists of a single ending spec and a list of

-- subtypes), check each ending in turn against LEMMA. If it matches, return

-- the pair BASE, SUBTYPES where BASE is the remainder of LEMMA minus the

-- ending, and SUBTYPES is the subtypes associated with the ending. If no

-- endings match, throw an error if DECLTYPE is non-nil, mentioning the

-- DECLTYPE (the user-specified declension); but if DECLTYPE is nil, just

-- return the pair nil, nil.

--

-- The ending spec in ENDINGS_AND_SUBTYPES is one of the following:

--

-- 1. A simple string, e.g. "ātur", specifying an ending.

-- 2. A regex that should match the entire lemma (it should be anchored at

-- the beginning with ^ and at the end with $), and contains a single

-- capturing group to match the base.

local function get_subtype_by_ending(lemma, conjtype, specified_subtypes,

endings_and_subtypes)

for _, ending_and_subtypes in ipairs(endings_and_subtypes) do

local ending = ending_and_subtypes[1]

local subtypes = ending_and_subtypes[2]

not_this_subtype = false

for _, subtype in ipairs(subtypes) do

-- A subtype is directly canceled by specifying -SUBTYPE.

if specified_subtypes["-" .. subtype] then

not_this_subtype = true

break

end

end

if not not_this_subtype then

local base = extract_base(lemma, ending)

if base then

return base, subtypes

end

end

end

if conjtype then

error("Unrecognized ending for conjugation-" .. conjtype .. " verb: " .. lemma)

end

return nil, nil

end

local irreg_verbs_to_conj_type = {

["aiō"] = "3rd-io",

["aiiō"] = "3rd-io",

["ajō"] = "3rd-io",

["dīcō"] = "3rd",

["dūcō"] = "3rd",

["faciō"] = "3rd-io",

["fīō"] = "3rd",

["ferō"] = "3rd",

["inquam"] = "irreg",

["libet"] = "2nd",

["lubet"] = "2nd",

["licet"] = "2nd",

["volō"] = "irreg",

["mālō"] = "irreg",

["nōlō"] = "irreg",

["possum"] = "irreg",

["piget"] = "2nd",

["coepī"] = "irreg",

["sum"] = "irreg",

["edō"] = "3rd",

["dō"] = "1st",

["eō"] = "irreg",

}

local function detect_decl_and_subtypes(args)

local specs = rsplit(args[1] or "", "%.")

local subtypes = {}

local conj_arg

for i, spec in ipairs(specs) do

if i == 1 then

conj_arg = spec

else

local begins_with_hyphen = rfind(spec, "^%-")

spec = spec:gsub("%-", "")

if begins_with_hyphen then

spec = "-" .. spec

end

subtypes[spec] = true

end

end

local orig_lemma = args[2] or mw.title.getCurrentTitle().subpageText

orig_lemma = rsub(orig_lemma, "o$", "ō")

local lemma = m_links.remove_links(orig_lemma)

local base, conjtype, conj_subtype, detected_subtypes

local base_conj_arg, auto_perf_supine = rmatch(conj_arg, "^([124])(%+%+?)$")

if base_conj_arg then

if auto_perf_supine == "++" and base_conj_arg ~= "4" then

error("Conjugation types 1++ and 2++ not allowed")

end

conj_arg = base_conj_arg

end

local auto_perf, auto_supine

if conj_arg == "1" then

conjtype = "1st"

base, detected_subtypes = get_subtype_by_ending(lemma, "1", subtypes, {

{"ō", {}},

{"or", {"depon"}},

{"at", {"impers"}},

{"ātur", {"depon", "impers"}},

})

if auto_perf_supine then

auto_perf = base .. "āv"

auto_supine = base .. "āt"

end

elseif conj_arg == "2" then

conjtype = "2nd"

base, detected_subtypes = get_subtype_by_ending(lemma, "2", subtypes, {

{"eō", {}},

{"eor", {"depon"}},

{"et", {"impers"}},

{"ētur", {"depon", "impers"}},

})

if auto_perf_supine then

auto_perf = base .. "u"

auto_supine = base .. "it"

end

elseif conj_arg == "3" then

base, detected_subtypes = get_subtype_by_ending(lemma, nil, subtypes, {

{"iō", {"I"}},

{"ior", {"depon", "I"}},

})

if base then

conjtype = "3rd-io"

else

base, detected_subtypes = get_subtype_by_ending(lemma, "3", subtypes, {

{"ō", {}},

{"or", {"depon"}},

{"it", {"impers"}},

{"itur", {"depon", "impers"}},

})

if subtypes.I then

conjtype = "3rd-io"

else

conjtype = "3rd"

end

end

elseif conj_arg == "4" then

conjtype = "4th"

base, detected_subtypes = get_subtype_by_ending(lemma, "4", subtypes, {

{"iō", {}},

{"ior", {"depon"}},

{"it", {"impers"}},

{"ītur", {"depon", "impers"}},

})

if auto_perf_supine == "++" then

auto_perf = base .. "īv/" .. base .. "i"

auto_supine = base .. "īt"

elseif auto_perf_supine == "+" then

auto_perf = base .. "īv"

auto_supine = base .. "īt"

end

elseif conj_arg == "irreg" then

conjtype = "irreg"

local prefix

prefix, base = split_prefix_and_base(lemma, {

"aiō",

"aiiō",

"ajō",

"dīcō",

"dūcō",

"faciō",

"fīō",

"ferō",

"inquam",

"libet",

"lubet",

"licet",

"volō",

"mālō",

"nōlō",

"possum",

"piget",

"coepī",

-- list sum after possum

"sum",

-- FIXME: Will praedō cause problems?

"edō",

-- list dō after edō

"dō",

"eō",

})

conj_subtype = irreg_verbs_to_conj_type[base]

args[1] = m_la_utilities.strip_macrons(base)

args[2] = prefix

-- args[3] and args[4] are used by ferō and sum and stay where they are

detected_subtypes = {}

else

error("Unrecognized conjugation '" .. conj_arg .. "'")

end

for _, detected_subtype in ipairs(detected_subtypes) do

if detected_subtype == "impers" and subtypes["3only"] then

-- 3only overrides impers

else

subtypes[detected_subtype] = true

end

end

if conjtype ~= "irreg" then

args[1] = base

local perf_stem, supine_stem

if subtypes.depon or subtypes.semidepon then

supine_stem = args[3] or auto_supine

if supine_stem == "-" then

supine_stem = nil

end

if not supine_stem then

subtypes.noperf = true

subtypes.nosup = true

end

args[2] = supine_stem

args[3] = nil

else

perf_stem = args[3] or auto_perf

if perf_stem == "-" then

perf_stem = nil

end

if not perf_stem then

subtypes.noperf = true

end

supine_stem = args[4] or auto_supine

if supine_stem == "-" then

supine_stem = nil

end

if not supine_stem then

subtypes.nosup = true

end

args[2] = perf_stem

args[3] = supine_stem

end

args[4] = nil

end

for subtype, _ in pairs(subtypes) do

if not m_la_headword.allowed_subtypes[subtype] and

not (conjtype == "3rd" and subtype == "-I") and

not (conjtype == "3rd-io" and subtype == "I") then

error("Unrecognized verb subtype " .. subtype)

end

end

return conjtype, conj_subtype, subtypes, orig_lemma, lemma

end

-- The main new entry point.

function export.show(frame)

local parent_args = frame:getParent().args

local data, typeinfo = export.make_data(parent_args)

local domain = frame:getParent().args['search']

-- Test code to compare existing module to new one.

if test_new_la_verb_module then

local m_new_la_verb = require("Module:User:Benwing2/la-verb")

local miscdata = {

title = data.title,

categories = data.categories,

}

local new_parent_args = frame:getParent().args

local newdata, newtypeinfo = m_new_la_verb.make_data(new_parent_args)

local newmiscdata = {

title = newdata.title,

categories = newdata.categories,

}

local all_verb_props = {"forms", "form_footnote_indices", "footnotes", "miscdata"}

local difconj = false

for _, prop in ipairs(all_verb_props) do

local table = prop == "miscdata" and miscdata or data[prop]

local newtable = prop == "miscdata" and newmiscdata or newdata[prop]

for key, val in pairs(table) do

local newval = newtable[key]

if not forms_equal(val, newval) then

-- Uncomment this to display the particular key and

-- differing forms.

--error(key .. " " .. (val and concat_vals(val) or "nil") .. " || " .. (newval and concat_vals(newval) or "nil"))

difconj = true

break

end

end

if difconj then

break

end

-- Do the comparison the other way as well in case of extra keys

-- in the new table.

for key, newval in pairs(newtable) do

local val = table[key]

if not forms_equal(val, newval) then

-- Uncomment this to display the particular key and

-- differing forms.

--error(key .. " " .. (val and concat_vals(val) or "nil") .. " || " .. (newval and concat_vals(newval) or "nil"))

difconj = true

break

end

end

if difconj then

break

end

end

track(difconj and "different-conj" or "same-conj")

end

if domain == nil then

return make_table(data) .. m_utilities.format_categories(data.categories, lang)

else

local verb = data['forms']['1s_pres_actv_indc'] ~= nil and (''..data['forms']['1s_pres_actv_indc'].. '') or 'verb'

return link_google_books(verb, flatten_values(data['forms']), domain) end

end

local function concat_forms(data, typeinfo, include_props)

local ins_text = {}

for key, val in pairs(data.forms) do

local ins_form = {}

if type(val) ~= "table" then

val = {val}

end

for _, v in ipairs(val) do

if not form_is_empty(v) then

table.insert(ins_form,

rsub(rsub(rsub(v, "|", ""), "=", "<->"), ",", "<.>")

)

end

end

if #ins_form > 0 then

table.insert(ins_text, key .. "=" .. table.concat(ins_form, ","))

end

end

if include_props then

table.insert(ins_text, "conj_type=" .. typeinfo.conj_type)

if typeinfo.conj_subtype then

table.insert(ins_text, "conj_subtype=" .. typeinfo.conj_subtype)

end

local subtypes = {}

for subtype, _ in pairs(typeinfo.subtypes) do

table.insert(subtypes, subtype)

end

table.insert(ins_text, "subtypes=" .. table.concat(subtypes, "."))

end

return table.concat(ins_text, "|")

end

-- The entry point for 'la-generate-verb-forms' and 'la-generate-verb-props'

-- to generate all verb forms/props.

function export.generate_forms(frame)

local include_props = frame.args["include_props"]

local parent_args = frame:getParent().args

local data, typeinfo = export.make_data(parent_args)

return concat_forms(data, typeinfo, include_props)

end

-- Add prefixes and suffixes to non-generic slots. The generic slots (e.g.

-- perf_pasv_indc, whose text indicates to use the past passive participle +

-- the present active indicative of sum), handle prefixes and suffixes

-- themselves in make_perfect_passive().

local function add_prefix_suffix(data, typeinfo)

if not data.prefix and not data.suffix then

return

end

local active_prefix = data.prefix or ""

local passive_prefix = data.passive_prefix or ""

local plural_prefix = data.plural_prefix or ""

local plural_passive_prefix = data.plural_passive_prefix or ""

local active_prefix_no_links = m_links.remove_links(active_prefix)

local passive_prefix_no_links = m_links.remove_links(passive_prefix)

local plural_prefix_no_links = m_links.remove_links(plural_prefix)

local plural_passive_prefix_no_links = m_links.remove_links(plural_passive_prefix)

local active_suffix = data.suffix or ""

local passive_suffix = data.passive_suffix or ""

local plural_suffix = data.plural_suffix or ""

local plural_passive_suffix = data.plural_passive_suffix or ""

local active_suffix_no_links = m_links.remove_links(active_suffix)

local passive_suffix_no_links = m_links.remove_links(passive_suffix)

local plural_suffix_no_links = m_links.remove_links(plural_suffix)

local plural_passive_suffix_no_links = m_links.remove_links(plural_passive_suffix)

for slot in iter_slots(false, true) do

if not slot:find("ger_") then

local prefix, suffix, prefix_no_links, suffix_no_links

if slot:find("pasv") and slot:find("[123]p") then

prefix = plural_passive_prefix

suffix = plural_passive_suffix

prefix_no_links = plural_passive_prefix_no_links

suffix_no_links = plural_passive_suffix_no_links

elseif slot:find("pasv") and not slot:find("_inf") then

prefix = passive_prefix

suffix = passive_suffix

prefix_no_links = passive_prefix_no_links

suffix_no_links = passive_suffix_no_links

elseif slot:find("[123]p") then

prefix = plural_prefix

suffix = plural_suffix

prefix_no_links = plural_prefix_no_links

suffix_no_links = plural_suffix_no_links

else

prefix = active_prefix

suffix = active_suffix

prefix_no_links = active_prefix_no_links

suffix_no_links = active_suffix_no_links

end

local forms = data.forms[slot]

if not form_is_empty(forms) then

local affixed_forms = {}

if type(forms) ~= "table" then

forms = {forms}

end

for _, form in ipairs(forms) do

if form_is_empty(form) then

table.insert(affixed_forms, form)

elseif slot:find("^linked") then

-- If we're dealing with a linked slot, include the original links

-- in the prefix/suffix and also add a link around the form itself

-- if links aren't already present. (Note, above we early-exited

-- if there was no prefix and no suffix.)

if not form:find("[%[%]]") then

form = "" .. form .. ""

end

table.insert(affixed_forms, prefix .. form .. suffix)

elseif form:find("[%[%]]") then

-- If not dealing with a linked slot, but there are links in the slot,

-- include the original, potentially linked versions of the prefix and

-- suffix (e.g. in perfect passive forms).

table.insert(affixed_forms, prefix .. form .. suffix)

else

-- Otherwise, use the non-linking versions of the prefix and suffix

-- so that the whole term (including prefix/suffix) gets linked.

table.insert(affixed_forms, prefix_no_links .. form .. suffix_no_links)

end

end

data.forms[slot] = affixed_forms

end

end

end

end

local function set_linked_forms(data, typeinfo)

-- Generate linked variants of slots that may be the lemma.

-- If the form is the same as the lemma (with links removed),

-- substitute the original lemma (with links included).

for _, slot in ipairs(potential_lemma_slots) do

local forms = data.forms[slot]

local linked_forms = {}

if forms then

if type(forms) ~= "table" then

forms = {forms}

end

for _, form in ipairs(forms) do

if form == typeinfo.lemma then

table.insert(linked_forms, typeinfo.orig_lemma)

else

table.insert(linked_forms, form)

end

end

end

data.forms["linked_" .. slot] = linked_forms

end

end

function export.make_data(parent_args, from_headword, def1, def2)

local params = {

[1] = {required = true, default = def1 or "1+"},

[2] = {required = true, default = def2 or "amō"},

[3] = {},

[4] = {},

prefix = {},

passive_prefix = {},

plural_prefix = {},

plural_passive_prefix = {},

gen_prefix = {},

dat_prefix = {},

acc_prefix = {},

abl_prefix = {},

suffix = {},

passive_suffix = {},

plural_suffix = {},

plural_passive_suffix = {},

gen_suffix = {},

dat_suffix = {},

acc_suffix = {},

abl_suffix = {},

-- examined directly in export.show()

search = {},

}

for slot in iter_slots(true, false) do

params[slot] = {}

end

if from_headword then

params.lemma = {list = true}

params.id = {}

params.cat = {list = true}

end

local args = m_para.process(parent_args, params)

local conj_type, conj_subtype, subtypes, orig_lemma, lemma =

detect_decl_and_subtypes(args)

if not conjugations[conj_type] then

error("Unknown conjugation type '" .. conj_type .. "'")

end

local data = {

forms = {},

title = {},

categories = args.cat and ut.clone(args.cat) or {},

form_footnote_indices = {},

footnotes = {},

id = args.id,

overriding_lemma = args.lemma,

} --note: the addition of red superscripted footnotes ('' ... ) is only implemented for the three form printing loops in which it is used

local typeinfo = {

lemma = lemma,

orig_lemma = orig_lemma,

conj_type = conj_type,

conj_subtype = conj_subtype,

subtypes = subtypes,

}

if args.passive_prefix and not args.prefix then

error("Can't specify passive_prefix= without prefix=")

end

if args.plural_prefix and not args.prefix then

error("Can't specify plural_prefix= without prefix=")

end

if args.plural_passive_prefix and not args.prefix then

error("Can't specify plural_passive_prefix= without prefix=")

end

if args.passive_suffix and not args.suffix then

error("Can't specify passive_suffix= without suffix=")

end

if args.plural_suffix and not args.suffix then

error("Can't specify plural_suffix= without suffix=")

end

if args.plural_passive_suffix and not args.suffix then

error("Can't specify plural_passive_suffix= without suffix=")

end

local function normalize_prefix(prefix)

if not prefix then

return nil

end

local no_space_prefix = rmatch(prefix, "(.*)_$")

if no_space_prefix then

return no_space_prefix

elseif rfind(prefix, "%-$") then

return prefix

else

return prefix .. " "

end

end

local function normalize_suffix(suffix)

if not suffix then

return nil

end

local no_space_suffix = rmatch(suffix, "^_(.*)$")

if no_space_suffix then

return no_space_suffix

elseif rfind(suffix, "^%-") then

return suffix

else

return " " .. suffix

end

end

data.prefix = normalize_prefix(args.prefix)

data.passive_prefix = normalize_prefix(args.passive_prefix) or data.prefix

data.plural_prefix = normalize_prefix(args.plural_prefix) or data.prefix

-- First fall back to the passive prefix (e.g. poenās dare, where the

-- plural noun is used with both singular and plural verbs, but there's a

-- separate passive form poenae datur), then to the plural prefix,

-- then to the base prefix.

data.plural_passive_prefix = normalize_prefix(args.plural_passive_prefix) or

normalize_prefix(args.passive_prefix) or data.plural_prefix

data.gen_prefix = normalize_prefix(args.gen_prefix)

data.dat_prefix = normalize_prefix(args.dat_prefix)

data.acc_prefix = normalize_prefix(args.acc_prefix)

data.abl_prefix = normalize_prefix(args.abl_prefix)

data.suffix = normalize_suffix(args.suffix)

data.passive_suffix = normalize_suffix(args.passive_suffix) or data.suffix

data.plural_suffix = normalize_suffix(args.plural_suffix) or data.suffix

-- Same as above for prefixes.

data.plural_passive_suffix = normalize_suffix(args.plural_passive_suffix) or

normalize_suffix(args.passive_suffix) or data.plural_suffix

data.gen_suffix = normalize_suffix(args.gen_suffix)

data.dat_suffix = normalize_suffix(args.dat_suffix)

data.acc_suffix = normalize_suffix(args.acc_suffix)

data.abl_suffix = normalize_suffix(args.abl_suffix)

-- Generate the verb forms

conjugations[conj_type](args, data, typeinfo)

-- Post-process the forms

postprocess(data, typeinfo)

-- Override with user-set forms

override(data, args)

-- Set linked_* forms

set_linked_forms(data, typeinfo)

-- Prepend any prefixes, append any suffixes

add_prefix_suffix(data)

-- Check if the links to the verb forms exist

checkexist(data)

-- Check if the verb is irregular

if not conj_type == 'irreg' then checkirregular(args, data) end

return data, typeinfo

end

local function form_contains(forms, form)

if type(forms) == "string" then

return forms == form

else

return ut.contains(forms, form)

end

end

-- Add a value to a given form key, e.g. "1s_pres_actv_indc". If the

-- value is already present in the key, it won't be added again.

--

-- The value is formed by concatenating STEM and SUF. SUF can be a list,

-- in which case STEM will be concatenated in turn to each value in the

-- list and all the resulting forms added to the key.

--

-- POS is the position to insert the form(s) at; default is at the end.

-- To insert at the beginning specify 1 for POS.

local function add_form(data, key, stem, suf, pos)

if not suf then

return

end

if type(suf) ~= "table" then

suf = {suf}

end

for _, s in ipairs(suf) do

if not data.forms[key] then

data.forms[key] = {}

elseif type(data.forms[key]) == "string" then

data.forms[key] = {data.forms[key]}

end

ut.insert_if_not(data.forms[key], stem .. s, pos)

end

end

-- Add a value to all persons/numbers of a given tense/voice/mood, e.g.

-- "pres_actv_indc" (specified by KEYTYPE). If a value is already present

-- in a key, it won't be added again.

--

-- The value for a given person/number combination is formed by concatenating

-- STEM and the appropriate suffix for that person/number, e.g. SUF1S. The

-- suffix can be a list, in which case STEM will be concatenated in turn to

-- each value in the list and all the resulting forms added to the key. To

-- not add a value for a specific person/number, specify nil or {} for the

-- suffix for the person/number.

local function add_forms(data, keytype, stem, suf1s, suf2s, suf3s, suf1p, suf2p, suf3p)

add_form(data, "1s_" .. keytype, stem, suf1s)

add_form(data, "2s_" .. keytype, stem, suf2s)

add_form(data, "3s_" .. keytype, stem, suf3s)

add_form(data, "1p_" .. keytype, stem, suf1p)

add_form(data, "2p_" .. keytype, stem, suf2p)

add_form(data, "3p_" .. keytype, stem, suf3p)

end

-- Add a value to the 2nd person (singular and plural) of a given

-- tense/voice/mood. This works like add_forms().

local function add_2_forms(data, keytype, stem, suf2s, suf2p)

add_form(data, "2s_" .. keytype, stem, suf2s)

add_form(data, "2p_" .. keytype, stem, suf2p)

end

-- Add a value to the 2nd and 3rd persons (singular and plural) of a given

-- tense/voice/mood. This works like add_forms().

local function add_23_forms(data, keytype, stem, suf2s, suf3s, suf2p, suf3p)

add_form(data, "2s_" .. keytype, stem, suf2s)

add_form(data, "3s_" .. keytype, stem, suf3s)

add_form(data, "2p_" .. keytype, stem, suf2p)

add_form(data, "3p_" .. keytype, stem, suf3p)

end

-- Clear out all forms from a given key (e.g. "1s_pres_actv_indc").

local function clear_form(data, key)

data.forms[key] = nil

end

-- Clear out all forms from all persons/numbers a given tense/voice/mood

-- (e.g. "pres_actv_indc").

local function clear_forms(data, keytype)

clear_form(data, "1s_" .. keytype)

clear_form(data, "2s_" .. keytype)

clear_form(data, "3s_" .. keytype)

clear_form(data, "1p_" .. keytype)

clear_form(data, "2p_" .. keytype)

clear_form(data, "3p_" .. keytype)

end

local function make_perfect_passive(data)

local ppp = data.forms["perf_pasv_ptc"]

if type(ppp) ~= "table" then

ppp = {ppp}

end

local ppplinks = {}

for _, pppform in ipairs(ppp) do

table.insert(ppplinks, make_link({lang = lang, term = pppform}, "term"))

end

local ppplink = table.concat(ppplinks, " or ")

local sumlink = make_link({lang = lang, term = "sum"}, "term")

text_for_slot = {

perf_pasv_indc = "present active indicative",

futp_pasv_indc = "future active indicative",

plup_pasv_indc = "imperfect active indicative",

perf_pasv_subj = "present active subjunctive",

plup_pasv_subj = "imperfect active subjunctive"

}

local prefix_joiner = data.passive_prefix and data.passive_prefix:find(" $") and "+ " or ""

local suffix_joiner = data.passive_suffix and data.passive_suffix:find("^ ") and " +" or ""

for slot, text in pairs(text_for_slot) do

data.forms[slot] =

(data.passive_prefix or "") .. prefix_joiner .. ppplink .. " + " ..

text .. " of " .. sumlink .. suffix_joiner .. (data.passive_suffix or "")

end

end

-- Make the gerund and gerundive/future passive participle. For the forms

-- labeled "gerund", we generate both gerund and gerundive variants if there's

-- a case-specific prefix or suffix for the case in question; otherwise we

-- generate only the gerund per se. BASE is the stem (ending in -nd).

-- UND_VARIANT, if true, means that a gerundive in -und should be generated

-- along with a gerundive in -end. NO_GERUND means to skip generating any

-- gerunds (and gerundive variants). NO_FUTR_PASV_PTC means to skip generating

-- the future passive participle.

local function make_gerund(data, typeinfo, base, und_variant, no_gerund, no_futr_pasv_ptc)

local neut_endings = {

nom = "um",

gen = "ī",

dat = "ō",

acc = "um",

abl = "ō",

}

local endings

if typeinfo.subtypes.f then

endings = {

nom = "a",

gen = "ae",

dat = "ae",

acc = "am",

abl = "ā",

}

elseif typeinfo.subtypes.n then

endings = neut_endings

elseif typeinfo.subtypes.mp then

endings = {

nom = "ī",

gen = "ōrum",

dat = "īs",

acc = "ōs",

abl = "īs",

}

elseif typeinfo.subtypes.fp then

endings = {

nom = "ae",

gen = "ārum",

dat = "īs",

acc = "ās",

abl = "īs",

}

elseif typeinfo.subtypes.np then

endings = {

nom = "a",

gen = "ōrum",

dat = "īs",

acc = "a",

abl = "īs",

}

else

endings = {

nom = "us",

gen = "ī",

dat = "ō",

acc = "um",

abl = "ō",

}

end

if rfind(base, "[uv]end$") then

-- Per Lane's grammar section 899: "Verbs in -ere and -īre often have

-- -undus, when not preceded by u or v, especially in formal style"

und_variant = false

end

local und_base = und_variant and base:gsub("end$", "und")

for case, ending in pairs(endings) do

if case == "nom" then

if not no_futr_pasv_ptc then

if typeinfo.subtypes.passimpers then

ending = "um"

end

add_form(data, "futr_pasv_ptc", "", base .. ending)

if und_base then

add_form(data, "futr_pasv_ptc", "", und_base .. ending)

end

end

elseif (data[case .. "_prefix"] or data[case .. "_suffix"]) and not no_gerund then

add_form(data, "ger_" .. case, "", (data[case .. "_prefix"] or "")

.. base .. ending .. (data[case .. "_suffix"] or ""))

if und_base then

add_form(data, "ger_" .. case, "", (data[case .. "_prefix"] or "")

.. und_base .. ending .. (data[case .. "_suffix"] or ""))

end

end

end

if not no_gerund then

for case, ending in pairs(neut_endings) do

add_form(data, "ger_" .. case, "",

(data.prefix or "") .. base .. ending .. (data.suffix or ""))

end

end

end

postprocess = function(data, typeinfo)

-- Maybe clear out the supine-derived forms (except maybe for the

-- future active participle). Do this first because some code below

-- looks at the perfect participle to derive other forms.

if typeinfo.subtypes.nosup then

-- Some verbs have no supine forms or forms derived from the supine

ut.insert_if_not(data.title, "no supine stem")

ut.insert_if_not(data.categories, "Latin verbs with missing supine stem")

ut.insert_if_not(data.categories, "Latin defective verbs")

for key, _ in pairs(data.forms) do

if cfind(key, "sup") or (

key == "perf_actv_ptc" or key == "perf_pasv_ptc" or key == "perf_pasv_inf" or

key == "futr_actv_ptc" or key == "futr_actv_inf" or key == "futr_pasv_inf" or

(typeinfo.subtypes.depon or typeinfo.subtypes.semidepon or

typeinfo.subtypes.optsemidepon) and key == "perf_actv_inf"

) then

data.forms[key] = nil

end

end

elseif typeinfo.subtypes.supfutractvonly then

-- Some verbs have no supine forms or forms derived from the supine,

-- except for the future active infinitive/participle

ut.insert_if_not(data.title, "no supine stem except in the future active participle")

ut.insert_if_not(data.categories, "Latin verbs with missing supine stem except in the future active participle")

ut.insert_if_not(data.categories, "Latin defective verbs")

for key, _ in pairs(data.forms) do

if cfind(key, "sup") or (

key == "perf_actv_ptc" or key == "perf_pasv_ptc" or key == "perf_pasv_inf" or

key == "futr_pasv_inf"

) then

data.forms[key] = nil

end

end

end

-- Add information for the passive perfective forms

if data.forms["perf_pasv_ptc"] and not form_is_empty(data.forms["perf_pasv_ptc"]) then

if typeinfo.subtypes.passimpers then

-- this should always be a table because it's generated only in

-- make_supine()

local pppforms = data.forms["perf_pasv_ptc"]

for _, ppp in ipairs(pppforms) do

if not form_is_empty(ppp) then

-- make_supine() already generated the neuter form of the PPP.

local nns_ppp = make_raw_link(ppp)

add_form(data, "3s_perf_pasv_indc", nns_ppp, " est")

add_form(data, "3s_futp_pasv_indc", nns_ppp, " erit")

add_form(data, "3s_plup_pasv_indc", nns_ppp, " erat")

add_form(data, "3s_perf_pasv_subj", nns_ppp, " sit")

add_form(data, "3s_plup_pasv_subj", nns_ppp, {" esset", " foret"})

end

end

elseif typeinfo.subtypes.pass3only then

local pppforms = data.forms["perf_pasv_ptc"]

if type(pppforms) ~= "table" then

pppforms = {pppforms}

end

for _, ppp in ipairs(pppforms) do

if not form_is_empty(ppp) then

local ppp_s, ppp_p

if typeinfo.subtypes.mp then

ppp_p = make_raw_link(rsub(ppp, "ī$", "us"), ppp)

elseif typeinfo.subtypes.fp then

ppp_p = make_raw_link(rsub(ppp, "ae$", "us"), ppp)

elseif typeinfo.subtypes.np then

ppp_p = make_raw_link(rsub(ppp, "a$", "us"), ppp)

elseif typeinfo.subtypes.f then

local ppp_lemma = rsub(ppp, "a$", "us")

ppp_s = make_raw_link(ppp_lemma, ppp)

ppp_p = make_raw_link(ppp_lemma, rsub(ppp, "a$", "ae"))

elseif typeinfo.subtypes.n then

local ppp_lemma = rsub(ppp, "um$", "us")

ppp_s = make_raw_link(ppp_lemma, ppp)

ppp_p = make_raw_link(ppp_lemma, rsub(ppp, "um$", "a"))

else

ppp_s = make_raw_link(ppp)

ppp_p = make_raw_link(ppp, rsub(ppp, "us$", "ī"))

end

if not typeinfo.subtypes.mp and not typeinfo.subtypes.fp and not typeinfo.subtypes.np then

add_form(data, "3s_perf_pasv_indc", ppp_s, " est")

add_form(data, "3s_futp_pasv_indc", ppp_s, " erit")

add_form(data, "3s_plup_pasv_indc", ppp_s, " erat")

add_form(data, "3s_perf_pasv_subj", ppp_s, " sit")

add_form(data, "3s_plup_pasv_subj", ppp_s, {" esset", " foret"})

end

add_form(data, "3p_perf_pasv_indc", ppp_p, " sunt")

add_form(data, "3p_futp_pasv_indc", ppp_p, " erunt")

add_form(data, "3p_plup_pasv_indc", ppp_p, " erant")

add_form(data, "3p_perf_pasv_subj", ppp_p, " sint")

add_form(data, "3p_plup_pasv_subj", ppp_p, {" essent", " forent"})

end

end

else

make_perfect_passive(data)

end

end

if typeinfo.subtypes.perfaspres then

-- Perfect forms as present tense

ut.insert_if_not(data.title, "active only")

ut.insert_if_not(data.title, "perfect forms as present")

ut.insert_if_not(data.title, "pluperfect as imperfect")

ut.insert_if_not(data.title, "future perfect as future")

ut.insert_if_not(data.categories, "Latin defective verbs")

ut.insert_if_not(data.categories, "Latin active-only verbs")

ut.insert_if_not(data.categories, "Latin verbs with perfect forms having imperfective meanings")

-- Change perfect passive participle to perfect active participle

data.forms["perf_actv_ptc"] = data.forms["perf_pasv_ptc"]

-- Change perfect active infinitive to present active infinitive

data.forms["pres_actv_inf"] = data.forms["perf_actv_inf"]

-- Remove passive forms

-- Remove present active, imperfect active and future active forms

for key, _ in pairs(data.forms) do

if key ~= "futr_actv_inf" and key ~= "futr_actv_ptc" and (

cfind(key, "pasv") or cfind(key, "pres") and key ~= "pres_actv_inf" or

cfind(key, "impf") or cfind(key, "futr")

) then

data.forms[key] = nil

end

end

-- Change perfect forms to non-perfect forms

for key, form in pairs(data.forms) do

if cfind(key, "perf") and key ~= "perf_actv_ptc" then

data.forms[key:gsub("perf", "pres")] = form

data.forms[key] = nil

elseif cfind(key, "plup") then

data.forms[key:gsub("plup", "impf")] = form

data.forms[key] = nil

elseif cfind(key, "futp") then

data.forms[key:gsub("futp", "futr")] = form

data.forms[key] = nil

elseif cfind(key, "ger") then

data.forms[key] = nil

end

end

data.forms["pres_actv_ptc"] = nil

end

-- Types of irregularity related primarily to the active.

-- These could in theory be combined with those related to the passive and imperative,

-- i.e. there's no reason there couldn't be an impersonal deponent verb with no imperatives.

if typeinfo.subtypes.impers then

-- Impersonal verbs have only third-person singular forms.

ut.insert_if_not(data.title, "impersonal")

ut.insert_if_not(data.categories, "Latin impersonal verbs")

-- Remove all non-3sg forms

for key, _ in pairs(data.forms) do

if key:find("^[12][sp]") or key:find("^3p") then

data.forms[key] = nil

end

end

elseif typeinfo.subtypes["3only"] then

ut.insert_if_not(data.title, "third person only")

ut.insert_if_not(data.categories, "Latin third-person-only verbs")

-- Remove all non-3sg forms

for key, _ in pairs(data.forms) do

if key:find("^[12][sp]") then

data.forms[key] = nil

end

end

end

if typeinfo.subtypes.nopasvperf and not typeinfo.subtypes.nosup and

not typeinfo.subtypes.supfutractvonly then

-- Some verbs have no passive perfect forms (e.g. ārēscō, -ěre).

-- Only do anything here if the verb has a supine; otherwise it

-- necessarily has no passive perfect forms.

ut.insert_if_not(data.title, "no passive perfect forms")

ut.insert_if_not(data.categories, "Latin defective verbs")

-- Remove all passive perfect forms

for key, _ in pairs(data.forms) do

if cfind(key, "pasv") and (cfind(key, "perf") or cfind(key, "plup") or cfind(key, "futp")) then

data.forms[key] = nil

end

end

end

-- Handle certain irregularities in the passive

if typeinfo.subtypes.optsemidepon then

-- Optional semi-deponent verbs use perfective passive forms with active

-- meaning, but also have perfect active forms with the same meaning,

-- and have no imperfective passive. We already generated the perfective

-- forms but need to clear out the imperfective passive.

ut.insert_if_not(data.title, "optionally semi-deponent")

ut.insert_if_not(data.categories, "Latin semi-deponent verbs")

ut.insert_if_not(data.categories, "Latin optionally semi-deponent verbs")

-- Remove imperfective passive forms

for key, _ in pairs(data.forms) do

if cfind(key, "pres_pasv") or cfind(key, "impf_pasv") or cfind(key, "futr_pasv") then

data.forms[key] = nil

end

end

elseif typeinfo.subtypes.semidepon then

-- Semi-deponent verbs use perfective passive forms with active meaning,

-- and have no imperfective passive

ut.insert_if_not(data.title, "semi-deponent")

ut.insert_if_not(data.categories, "Latin semi-deponent verbs")

-- Remove perfective active and imperfective passive forms

for key, _ in pairs(data.forms) do

if cfind(key, "perf_actv") or cfind(key, "plup_actv") or cfind(key, "futp_actv") or cfind(key, "pres_pasv") or cfind(key, "impf_pasv") or cfind(key, "futr_pasv") then

data.forms[key] = nil

end

end

-- Change perfective passive to active

for key, form in pairs(data.forms) do

if cfind(key, "perf_pasv") or cfind(key, "plup_pasv") or cfind(key, "futp_pasv") then

data.forms[key:gsub("pasv", "actv")] = form

data.forms[key] = nil

end

end

elseif typeinfo.subtypes.depon then

-- Deponent verbs use passive forms with active meaning

ut.insert_if_not(data.title, "deponent")

ut.insert_if_not(data.categories, "Latin deponent verbs")

-- Remove active forms and future passive infinitive

for key, _ in pairs(data.forms) do

if cfind(key, "actv") and key ~= "pres_actv_ptc" and key ~= "futr_actv_ptc" and key ~= "futr_actv_inf" or key == "futr_pasv_inf" then

data.forms[key] = nil

end

end

-- Change passive to active

for key, form in pairs(data.forms) do

if cfind(key, "pasv") and key ~= "pres_pasv_ptc" and key ~= "futr_pasv_ptc" and key ~= "futr_pasv_inf" then

data.forms[key:gsub("pasv", "actv")] = form

data.forms[key] = nil

end

end

end

if typeinfo.subtypes.noperf then

-- Some verbs have no perfect stem (e.g. inalbēscō, -ěre)

ut.insert_if_not(data.title, "no perfect stem")

ut.insert_if_not(data.categories, "Latin verbs with missing perfect stem")

ut.insert_if_not(data.categories, "Latin defective verbs")

-- Remove all active perfect forms (passive perfect forms may

-- still exist as they are formed with the supine stem)

for key, _ in pairs(data.forms) do

if cfind(key, "actv") and (cfind(key, "perf") or cfind(key, "plup") or cfind(key, "futp")) then

data.forms[key] = nil

end

end

end

if typeinfo.subtypes.nopass then

-- Remove all passive forms

ut.insert_if_not(data.title, "active only")

ut.insert_if_not(data.categories, "Latin active-only verbs")

-- Remove all non-3sg and passive forms

for key, _ in pairs(data.forms) do

if cfind(key, "pasv") then

data.forms[key] = nil

end

end

elseif typeinfo.subtypes.pass3only then

-- Some verbs have only third-person forms in the passive

ut.insert_if_not(data.title, "only third-person forms in passive")

ut.insert_if_not(data.categories, "Latin verbs with third-person passive")

-- Remove all non-3rd-person passive forms and all passive imperatives

for key, _ in pairs(data.forms) do

if cfind(key, "pasv") and (key:find("^[12][sp]") or cfind(key, "impr")) then

data.forms[key] = nil

end

-- For phrasal verbs with a plural complement, also need to erase the

-- 3s forms.

if typeinfo.subtypes.mp or typeinfo.subtypes.fp or typeinfo.subtypes.np then

if cfind(key, "pasv") and key:find("^3s") then

data.forms[key] = nil

end

end

end

elseif typeinfo.subtypes.passimpers then

-- Some verbs are impersonal in the passive

ut.insert_if_not(data.title, "impersonal in passive")

ut.insert_if_not(data.categories, "Latin verbs with impersonal passive")

-- Remove all non-3sg passive forms

for key, _ in pairs(data.forms) do

if cfind(key, "pasv") and (key:find("^[12][sp]") or key:find("^3p") or cfind(key, "impr")) or cfind(key, "futr_pasv_inf") then

data.forms[key] = nil

end

end

end

-- Handle certain irregularities in the imperative

if typeinfo.subtypes.noimp then

-- Some verbs have no imperatives

ut.insert_if_not(data.title, "no imperatives")

ut.insert_if_not(data.categories, "Latin verbs with missing imperative")

ut.insert_if_not(data.categories, "Latin defective verbs")

-- Remove all imperative forms

for key, _ in pairs(data.forms) do

if cfind(key, "impr") then

data.forms[key] = nil

end

end

end

-- Handle certain irregularities in the future

if typeinfo.subtypes.nofut then

-- Some verbs (e.g. soleō) have no future

ut.insert_if_not(data.title, "no future")

ut.insert_if_not(data.categories, "Latin verbs with missing future")

ut.insert_if_not(data.categories, "Latin defective verbs")

-- Remove all future forms

for key, _ in pairs(data.forms) do

if cfind(key, "fut") then -- handles futr = future and futp = future perfect

data.forms[key] = nil

end

end

end

-- Add the ancient future_passive_participle of certain verbs

-- if typeinfo.pres_stem == "lāb" then

-- data.forms["futr_pasv_ptc"] = "lābundus"

-- elseif typeinfo.pres_stem == "collāb" then

-- data.forms["futr_pasv_ptc"] = "collābundus"

-- elseif typeinfo.pres_stem == "illāb" then

-- data.forms["futr_pasv_ptc"] = "illābundus"

-- elseif typeinfo.pres_stem == "relāb" then

-- data.forms["futr_pasv_ptc"] = "relābundus"

-- end

-- Add the poetic present passive infinitive forms of certain verbs

if typeinfo.subtypes.p3inf then

local is_depon = typeinfo.subtypes.depon

local form = "pres_" .. (is_depon and "actv" or "pasv") .. "_inf"

local noteindex = #(data.footnotes) + 1

local formval = data.forms[form]

if type(formval) ~= "table" then

formval = {formval}

end

local newvals = mw.clone(formval)

for _, fv in ipairs(formval) do

table.insert(newvals, mw.ustring.sub(fv, 1, -2) .. "ier")

end

data.forms[form] = newvals

data.form_footnote_indices[form] = tostring(noteindex)

data.footnotes[noteindex] = 'The present passive infinitive in -ier is a rare poetic form which is attested for this verb.'

end

--Add the syncopated perfect forms, omitting the separately handled fourth conjugation cases

if typeinfo.subtypes.poetsyncperf then

local sss = {

--infinitive

{'perf_actv_inf', 'sse'},

--unambiguous perfect actives

{'2s_perf_actv_indc', 'stī'},

{'2p_perf_actv_indc', 'stis'},

--pluperfect subjunctives

{'1s_plup_actv_subj', 'ssem'},

{'2s_plup_actv_subj', 'ssēs'},

{'3s_plup_actv_subj', 'sset'},

{'1p_plup_actv_subj', 'ssēmus'},

{'2p_plup_actv_subj', 'ssētis'},

{'3p_plup_actv_subj', 'ssent'}

}

local noteindex = #(data.footnotes)+1

function add_sync_perf(form, suff_sync)

local formval = data.forms[form]

if type(formval) ~= "table" then

formval = {formval}

end

local newvals = mw.clone(formval)

for _, fv in ipairs(formval) do

-- Can only syncopate 'vi', or 'vi' spelled as 'ui' after a vowel

if fv:find('vi' .. suff_sync .. '$') or mw.ustring.find(fv, '[aeiouyāēīōūȳăĕĭŏŭ]ui' .. suff_sync.. '$') then

ut.insert_if_not(newvals, mw.ustring.sub(fv, 1, -mw.ustring.len(suff_sync) - 3) .. suff_sync)

end

end

data.forms[form] = newvals

data.form_footnote_indices[form] = noteindex

end

for _, v in ipairs(sss) do

add_sync_perf(v[1], v[2])

end

data.footnotes[noteindex] = "At least one rare poetic syncopated perfect form is attested." end

end

--[=[

Conjugation functions

]=]--

local function get_regular_stems(args, typeinfo)

-- Get the parameters

if typeinfo.subtypes.depon or typeinfo.subtypes.semidepon then

-- Deponent and semi-deponent verbs don't have the perfective principal part.

-- But optionally semi-deponent verbs do.

typeinfo.pres_stem = ine(args[1])

typeinfo.perf_stem = nil

typeinfo.supine_stem = ine(args[2])

else

typeinfo.pres_stem = ine(args[1])

typeinfo.perf_stem = ine(args[2])

typeinfo.supine_stem = ine(args[3])

end

if typeinfo.subtypes.perfaspres and not typeinfo.pres_stem then

typeinfo.pres_stem = "whatever"

end

-- Prepare stems

if not typeinfo.pres_stem then

if NAMESPACE == "Template" then

typeinfo.pres_stem = "-"

else

error("Present stem has not been provided")

end

end

if typeinfo.perf_stem then

typeinfo.perf_stem = mw.text.split(typeinfo.perf_stem, "/")

else

typeinfo.perf_stem = {}

end

if typeinfo.supine_stem then

typeinfo.supine_stem = mw.text.split(typeinfo.supine_stem, "/")

else

typeinfo.supine_stem = {}

end

end

local function has_perf_in_s_or_x(pres_stem, perf_stem)

if pres_stem == perf_stem then

return false

end

return perf_stem and perf_stem:find("[sx]$") ~= nil

end

conjugations["1st"] = function(args, data, typeinfo)

get_regular_stems(args, typeinfo)

table.insert(data.title, "first conjugation")

table.insert(data.categories, "Latin first conjugation verbs")

for _, perf_stem in ipairs(typeinfo.perf_stem) do

if perf_stem == typeinfo.pres_stem .. "āv" then

table.insert(data.categories, "Latin first conjugation verbs with perfect in -av-")

elseif perf_stem == typeinfo.pres_stem .. "u" then

table.insert(data.categories, "Latin first conjugation verbs with perfect in -u-")

elseif perf_stem == typeinfo.pres_stem then

table.insert(data.categories, "Latin first conjugation verbs with suffixless perfect")

else

table.insert(data.categories, "Latin first conjugation verbs with irregular perfect")

end

end

make_pres_1st(data, typeinfo, typeinfo.pres_stem)

make_perf_and_supine(data, typeinfo)

end

conjugations["2nd"] = function(args, data, typeinfo)

get_regular_stems(args, typeinfo)

table.insert(data.title, "second conjugation")

table.insert(data.categories, "Latin second conjugation verbs")

for _, perf_stem in ipairs(typeinfo.perf_stem) do

local pres_stem = typeinfo.pres_stem

pres_stem = pres_stem:gsub("qu", "1")

perf_stem = perf_stem:gsub("qu", "1")

if perf_stem == pres_stem .. "ēv" then

table.insert(data.categories, "Latin second conjugation verbs with perfect in -ev-")

elseif perf_stem == pres_stem .. "u" then

table.insert(data.categories, "Latin second conjugation verbs with perfect in -u-")

elseif perf_stem == pres_stem then

table.insert(data.categories, "Latin second conjugation verbs with suffixless perfect")

elseif has_perf_in_s_or_x(pres_stem, perf_stem) then

table.insert(data.categories, "Latin second conjugation verbs with perfect in -s- or -x-")

else

table.insert(data.categories, "Latin second conjugation verbs with irregular perfect")

end

end

make_pres_2nd(data, typeinfo, typeinfo.pres_stem)

make_perf_and_supine(data, typeinfo)

end

local function set_3rd_conj_categories(data, typeinfo)

table.insert(data.categories, "Latin third conjugation verbs")

for _, perf_stem in ipairs(typeinfo.perf_stem) do

local pres_stem = typeinfo.pres_stem

pres_stem = pres_stem:gsub("qu", "1")

perf_stem = perf_stem:gsub("qu", "1")

if perf_stem == pres_stem .. "āv" then

table.insert(data.categories, "Latin third conjugation verbs with perfect in -av-")

elseif perf_stem == pres_stem .. "ēv" then

table.insert(data.categories, "Latin third conjugation verbs with perfect in -ev-")

elseif perf_stem == pres_stem .. "īv" then

table.insert(data.categories, "Latin third conjugation verbs with perfect in -iv-")

elseif perf_stem == pres_stem .. "i" then

table.insert(data.categories, "Latin third conjugation verbs with perfect in -i-")

elseif perf_stem == pres_stem .. "u" then

table.insert(data.categories, "Latin third conjugation verbs with perfect in -u-")

elseif perf_stem == pres_stem then

table.insert(data.categories, "Latin third conjugation verbs with suffixless perfect")

elseif has_perf_in_s_or_x(pres_stem, perf_stem) then

table.insert(data.categories, "Latin third conjugation verbs with perfect in -s- or -x-")

else

table.insert(data.categories, "Latin third conjugation verbs with irregular perfect")

end

end

end

conjugations["3rd"] = function(args, data, typeinfo)

get_regular_stems(args, typeinfo)

table.insert(data.title, "third conjugation")

set_3rd_conj_categories(data, typeinfo)

if typeinfo.pres_stem and mw.ustring.match(typeinfo.pres_stem,"[āēīōū]sc$") then

table.insert(data.categories, "Latin inchoative verbs")

end

make_pres_3rd(data, typeinfo, typeinfo.pres_stem)

make_perf_and_supine(data, typeinfo)

end

conjugations["3rd-io"] = function(args, data, typeinfo)

get_regular_stems(args, typeinfo)

table.insert(data.title, "third conjugation -variant")

set_3rd_conj_categories(data, typeinfo)

make_pres_3rd_io(data, typeinfo, typeinfo.pres_stem)

make_perf_and_supine(data, typeinfo)

end

local function ivi_ive(form)

form = form:gsub("īvī", "iī")

form = form:gsub("īvi", "ī")

form = form:gsub("īve", "ī")

form = form:gsub("īvē", "ē")

return form

end

conjugations["4th"] = function(args, data, typeinfo)

get_regular_stems(args, typeinfo)

table.insert(data.title, "fourth conjugation")

table.insert(data.categories, "Latin fourth conjugation verbs")

for _, perf_stem in ipairs(typeinfo.perf_stem) do

local pres_stem = typeinfo.pres_stem

pres_stem = pres_stem:gsub("qu", "1")

perf_stem = perf_stem:gsub("qu", "1")

if perf_stem == pres_stem .. "īv" then

table.insert(data.categories, "Latin fourth conjugation verbs with perfect in -iv-")

elseif perf_stem == pres_stem .. "i" then

table.insert(data.categories, "Latin fourth conjugation verbs with perfect in -i-")

elseif perf_stem == pres_stem .. "u" then

table.insert(data.categories, "Latin fourth conjugation verbs with perfect in -u-")

elseif perf_stem == pres_stem then

table.insert(data.categories, "Latin fourth conjugation verbs with suffixless perfect")

elseif has_perf_in_s_or_x(pres_stem, perf_stem) then

table.insert(data.categories, "Latin fourth conjugation verbs with perfect in -s- or -x-")

else

table.insert(data.categories, "Latin fourth conjugation verbs with irregular perfect")

end

end

make_pres_4th(data, typeinfo, typeinfo.pres_stem)

make_perf_and_supine(data, typeinfo)

if form_contains(data.forms["1s_pres_actv_indc"], "serviō") or form_contains(data.forms["1s_pres_actv_indc"], "saeviō") then

add_forms(data, "impf_actv_indc", typeinfo.pres_stem,

{"iēbam", "ībam"},

{"iēbās", "ībās"},

{"iēbat", "ībat"},

{"iēbāmus", "ībāmus"},

{"iēbātis", "ībātis"},

{"iēbant", "ībant"}

)

add_forms(data, "futr_actv_indc", typeinfo.pres_stem,

{"iam", "ībō"},

{"iēs", "ībis"},

{"iet", "ībit"},

{"iēmus", "ībimus"},

{"iētis", "ībitis"},

{"ient", "ībunt"}

)

end

if typeinfo.subtypes.alwayssyncperf or typeinfo.subtypes.optsyncperf then

for key, form in pairs(data.forms) do

if cfind(key, "perf") or cfind(key, "plup") or cfind(key, "futp") then

local forms = data.forms[key]

if type(forms) ~= "table" then

forms = {forms}

end

data.forms[key] = {}

for _, f in ipairs(forms) do

if typeinfo.subtypes.optsyncperf then

ut.insert_if_not(data.forms[key], f)

end

ut.insert_if_not(data.forms[key], ivi_ive(f))

end

end

end

end

end

-- Irregular conjugations

local irreg_conjugations = {}

conjugations["irreg"] = function(args, data, typeinfo)

local verb = ine(args[1])

local prefix = ine(args[2])

if not verb then

if NAMESPACE == "Template" then

verb = "sum"

else

error("The verb to be conjugated has not been specified.")

end

end

if not irreg_conjugations[verb] then

error("The verb '" .. verb .. "' is not recognised as an irregular verb.")

end

typeinfo.verb = verb

typeinfo.prefix = prefix

-- Generate the verb forms

irreg_conjugations[verb](args, data, typeinfo)

end

irreg_conjugations["aio"] = function(args, data, typeinfo)

table.insert(data.title, "third conjugation iō-variant")

table.insert(data.title, "irregular")

table.insert(data.title, "active only")

table.insert(data.title, "highly defective")

table.insert(data.categories, "Latin third conjugation verbs")

table.insert(data.categories, "Latin irregular verbs")

table.insert(data.categories, "Latin active-only verbs")

table.insert(data.categories, "Latin defective verbs")

-- Signal to {{la-verb}} to display the verb as irregular and highly defective

typeinfo.subtypes.irreg = true

typeinfo.subtypes.highlydef = true

local prefix = typeinfo.prefix or ""

data.forms["1s_pres_actv_indc"] = prefix .. "aiō"

data.forms["2s_pres_actv_indc"] = prefix .. "ais"

data.forms["3s_pres_actv_indc"] = prefix .. "ait"

data.forms["3p_pres_actv_indc"] = prefix .. "aiunt"

data.forms["1s_impf_actv_indc"] = prefix .. "aiēbam"

data.forms["2s_impf_actv_indc"] = prefix .. "aiēbās"

data.forms["3s_impf_actv_indc"] = prefix .. "aiēbat"

data.forms["1p_impf_actv_indc"] = prefix .. "aiēbāmus"

data.forms["2p_impf_actv_indc"] = prefix .. "aiēbātis"

data.forms["3p_impf_actv_indc"] = prefix .. "aiēbant"

data.forms["2s_perf_actv_indc"] = prefix .. "aistī"

data.forms["3s_perf_actv_indc"] = prefix .. "ait"

data.forms["2s_pres_actv_subj"] = prefix .. "aiās"

data.forms["3s_pres_actv_subj"] = prefix .. "aiat"

data.forms["3p_pres_actv_subj"] = prefix .. "aiant"

data.forms["2s_pres_actv_impr"] = prefix .. "ai"

data.forms["pres_actv_inf"] = prefix .. "aiere"

data.forms["pres_actv_ptc"] = prefix .. "aiēns"

end

irreg_conjugations["aiio"] = function(args, data, typeinfo)

table.insert(data.title, "third conjugation iō-variant")

table.insert(data.title, "irregular")

table.insert(data.title, "active only")

table.insert(data.title, "highly defective")

table.insert(data.categories, "Latin third conjugation verbs")

table.insert(data.categories, "Latin irregular verbs")

table.insert(data.categories, "Latin active-only verbs")

table.insert(data.categories, "Latin defective verbs")

-- Signal to {{la-verb}} to display the verb as irregular and highly defective

typeinfo.subtypes.irreg = true

typeinfo.subtypes.highlydef = true

local prefix = typeinfo.prefix or ""

data.forms["1s_pres_actv_indc"] = prefix .. "aiiō"

data.forms["2s_pres_actv_indc"] = prefix .. "ais"

data.forms["3s_pres_actv_indc"] = prefix .. "ait"

data.forms["3p_pres_actv_indc"] = prefix .. "aiunt"

data.forms["1s_impf_actv_indc"] = prefix .. "aiiēbam"

data.forms["2s_impf_actv_indc"] = prefix .. "aiiēbās"

data.forms["3s_impf_actv_indc"] = prefix .. "aiiēbat"

data.forms["1p_impf_actv_indc"] = prefix .. "aiiēbāmus"

data.forms["2p_impf_actv_indc"] = prefix .. "aiiēbātis"

data.forms["3p_impf_actv_indc"] = prefix .. "aiiēbant"

data.forms["2s_perf_actv_indc"] = prefix .. "aistī"

data.forms["3s_perf_actv_indc"] = prefix .. "ait"

data.forms["2s_pres_actv_subj"] = prefix .. "aiiās"

data.forms["3s_pres_actv_subj"] = prefix .. "aiiat"

data.forms["3p_pres_actv_subj"] = prefix .. "aiiant"

data.forms["2s_pres_actv_impr"] = prefix .. "ai"

data.forms["pres_actv_inf"] = prefix .. "aiiere"

data.forms["pres_actv_ptc"] = prefix .. "aiiēns"

end

irreg_conjugations["ajo"] = function(args, data, typeinfo)

table.insert(data.title, "third conjugation iō-variant")

table.insert(data.title, "irregular")

table.insert(data.title, "active only")

table.insert(data.title, "highly defective")

table.insert(data.categories, "Latin third conjugation verbs")

table.insert(data.categories, "Latin irregular verbs")

table.insert(data.categories, "Latin active-only verbs")

table.insert(data.categories, "Latin defective verbs")

-- Signal to {{la-verb}} to display the verb as irregular and highly defective

typeinfo.subtypes.irreg = true

typeinfo.subtypes.highlydef = true

local prefix = typeinfo.prefix or ""

data.forms["1s_pres_actv_indc"] = prefix .. "ajō"

data.forms["2s_pres_actv_indc"] = prefix .. "ais"

data.forms["3s_pres_actv_indc"] = prefix .. "ait"

data.forms["3p_pres_actv_indc"] = prefix .. "ajunt"

data.forms["1s_impf_actv_indc"] = prefix .. "ajēbam"

data.forms["2s_impf_actv_indc"] = prefix .. "ajēbās"

data.forms["3s_impf_actv_indc"] = prefix .. "ajēbat"

data.forms["1p_impf_actv_indc"] = prefix .. "ajēbāmus"

data.forms["2p_impf_actv_indc"] = prefix .. "ajēbātis"

data.forms["3p_impf_actv_indc"] = prefix .. "ajēbant"

data.forms["2s_perf_actv_indc"] = prefix .. "aistī"

data.forms["3s_perf_actv_indc"] = prefix .. "ait"

data.forms["2s_pres_actv_subj"] = prefix .. "ajās"

data.forms["3s_pres_actv_subj"] = prefix .. "ajat"

data.forms["3p_pres_actv_subj"] = prefix .. "ajant"

data.forms["2s_pres_actv_impr"] = prefix .. "ai"

data.forms["pres_actv_inf"] = prefix .. "ajere"

data.forms["pres_actv_ptc"] = prefix .. "ajēns"

end

irreg_conjugations["dico"] = function(args, data, typeinfo)

table.insert(data.title, "third conjugation")

table.insert(data.title, "irregular short imperative")

table.insert(data.categories, "Latin third conjugation verbs")

table.insert(data.categories, "Latin irregular verbs")

local prefix = typeinfo.prefix or ""

make_pres_3rd(data, typeinfo, prefix .. "dīc")

make_perf(data, prefix .. "dīx")

make_supine(data, typeinfo, prefix .. "dict")

add_form(data, "2s_pres_actv_impr", prefix, "dīc", 1)

end

irreg_conjugations["do"] = function(args, data, typeinfo)

table.insert(data.title, "first conjugation")

table.insert(data.title, "irregular short a in most forms except " .. make_link({lang = lang, alt = "dās"}, "term") .. " and " .. make_link({lang = lang, alt = "dā"}, "term"))

table.insert(data.categories, "Latin first conjugation verbs")

table.insert(data.categories, "Latin irregular verbs")

-- Signal to {{la-verb}} to display the verb as irregular

typeinfo.subtypes.irreg = true

local prefix = typeinfo.prefix or ""

make_perf(data, prefix .. "ded")

make_supine(data, typeinfo, prefix .. "dat")

-- Active imperfective indicative

add_forms(data, "pres_actv_indc", prefix, "dō", "dās", "dat", "damus", "datis", "dant")

add_forms(data, "impf_actv_indc", prefix, "dabam", "dabās", "dabat", "dabāmus", "dabātis", "dabant")

add_forms(data, "futr_actv_indc", prefix, "dabō", "dabis", "dabit", "dabimus", "dabitis", "dabunt")

-- Passive imperfective indicative

add_forms(data, "pres_pasv_indc", prefix, "dor", {"daris", "dare"}, "datur", "damur", "daminī", "dantur")

add_forms(data, "impf_pasv_indc", prefix, "dabar", {"dabāris", "dabāre"}, "dabātur", "dabāmur", "dabāminī", "dabantur")

add_forms(data, "futr_pasv_indc", prefix, "dabor", {"daberis", "dabere"}, "dabitur", "dabimur", "dabiminī", "dabuntur")

-- Active imperfective subjunctive

add_forms(data, "pres_actv_subj", prefix, "dem", "dēs", "det", "dēmus", "dētis", "dent")

add_forms(data, "impf_actv_subj", prefix, "darem", "darēs", "daret", "darēmus", "darētis", "darent")

-- Passive imperfective subjunctive

add_forms(data, "pres_pasv_subj", prefix, "der", {"dēris", "dēre"}, "dētur", "dēmur", "dēminī", "dentur")

add_forms(data, "impf_pasv_subj", prefix, "darer", {"darēris", "darēre"}, "darētur", "darēmur", "darēminī", "darentur")

-- Imperative

add_2_forms(data, "pres_actv_impr", prefix, "dā", "date")

add_23_forms(data, "futr_actv_impr", prefix, "datō", "datō", "datōte", "dantō")

add_2_forms(data, "pres_pasv_impr", prefix, "dare", "daminī")

-- no 2p form

add_23_forms(data, "futr_pasv_impr", prefix, "dator", "dator", {}, "dantor")

-- Present infinitives

data.forms["pres_actv_inf"] = prefix .. "dare"

data.forms["pres_pasv_inf"] = prefix .. "darī"

-- Imperfective participles

data.forms["pres_actv_ptc"] = prefix .. "dāns"

-- Gerund

make_gerund(data, typeinfo, prefix .. "dand")

end

irreg_conjugations["duco"] = function(args, data, typeinfo)

table.insert(data.title, "third conjugation")

table.insert(data.title, "irregular short imperative")

table.insert(data.categories, "Latin third conjugation verbs")

table.insert(data.categories, "Latin irregular verbs")

local prefix = typeinfo.prefix or ""

make_pres_3rd(data, typeinfo, prefix .. "dūc")

make_perf(data, prefix .. "dūx")

make_supine(data, typeinfo, prefix .. "duct")

add_form(data, "2s_pres_actv_impr", prefix, "dūc", 1)

end

irreg_conjugations["edo"] = function(args, data, typeinfo)

table.insert(data.title, "third conjugation")

table.insert(data.title, "some irregular alternative forms")

table.insert(data.categories, "Latin third conjugation verbs")

table.insert(data.categories, "Latin irregular verbs")

-- Signal to {{la-verb}} to display the verb as irregular

typeinfo.subtypes.irreg = true

local prefix = typeinfo.prefix or ""

make_pres_3rd(data, typeinfo, prefix .. "ed")

make_perf(data, prefix .. "ēd")

make_supine(data, typeinfo, prefix .. "ēs")

-- Active imperfective indicative

add_forms(data, "pres_actv_indc", prefix, {}, "ēs", "ēst", {}, "ēstis", {})

-- Passive imperfective indicative

add_form(data, "3s_pres_pasv_indc", prefix, "ēstur")

-- Active imperfective subjunctive

add_forms(data, "pres_actv_subj", prefix, "edim", "edīs", "edit", "edīmus", "edītis", "edint")

add_forms(data, "impf_actv_subj", prefix, "ēssem", "ēssēs", "ēsset", "ēssēmus", "ēssētis", "ēssent")

-- Active imperative

add_2_forms(data, "pres_actv_impr", prefix, "ēs", "ēste")

add_23_forms(data, "futr_actv_impr", prefix, "ēstō", "ēstō", "ēstōte", {})

-- Present infinitives

add_form(data, "pres_actv_inf", prefix, "ēsse")

end

irreg_conjugations["eo"] = function(args, data, typeinfo)

table.insert(data.title, "irregular")

table.insert(data.categories, "Latin irregular verbs")

local prefix = typeinfo.prefix or ""

make_perf(data, prefix .. "i")

make_supine(data, typeinfo, prefix .. "it")

-- Active imperfective indicative

add_forms(data, "pres_actv_indc", prefix, "eō", "īs", "it", "īmus", "ītis",

prefix == "prōd" and {"eunt", "īnunt"} or "eunt")

add_forms(data, "impf_actv_indc", prefix, "ībam", "ībās", "ībat", "ībāmus", "ībātis", "ībant")

add_forms(data, "futr_actv_indc", prefix, "ībō", "ībis", "ībit", "ībimus", "ībitis", "ībunt")

-- Active perfective indicative

add_form(data, "1s_perf_actv_indc", prefix, "īvī")

data.forms["2s_perf_actv_indc"] = {prefix .. "īstī", prefix .. "īvistī"}

add_form(data, "3s_perf_actv_indc", prefix, "īvit")

data.forms["2p_perf_actv_indc"] = prefix .. "īstis"

-- Passive imperfective indicative

add_forms(data, "pres_pasv_indc", prefix, "eor", { "īris", "īre"}, "ītur", "īmur", "īminī", "euntur")

add_forms(data, "impf_pasv_indc", prefix, "ībar", {"ībāris", "ībāre"}, "ībātur", "ībāmur", "ībāminī", "ībantur")

add_forms(data, "futr_pasv_indc", prefix, "ībor", {"īberis", "ībere"}, "ībitur", "ībimur", "ībiminī", "ībuntur")

-- Active imperfective subjunctive

add_forms(data, "pres_actv_subj", prefix, "eam", "eās", "eat", "eāmus", "eātis", "eant")

add_forms(data, "impf_actv_subj", prefix, "īrem", "īrēs", "īret", "īrēmus", "īrētis", "īrent")

-- Active perfective subjunctive

data.forms["1s_plup_actv_subj"] = prefix .. "īssem"

data.forms["2s_plup_actv_subj"] = prefix .. "īssēs"

data.forms["3s_plup_actv_subj"] = prefix .. "īsset"

data.forms["1p_plup_actv_subj"] = prefix .. "īssēmus"

data.forms["2p_plup_actv_subj"] = prefix .. "īssētis"

data.forms["3p_plup_actv_subj"] = prefix .. "īssent"

-- Passive imperfective subjunctive

add_forms(data, "pres_pasv_subj", prefix, "ear", {"eāris", "eāre"}, "eātur", "eāmur", "eāminī", "eantur")

add_forms(data, "impf_pasv_subj", prefix, "īrer", {"īrēris", "īrēre"}, "īrētur", "īrēmur", "īrēminī", "īrentur")

-- Imperative

add_2_forms(data, "pres_actv_impr", prefix, "ī", "īte")

add_23_forms(data, "futr_actv_impr", prefix, "ītō", "ītō", "ītōte", "euntō")

add_2_forms(data, "pres_pasv_impr", prefix, "īre", "īminī")

add_23_forms(data, "futr_pasv_impr", prefix, "ītor", "ītor", {}, "euntor")

-- Present infinitives

data.forms["pres_actv_inf"] = prefix .. "īre"

data.forms["pres_pasv_inf"] = prefix .. "īrī"

-- Perfect/future infinitives

data.forms["perf_actv_inf"] = prefix .. "īsse"

-- Imperfective participles

data.forms["pres_actv_ptc"] = prefix .. "iēns"

-- Gerund

make_gerund(data, typeinfo, prefix .. "eund")

end

local function fio(data, prefix, voice)

-- Active/passive imperfective indicative

add_forms(data, "pres_" .. voice .. "_indc", prefix,

"fīō", "fīs", "fit", "fīmus", "fītis", "fīunt")

add_forms(data, "impf_" .. voice .. "_indc", prefix .. "fīēb",

"am", "ās", "at", "āmus", "ātis", "ant")

add_forms(data, "futr_" .. voice .. "_indc", prefix .. "fī",

"am", "ēs", "et", "ēmus", "ētis", "ent")

-- Active/passive imperfective subjunctive

add_forms(data, "pres_" .. voice .. "_subj", prefix .. "fī",

"am", "ās", "at", "āmus", "ātis", "ant")

add_forms(data, "impf_" .. voice .. "_subj", prefix .. "fier",

"em", "ēs", "et", "ēmus", "ētis", "ent")

-- Active/passive imperative

add_2_forms(data, "pres_" .. voice .. "_impr", prefix .. "fī", "", "te")

add_23_forms(data, "futr_" .. voice .. "_impr", prefix .. "fī", "tō", "tō", "tōte", "untō")

-- Active/passive present infinitive

add_form(data, "pres_" .. voice .. "_inf", prefix, "fierī")

end

irreg_conjugations["facio"] = function(args, data, typeinfo)

table.insert(data.title, "third conjugation -variant")

table.insert(data.title, "irregular and suppletive in the passive")

table.insert(data.categories, "Latin third conjugation verbs")

table.insert(data.categories, "Latin irregular verbs")

table.insert(data.categories, "Latin suppletive verbs")

local prefix = typeinfo.prefix or ""

make_pres_3rd_io(data, typeinfo, prefix .. "fac", "nopass")

-- We said no passive, but we do want the future passive participle.

make_gerund(data, typeinfo, prefix .. "faciend", "und-variant", "no-gerund")

make_perf(data, prefix .. "fēc")

make_supine(data, typeinfo, prefix .. "fact")

-- Active imperative

if prefix == "" then

add_form(data, "2s_pres_actv_impr", prefix, "fac", 1)

end

fio(data, prefix, "pasv")

end

irreg_conjugations["fio"] = function(args, data, typeinfo)

table.insert(data.title, "third conjugation -variant")

table.insert(data.title, "irregular long ī")

if not typeinfo.subtypes.nosup then

table.insert(data.title, "suppletive in the supine stem")

end

table.insert(data.categories, "Latin third conjugation verbs")

table.insert(data.categories, "Latin irregular verbs")

table.insert(data.categories, "Latin suppletive verbs")

local prefix = typeinfo.prefix or ""

typeinfo.subtypes.semidepon = true

fio(data, prefix, "actv")

make_supine(data, typeinfo, prefix .. "fact")

-- Perfect/future infinitives

data.forms["futr_actv_inf"] = data.forms["futr_pasv_inf"]

-- Imperfective participles

data.forms["pres_actv_ptc"] = nil

data.forms["futr_actv_ptc"] = nil

-- Gerund

make_gerund(data, typeinfo, prefix .. "fiend", "und-variant")

end

irreg_conjugations["fero"] = function(args, data, typeinfo)

table.insert(data.title, "third conjugation")

table.insert(data.title, "irregular")

table.insert(data.title, "suppletive")

table.insert(data.categories, "Latin third conjugation verbs")

table.insert(data.categories, "Latin irregular verbs")

table.insert(data.categories, "Latin suppletive verbs")

-- Signal to {{la-verb}} to display the verb as irregular

typeinfo.subtypes.irreg = true

local prefix_pres = typeinfo.prefix or ""

local prefix_perf = ine(args[3])

local prefix_supine = ine(args[4])

prefix_perf = prefix_perf or prefix_pres

prefix_supine = prefix_supine or prefix_pres

make_pres_3rd(data, typeinfo, prefix_pres .. "fer")

if prefix_perf == "" then

make_perf(data, {"tul", "tetul"})

local noteindex = #(data.footnotes) + 1

for slot in iter_slots(false, false) do

if cfind(slot, "perf") or cfind(slot, "plup") or cfind(slot, "futp") then

data.form_footnote_indices[slot] = tostring(noteindex)

data.footnotes[noteindex] = 'Archaic.'

end

end

else

make_perf(data, prefix_perf .. "tul")

end

make_supine(data, typeinfo, prefix_supine .. "lāt")

-- Active imperfective indicative

data.forms["2s_pres_actv_indc"] = prefix_pres .. "fers"

data.forms["3s_pres_actv_indc"] = prefix_pres .. "fert"

data.forms["2p_pres_actv_indc"] = prefix_pres .. "fertis"

-- Passive imperfective indicative

data.forms["3s_pres_pasv_indc"] = prefix_pres .. "fertur"

-- Active imperfective subjunctive

data.forms["1s_impf_actv_subj"] = prefix_pres .. "ferrem"

data.forms["2s_impf_actv_subj"] = prefix_pres .. "ferrēs"

data.forms["3s_impf_actv_subj"] = prefix_pres .. "ferret"

data.forms["1p_impf_actv_subj"] = prefix_pres .. "ferrēmus"

data.forms["2p_impf_actv_subj"] = prefix_pres .. "ferrētis"

data.forms["3p_impf_actv_subj"] = prefix_pres .. "ferrent"

-- Passive present indicative

data.forms["2s_pres_pasv_indc"] = {prefix_pres .. "ferris", prefix_pres .. "ferre"}

-- Passive imperfective subjunctive

data.forms["1s_impf_pasv_subj"] = prefix_pres .. "ferrer"

data.forms["2s_impf_pasv_subj"] = {prefix_pres .. "ferrēris", prefix_pres .. "ferrēre"}

data.forms["3s_impf_pasv_subj"] = prefix_pres .. "ferrētur"

data.forms["1p_impf_pasv_subj"] = prefix_pres .. "ferrēmur"

data.forms["2p_impf_pasv_subj"] = prefix_pres .. "ferrēminī"

data.forms["3p_impf_pasv_subj"] = prefix_pres .. "ferrentur"

-- Imperative

data.forms["2s_pres_actv_impr"] = prefix_pres .. "fer"

data.forms["2p_pres_actv_impr"] = prefix_pres .. "ferte"

data.forms["2s_futr_actv_impr"] = prefix_pres .. "fertō"

data.forms["3s_futr_actv_impr"] = prefix_pres .. "fertō"

data.forms["2p_futr_actv_impr"] = prefix_pres .. "fertōte"

data.forms["2s_pres_pasv_impr"] = prefix_pres .. "ferre"

data.forms["2s_futr_pasv_impr"] = prefix_pres .. "fertor"

data.forms["3s_futr_pasv_impr"] = prefix_pres .. "fertor"

-- Present infinitives

data.forms["pres_actv_inf"] = prefix_pres .. "ferre"

data.forms["pres_pasv_inf"] = prefix_pres .. "ferrī"

end

irreg_conjugations["inquam"] = function(args, data, typeinfo)

table.insert(data.title, "irregular")

table.insert(data.title, "highly defective")

table.insert(data.categories, "Latin irregular verbs")

table.insert(data.categories, "Latin defective verbs")

-- Signal to {{la-verb}} to display the verb as highly defective

-- (it already displays as irregular because conj == "irreg" and

-- subconj == "irreg")

typeinfo.subtypes.highlydef = true

data.forms["1s_pres_actv_indc"] = "inquam"

data.forms["2s_pres_actv_indc"] = "inquis"

data.forms["3s_pres_actv_indc"] = "inquit"

data.forms["1p_pres_actv_indc"] = "inquimus"

data.forms["2p_pres_actv_indc"] = "inquitis"

data.forms["3p_pres_actv_indc"] = "inquiunt"

data.forms["2s_futr_actv_indc"] = "inquiēs"

data.forms["3s_futr_actv_indc"] = "inquiet"

data.forms["3s_impf_actv_indc"] = "inquiēbat"

data.forms["1s_perf_actv_indc"] = "inquiī"

data.forms["2s_perf_actv_indc"] = "inquistī"

data.forms["3s_perf_actv_indc"] = "inquit"

data.forms["3s_pres_actv_subj"] = "inquiat"

data.forms["2s_pres_actv_impr"] = "inque"

data.forms["2s_futr_actv_impr"] = "inquitō"

data.forms["3s_futr_actv_impr"] = "inquitō"

data.forms["pres_actv_ptc"] = "inquiēns"

end

local function libet_lubet(data, typeinfo, stem)

table.insert(data.title, "second conjugation")

table.insert(data.title, "mostly impersonal")

table.insert(data.categories, "Latin second conjugation verbs")

table.insert(data.categories, "Latin impersonal verbs")

typeinfo.subtypes.nopass = true

local prefix = typeinfo.prefix or ""

stem = prefix .. stem

-- Active imperfective indicative

data.forms["3s_pres_actv_indc"] = stem .. "et"

data.forms["3s_impf_actv_indc"] = stem .. "ēbat"

data.forms["3s_futr_actv_indc"] = stem .. "ēbit"

-- Active perfective indicative

data.forms["3s_perf_actv_indc"] = {stem .. "uit", "" .. stem .. "itum est"}

data.forms["3s_plup_actv_indc"] = {stem .. "uerat", "" .. stem .. "itum erat"}

data.forms["3s_futp_actv_indc"] = {stem .. "uerit", "" .. stem .. "itum erit"}

-- Active imperfective subjunctive

data.forms["3s_pres_actv_subj"] = stem .. "eat"

data.forms["3s_impf_actv_subj"] = stem .. "ēret"

-- Active perfective subjunctive

data.forms["3s_perf_actv_subj"] = {stem .. "uerit", "" .. stem .. "itum sit"}

data.forms["3s_plup_actv_subj"] = {stem .. "uisset", "" .. stem .. "itum esset"}

data.forms["3p_plup_actv_subj"] = stem .. "uissent"

-- Present infinitives

data.forms["pres_actv_inf"] = stem .. "ēre"

-- Perfect infinitive

data.forms["perf_actv_inf"] = {stem .. "uisse", "" .. stem .. "itum esse"}

-- Imperfective participles

data.forms["pres_actv_ptc"] = stem .. "ēns"

data.forms["perf_actv_ptc"] = stem .. "itum"

end

irreg_conjugations["libet"] = function(args, data, typeinfo)

libet_lubet(data, typeinfo, "lib")

end

irreg_conjugations["lubet"] = function(args, data, typeinfo)

libet_lubet(data, typeinfo, "lub")

end

irreg_conjugations["licet"] = function(args, data, typeinfo)

table.insert(data.title, "second conjugation")

table.insert(data.title, "mostly impersonal")

table.insert(data.categories, "Latin second conjugation verbs")

table.insert(data.categories, "Latin impersonal verbs")

typeinfo.subtypes.nopass = true

-- Active imperfective indicative

data.forms["3s_pres_actv_indc"] = "licet"

data.forms["3p_pres_actv_indc"] = "licent"

data.forms["3s_impf_actv_indc"] = "licēbat"

data.forms["3p_impf_actv_indc"] = "licēbant"

data.forms["3s_futr_actv_indc"] = "licēbit"

-- Active perfective indicative

data.forms["3s_perf_actv_indc"] = {"licuit", "licitum est"}

data.forms["3s_plup_actv_indc"] = {"licuerat", "licitum erat"}

data.forms["3s_futp_actv_indc"] = {"licuerit", "licitum erit"}

-- Active imperfective subjunctive

data.forms["3s_pres_actv_subj"] = "liceat"

data.forms["3p_pres_actv_subj"] = "liceant"

data.forms["3s_impf_actv_subj"] = "licēret"

-- Perfective subjunctive

data.forms["3s_perf_actv_subj"] = {"licuerit", "licitum sit"}

data.forms["3s_plup_actv_subj"] = {"licuisset", "licitum esset"}

-- Imperative

data.forms["2s_futr_actv_impr"] = "licētō"

data.forms["3s_futr_actv_impr"] = "licētō"

-- Infinitives

data.forms["pres_actv_inf"] = "licēre"

data.forms["perf_actv_inf"] = {"licuisse", "licitum esse"}

data.forms["futr_actv_inf"] = "licitūrum esse"

-- Participles

data.forms["pres_actv_ptc"] = "licēns"

data.forms["perf_actv_ptc"] = "licitus"

data.forms["futr_actv_ptc"] = "licitūrus"

end

-- Handle most forms of volō, mālō, nōlō.

local function volo_malo_nolo(data, indc_stem, subj_stem)

-- Present active indicative needs to be done individually as each

-- verb is different.

add_forms(data, "impf_actv_indc", indc_stem .. "ēb", "am", "ās", "at", "āmus", "ātis", "ant")

add_forms(data, "futr_actv_indc", indc_stem, "am", "ēs", "et", "ēmus", "ētis", "ent")

-- Active imperfective subjunctive

add_forms(data, "pres_actv_subj", subj_stem, "im", "īs", "it", "īmus", "ītis", "int")

add_forms(data, "impf_actv_subj", subj_stem .. "l", "em", "ēs", "et", "ēmus", "ētis", "ent")

-- Present infinitives

data.forms["pres_actv_inf"] = subj_stem .. "le"

-- Imperfective participles

data.forms["pres_actv_ptc"] = indc_stem .. "ēns"

end

irreg_conjugations["volo"] = function(args, data, typeinfo)

table.insert(data.title, "irregular")

table.insert(data.categories, "Latin irregular verbs")

local prefix = typeinfo.prefix or ""

typeinfo.subtypes.nopass = true

typeinfo.subtypes.noimp = true

make_perf(data, prefix .. "volu")

-- Active imperfective indicative

add_forms(data, "pres_actv_indc", prefix,

"volō", "vīs", prefix ~= "" and "vult" or {"vult", "volt"},

"volumus", prefix ~= "" and "vultis" or {"vultis", "voltis"}, "volunt")

volo_malo_nolo(data, prefix .. "vol", prefix .. "vel")

end

irreg_conjugations["malo"] = function(args, data, typeinfo)

table.insert(data.title, "irregular")

table.insert(data.categories, "Latin irregular verbs")

typeinfo.subtypes.nopass = true

typeinfo.subtypes.noimp = true

make_perf(data, "mālu")

-- Active imperfective indicative

add_forms(data, "pres_actv_indc", "",

"mālō", "māvīs", "māvult", "mālumus", "māvultis", "mālunt")

volo_malo_nolo(data, "māl", "māl")

end

irreg_conjugations["nolo"] = function(args, data, typeinfo)

table.insert(data.title, "irregular")

table.insert(data.categories, "Latin irregular verbs")

typeinfo.subtypes.nopass = true

make_perf(data, "nōlu")

-- Active imperfective indicative

add_forms(data, "pres_actv_indc", "",

"nōlō", "nōn vīs", "nōn vult", "nōlumus", "nōn vultis", "nōlunt")

add_forms(data, "impf_actv_indc", "nōlēb", "am", "ās", "at", "āmus", "ātis", "ant")

volo_malo_nolo(data, "nōl", "nōl")

-- Imperative

add_2_forms(data, "pres_actv_impr", "nōlī", "", "te")

add_23_forms(data, "futr_actv_impr", "nōl", "itō", "itō", "itōte", "untō")

end

irreg_conjugations["possum"] = function(args, data, typeinfo)

table.insert(data.title, "highly irregular")

table.insert(data.title, "suppletive")

table.insert(data.categories, "Latin irregular verbs")

table.insert(data.categories, "Latin suppletive verbs")

typeinfo.subtypes.nopass = true

make_perf(data, "potu")

-- Active imperfective indicative

add_forms(data, "pres_actv_indc", "", "possum", "potes", "potest",

"possumus", "potestis", "possunt")

add_forms(data, "impf_actv_indc", "poter", "am", "ās", "at", "āmus", "ātis", "ant")

add_forms(data, "futr_actv_indc", "poter", "ō", {"is", "e"}, "it", "imus", "itis", "unt")

-- Active imperfective subjunctive

add_forms(data, "pres_actv_subj", "poss", "im", "īs", "it", "īmus", "ītis", "int")

add_forms(data, "impf_actv_subj", "poss", "em", "ēs", "et", "ēmus", "ētis", "ent")

-- Present infinitives

data.forms["pres_actv_inf"] = "posse"

-- Imperfective participles

data.forms["pres_actv_ptc"] = "potēns"

end

irreg_conjugations["piget"] = function(args, data, typeinfo)

table.insert(data.title, "second conjugation")

table.insert(data.title, "impersonal")

table.insert(data.title, "semi-deponent")

table.insert(data.categories, "Latin second conjugation verbs")

table.insert(data.categories, "Latin impersonal verbs")

table.insert(data.categories, "Latin semi-deponent verbs")

table.insert(data.categories, "Latin defective verbs")

local prefix = typeinfo.prefix or ""

--[[

-- not used

local ppplink = make_link({lang = lang, term = prefix .. "ausus"}, "term")

local sumlink = make_link({lang = lang, term = "sum"}, "term")

--]]

data.forms["3s_pres_actv_indc"] = prefix .. "piget"

data.forms["3s_impf_actv_indc"] = prefix .. "pigēbat"

data.forms["3s_futr_actv_indc"] = prefix .. "pigēbit"

data.forms["3s_perf_actv_indc"] = {prefix .. "piguit", "" .. prefix .. "pigitum est"}

data.forms["3s_plup_actv_indc"] = {prefix .. "piguerat", "" .. prefix .. "pigitum erat"}

data.forms["3s_futp_actv_indc"] = {prefix .. "piguerit", "" .. prefix .. "pigitum erit"}

data.forms["3s_pres_actv_subj"] = prefix .. "pigeat"

data.forms["3s_impf_actv_subj"] = prefix .. "pigēret"

data.forms["3s_perf_actv_subj"] = {prefix .. "piguerit", "" .. prefix .. "pigitum sit"}

data.forms["3s_plup_actv_subj"] = {prefix .. "piguisset", "" .. prefix .. "pigitum esset"}

data.forms["pres_actv_inf"] = prefix .. "pigēre"

data.forms["perf_actv_inf"] = "" .. prefix .. "pigitum esse"

data.forms["pres_actv_ptc"] = prefix .. "pigēns"

data.forms["perf_actv_ptc"] = prefix .. "pigitum"

-- Gerund

make_gerund(data, typeinfo, prefix .. "pigend")

end

irreg_conjugations["coepi"] = function(args, data, typeinfo)

table.insert(data.title, "third conjugation")

table.insert(data.categories, "Latin third conjugation verbs")

table.insert(data.categories, "Latin defective verbs")

local prefix = typeinfo.prefix or ""

make_perf(data, prefix .. "coep")

make_supine(data, typeinfo, prefix .. "coept")

make_perfect_passive(data)

end

-- The vowel of the prefix is lengthened if it ends in -n and the next word begins with f- or s-.

local function lengthen_prefix(prefix)

return prefix:gsub("([aeiou]n)$", {["an"] = "ān", ["en"] = "ēn", ["in"] = "īn", ["on"] = "ōn", ["un"] = "ūn"})

end

irreg_conjugations["sum"] = function(args, data, typeinfo)

table.insert(data.title, "highly irregular")

table.insert(data.title, "suppletive")

table.insert(data.categories, "Latin irregular verbs")

table.insert(data.categories, "Latin suppletive verbs")

local prefix = typeinfo.prefix or ""

local prefix_e = ine(args[3]) or prefix

local prefix_f = lengthen_prefix(ine(args[4]) or prefix)

local prefix_s = lengthen_prefix(prefix)

typeinfo.subtypes.nopass = true

typeinfo.subtypes.supfutractvonly = true

make_perf(data, prefix_f .. "fu")

make_supine(data, typeinfo, prefix_f .. "fut")

-- Active imperfective indicative

data.forms["1s_pres_actv_indc"] = prefix_s .. "sum"

data.forms["2s_pres_actv_indc"] = prefix_e .. "es"

data.forms["3s_pres_actv_indc"] = prefix_e .. "est"

data.forms["1p_pres_actv_indc"] = prefix_s .. "sumus"

data.forms["2p_pres_actv_indc"] = prefix_e .. "estis"

data.forms["3p_pres_actv_indc"] = prefix_s .. "sunt"

data.forms["1s_impf_actv_indc"] = prefix_e .. "eram"

data.forms["2s_impf_actv_indc"] = prefix_e .. "erās"

data.forms["3s_impf_actv_indc"] = prefix_e .. "erat"

data.forms["1p_impf_actv_indc"] = prefix_e .. "erāmus"

data.forms["2p_impf_actv_indc"] = prefix_e .. "erātis"

data.forms["3p_impf_actv_indc"] = prefix_e .. "erant"

data.forms["1s_futr_actv_indc"] = prefix_e .. "erō"

data.forms["2s_futr_actv_indc"] = {prefix_e .. "eris", prefix_e .. "ere"}

data.forms["3s_futr_actv_indc"] = prefix_e .. "erit"

data.forms["1p_futr_actv_indc"] = prefix_e .. "erimus"

data.forms["2p_futr_actv_indc"] = prefix_e .. "eritis"

data.forms["3p_futr_actv_indc"] = prefix_e .. "erunt"

-- Active imperfective subjunctive

data.forms["1s_pres_actv_subj"] = prefix_s .. "sim"

data.forms["2s_pres_actv_subj"] = prefix_s .. "sīs"

data.forms["3s_pres_actv_subj"] = prefix_s .. "sit"

data.forms["1p_pres_actv_subj"] = prefix_s .. "sīmus"

data.forms["2p_pres_actv_subj"] = prefix_s .. "sītis"

data.forms["3p_pres_actv_subj"] = prefix_s .. "sint"

data.forms["1s_impf_actv_subj"] = {prefix_e .. "essem", prefix_f .. "forem"}

data.forms["2s_impf_actv_subj"] = {prefix_e .. "essēs", prefix_f .. "forēs"}

data.forms["3s_impf_actv_subj"] = {prefix_e .. "esset", prefix_f .. "foret"}

data.forms["1p_impf_actv_subj"] = {prefix_e .. "essēmus", prefix_f .. "forēmus"}

data.forms["2p_impf_actv_subj"] = {prefix_e .. "essētis", prefix_f .. "forētis"}

data.forms["3p_impf_actv_subj"] = {prefix_e .. "essent", prefix_f .. "forent"}

-- Imperative

data.forms["2s_pres_actv_impr"] = prefix_e .. "es"

data.forms["2p_pres_actv_impr"] = prefix_e .. "este"

data.forms["2s_futr_actv_impr"] = prefix_e .. "estō"

data.forms["3s_futr_actv_impr"] = prefix_e .. "estō"

data.forms["2p_futr_actv_impr"] = prefix_e .. "estōte"

data.forms["3p_futr_actv_impr"] = prefix_s .. "suntō"

-- Present infinitives

data.forms["pres_actv_inf"] = prefix_e .. "esse"

-- Future infinitives

data.forms["futr_actv_inf"] = {"" .. prefix_f .. "futūrum esse", prefix_f .. "fore"}

-- Imperfective participles

if prefix == "ab" then

data.forms["pres_actv_ptc"] = "absēns"

elseif prefix == "prae" then

data.forms["pres_actv_ptc"] = "praesēns"

end

-- Gerund

data.forms["ger_gen"] = nil

data.forms["ger_dat"] = nil

data.forms["ger_acc"] = nil

data.forms["ger_abl"] = nil

-- Supine

data.forms["sup_acc"] = nil

data.forms["sup_abl"] = nil

end

-- Form-generating functions

make_pres_1st = function(data, typeinfo, pres_stem)

if not pres_stem then

return

end

-- Active imperfective indicative

add_forms(data, "pres_actv_indc", pres_stem, "ō", "ās", "at", "āmus", "ātis", "ant")

add_forms(data, "impf_actv_indc", pres_stem, "ābam", "ābās", "ābat", "ābāmus", "ābātis", "ābant")

add_forms(data, "futr_actv_indc", pres_stem, "ābō", "ābis", "ābit", "ābimus", "ābitis", "ābunt")

-- Passive imperfective indicative

add_forms(data, "pres_pasv_indc", pres_stem, "or", {"āris", "āre"}, "ātur", "āmur", "āminī", "antur")

add_forms(data, "impf_pasv_indc", pres_stem, "ābar", {"ābāris", "ābāre"}, "ābātur", "ābāmur", "ābāminī", "ābantur")

add_forms(data, "futr_pasv_indc", pres_stem, "ābor", {"āberis", "ābere"}, "ābitur", "ābimur", "ābiminī", "ābuntur")

-- Active imperfective subjunctive

add_forms(data, "pres_actv_subj", pres_stem, "em", "ēs", "et", "ēmus", "ētis", "ent")

add_forms(data, "impf_actv_subj", pres_stem, "ārem", "ārēs", "āret", "ārēmus", "ārētis", "ārent")

-- Passive imperfective subjunctive

add_forms(data, "pres_pasv_subj", pres_stem, "er", {"ēris", "ēre"}, "ētur", "ēmur", "ēminī", "entur")

add_forms(data, "impf_pasv_subj", pres_stem, "ārer", {"ārēris", "ārēre"}, "ārētur", "ārēmur", "ārēminī", "ārentur")

-- Imperative

add_2_forms(data, "pres_actv_impr", pres_stem, "ā", "āte")

add_23_forms(data, "futr_actv_impr", pres_stem, "ātō", "ātō", "ātōte", "antō")

add_2_forms(data, "pres_pasv_impr", pres_stem, "āre", "āminī")

add_23_forms(data, "futr_pasv_impr", pres_stem, "ātor", "ātor", {}, "antor")

-- Present infinitives

data.forms["pres_actv_inf"] = pres_stem .. "āre"

data.forms["pres_pasv_inf"] = pres_stem .. "ārī"

-- Imperfective participles

data.forms["pres_actv_ptc"] = pres_stem .. "āns"

-- Gerund

make_gerund(data, typeinfo, pres_stem .. "and")

end

make_pres_2nd = function(data, typeinfo, pres_stem, nopass, noimpr)

-- Active imperfective indicative

add_forms(data, "pres_actv_indc", pres_stem, "eō", "ēs", "et", "ēmus", "ētis", "ent")

add_forms(data, "impf_actv_indc", pres_stem, "ēbam", "ēbās", "ēbat", "ēbāmus", "ēbātis", "ēbant")

add_forms(data, "futr_actv_indc", pres_stem, "ēbō", "ēbis", "ēbit", "ēbimus", "ēbitis", "ēbunt")

-- Active imperfective subjunctive

add_forms(data, "pres_actv_subj", pres_stem, "eam", "eās", "eat", "eāmus", "eātis", "eant")

add_forms(data, "impf_actv_subj", pres_stem, "ērem", "ērēs", "ēret", "ērēmus", "ērētis", "ērent")

-- Active imperative

if not noimpr then

add_2_forms(data, "pres_actv_impr", pres_stem, "ē", "ēte")

add_23_forms(data, "futr_actv_impr", pres_stem, "ētō", "ētō", "ētōte", "entō")

end

if not nopass then

-- Passive imperfective indicative

add_forms(data, "pres_pasv_indc", pres_stem, "eor", {"ēris", "ēre"}, "ētur", "ēmur", "ēminī", "entur")

add_forms(data, "impf_pasv_indc", pres_stem, "ēbar", {"ēbāris", "ēbāre"}, "ēbātur", "ēbāmur", "ēbāminī", "ēbantur")

add_forms(data, "futr_pasv_indc", pres_stem, "ēbor", {"ēberis", "ēbere"}, "ēbitur", "ēbimur", "ēbiminī", "ēbuntur")

-- Passive imperfective subjunctive

add_forms(data, "pres_pasv_subj", pres_stem, "ear", {"eāris", "eāre"}, "eātur", "eāmur", "eāminī", "eantur")

add_forms(data, "impf_pasv_subj", pres_stem, "ērer", {"ērēris", "ērēre"}, "ērētur", "ērēmur", "ērēminī", "ērentur")

-- Passive imperative

if not noimpr then

add_2_forms(data, "pres_pasv_impr", pres_stem, "ēre", "ēminī")

add_23_forms(data, "futr_pasv_impr", pres_stem, "ētor", "ētor", {}, "entor")

end

end

-- Present infinitives

data.forms["pres_actv_inf"] = pres_stem .. "ēre"

if not nopass then

data.forms["pres_pasv_inf"] = pres_stem .. "ērī"

end

-- Imperfective participles

data.forms["pres_actv_ptc"] = pres_stem .. "ēns"

-- Gerund

make_gerund(data, typeinfo, pres_stem .. "end", nil, nil, nopass)

end

make_pres_3rd = function(data, typeinfo, pres_stem)

-- Active imperfective indicative

add_forms(data, "pres_actv_indc", pres_stem, "ō", "is", "it", "imus", "itis", "unt")

add_forms(data, "impf_actv_indc", pres_stem, "ēbam", "ēbās", "ēbat", "ēbāmus", "ēbātis", "ēbant")

add_forms(data, "futr_actv_indc", pres_stem, "am", "ēs", "et", "ēmus", "ētis", "ent")

-- Passive imperfective indicative

add_forms(data, "pres_pasv_indc", pres_stem, "or", {"eris", "ere"}, "itur", "imur", "iminī", "untur")

add_forms(data, "impf_pasv_indc", pres_stem, "ēbar", {"ēbāris", "ēbāre"}, "ēbātur", "ēbāmur", "ēbāminī", "ēbantur")

add_forms(data, "futr_pasv_indc", pres_stem, "ar", {"ēris", "ēre"}, "ētur", "ēmur", "ēminī", "entur")

-- Active imperfective subjunctive

add_forms(data, "pres_actv_subj", pres_stem, "am", "ās", "at", "āmus", "ātis", "ant")

add_forms(data, "impf_actv_subj", pres_stem, "erem", "erēs", "eret", "erēmus", "erētis", "erent")

-- Passive imperfective subjunctive

add_forms(data, "pres_pasv_subj", pres_stem, "ar", {"āris", "āre"}, "ātur", "āmur", "āminī", "antur")

add_forms(data, "impf_pasv_subj", pres_stem, "erer", {"erēris", "erēre"}, "erētur", "erēmur", "erēminī", "erentur")

-- Imperative

add_2_forms(data, "pres_actv_impr", pres_stem, "e", "ite")

add_23_forms(data, "futr_actv_impr", pres_stem, "itō", "itō", "itōte", "untō")

add_2_forms(data, "pres_pasv_impr", pres_stem, "ere", "iminī")

add_23_forms(data, "futr_pasv_impr", pres_stem, "itor", "itor", {}, "untor")

-- Present infinitives

data.forms["pres_actv_inf"] = pres_stem .. "ere"

data.forms["pres_pasv_inf"] = pres_stem .. "ī"

-- Imperfective participles

data.forms["pres_actv_ptc"] = pres_stem .. "ēns"

-- Gerund

make_gerund(data, typeinfo, pres_stem .. "end", "und-variant")

end

make_pres_3rd_io = function(data, typeinfo, pres_stem, nopass)

-- Active imperfective indicative

add_forms(data, "pres_actv_indc", pres_stem, "iō", "is", "it", "imus", "itis", "iunt")

add_forms(data, "impf_actv_indc", pres_stem, "iēbam", "iēbās", "iēbat", "iēbāmus", "iēbātis", "iēbant")

add_forms(data, "futr_actv_indc", pres_stem, "iam", "iēs", "iet", "iēmus", "iētis", "ient")

-- Active imperfective subjunctive

add_forms(data, "pres_actv_subj", pres_stem, "iam", "iās", "iat", "iāmus", "iātis", "iant")

add_forms(data, "impf_actv_subj", pres_stem, "erem", "erēs", "eret", "erēmus", "erētis", "erent")

-- Active imperative

add_2_forms(data, "pres_actv_impr", pres_stem, "e", "ite")

add_23_forms(data, "futr_actv_impr", pres_stem, "itō", "itō", "itōte", "iuntō")

-- Passive imperfective indicative

if not nopass then

add_forms(data, "pres_pasv_indc", pres_stem, "ior", {"eris", "ere"}, "itur", "imur", "iminī", "iuntur")

add_forms(data, "impf_pasv_indc", pres_stem, "iēbar", {"iēbāris", "iēbāre"}, "iēbātur", "iēbāmur", "iēbāminī", "iēbantur")

add_forms(data, "futr_pasv_indc", pres_stem, "iar", {"iēris", "iēre"}, "iētur", "iēmur", "iēminī", "ientur")

-- Passive imperfective subjunctive

add_forms(data, "pres_pasv_subj", pres_stem, "iar", {"iāris", "iāre"}, "iātur", "iāmur", "iāminī", "iantur")

add_forms(data, "impf_pasv_subj", pres_stem, "erer", {"erēris", "erēre"}, "erētur", "erēmur", "erēminī", "erentur")

-- Passive imperative

add_2_forms(data, "pres_pasv_impr", pres_stem, "ere", "iminī")

add_23_forms(data, "futr_pasv_impr", pres_stem, "itor", "itor", {}, "iuntor")

end

-- Present infinitives

data.forms["pres_actv_inf"] = pres_stem .. "ere"

if not nopass then

data.forms["pres_pasv_inf"] = pres_stem .. "ī"

end

-- Imperfective participles

data.forms["pres_actv_ptc"] = pres_stem .. "iēns"

-- Gerund

make_gerund(data, typeinfo, pres_stem .. "iend", "und-variant", nil, nopass)

end

make_pres_4th = function(data, typeinfo, pres_stem)

-- Active imperfective indicative

add_forms(data, "pres_actv_indc", pres_stem, "iō", "īs", "it", "īmus", "ītis", "iunt")

add_forms(data, "impf_actv_indc", pres_stem, "iēbam", "iēbās", "iēbat", "iēbāmus", "iēbātis", "iēbant")

add_forms(data, "futr_actv_indc", pres_stem, "iam", "iēs", "iet", "iēmus", "iētis", "ient")

-- Passive imperfective indicative

add_forms(data, "pres_pasv_indc", pres_stem, "ior", {"īris", "īre"}, "ītur", "īmur", "īminī", "iuntur")

add_forms(data, "impf_pasv_indc", pres_stem, "iēbar", {"iēbāris", "iēbāre"}, "iēbātur", "iēbāmur", "iēbāminī", "iēbantur")

add_forms(data, "futr_pasv_indc", pres_stem, "iar", {"iēris", "iēre"}, "iētur", "iēmur", "iēminī", "ientur")

-- Active imperfective subjunctive

add_forms(data, "pres_actv_subj", pres_stem, "iam", "iās", "iat", "iāmus", "iātis", "iant")

add_forms(data, "impf_actv_subj", pres_stem, "īrem", "īrēs", "īret", "īrēmus", "īrētis", "īrent")

-- Passive imperfective subjunctive

add_forms(data, "pres_pasv_subj", pres_stem, "iar", {"iāris", "iāre"}, "iātur", "iāmur", "iāminī", "iantur")

add_forms(data, "impf_pasv_subj", pres_stem, "īrer", {"īrēris", "īrēre"}, "īrētur", "īrēmur", "īrēminī", "īrentur")

-- Imperative

add_2_forms(data, "pres_actv_impr", pres_stem, "ī", "īte")

add_23_forms(data, "futr_actv_impr", pres_stem, "ītō", "ītō", "ītōte", "iuntō")

add_2_forms(data, "pres_pasv_impr", pres_stem, "īre", "īminī")

add_23_forms(data, "futr_pasv_impr", pres_stem, "ītor", "ītor", {}, "iuntor")

-- Present infinitives

data.forms["pres_actv_inf"] = pres_stem .. "īre"

data.forms["pres_pasv_inf"] = pres_stem .. "īrī"

-- Imperfective participles

data.forms["pres_actv_ptc"] = pres_stem .. "iēns"

-- Gerund

make_gerund(data, typeinfo, pres_stem .. "iend", "und-variant")

end

make_perf_and_supine = function(data, typeinfo)

if typeinfo.subtypes.optsemidepon then

make_perf(data, typeinfo.perf_stem, "noinf")

make_deponent_perf(data, typeinfo.supine_stem)

else

make_perf(data, typeinfo.perf_stem)

make_supine(data, typeinfo, typeinfo.supine_stem)

end

end

make_perf = function(data, perf_stem, no_inf)

if not perf_stem then

return

end

if type(perf_stem) ~= "table" then

perf_stem = {perf_stem}

end

for _, stem in ipairs(perf_stem) do

-- Perfective indicative

add_forms(data, "perf_actv_indc", stem, "ī", "istī", "it", "imus", "istis", {"ērunt", "ēre"})

add_forms(data, "plup_actv_indc", stem, "eram", "erās", "erat", "erāmus", "erātis", "erant")

add_forms(data, "futp_actv_indc", stem, "erō", "eris", "erit", "erimus", "eritis", "erint")

-- Perfective subjunctive

add_forms(data, "perf_actv_subj", stem, "erim", "erīs", "erit", "erīmus", "erītis", "erint")

add_forms(data, "plup_actv_subj", stem, "issem", "issēs", "isset", "issēmus", "issētis", "issent")

-- Perfect infinitive

if not no_inf then

add_form(data, "perf_actv_inf", stem, "isse")

end

end

end

make_deponent_perf = function(data, supine_stem)

if not supine_stem then

return

end

if type(supine_stem) ~= "table" then

supine_stem = {supine_stem}

end

-- Perfect/future infinitives

for _, stem in ipairs(supine_stem) do

local stems = "" .. stem .. "us "

local stemp = "" .. stem .. "ī "

add_forms(data, "perf_actv_indc", stems, "sum", "es", "est", {}, {}, {})

add_forms(data, "perf_actv_indc", stemp, {}, {}, {}, "sumus", "estis", "sunt")

add_forms(data, "plup_actv_indc", stems, "eram", "erās", "erat", {}, {}, {})

add_forms(data, "plup_actv_indc", stemp, {}, {}, {}, "erāmus", "erātis", "erant")

add_forms(data, "futp_actv_indc", stems, "erō", "eris", "erit", {}, {}, {})

add_forms(data, "futp_actv_indc", stemp, {}, {}, {}, "erimus", "eritis", "erint")

add_forms(data, "perf_actv_subj", stems, "sim", "sīs", "sit", {}, {}, {})

add_forms(data, "perf_actv_subj", stemp, {}, {}, {}, "sīmus", "sītis", "sint")

add_forms(data, "plup_actv_subj", stems, "essem", "essēs", "esset", {}, {}, {})

add_forms(data, "plup_actv_subj", stemp, {}, {}, {}, "essēmus", "essētis", "essent")

add_form(data, "perf_actv_inf", "", "" .. stem .. "um esse")

add_form(data, "futr_actv_inf", "", "" .. stem .. "ūrum esse")

add_form(data, "perf_actv_ptc", stem, "us")

add_form(data, "futr_actv_ptc", stem, "ūrus")

-- Supine

add_form(data, "sup_acc", stem, "um")

add_form(data, "sup_abl", stem, "ū")

end

end

make_supine = function(data, typeinfo, supine_stem)

if not supine_stem then

return

end

if type(supine_stem) ~= "table" then

supine_stem = {supine_stem}

end

-- Perfect/future infinitives

for _, stem in ipairs(supine_stem) do

local futr_actv_inf, perf_pasv_inf, futr_pasv_inf, futr_actv_ptc

local perf_pasv_ptc_lemma, perf_actv_ptc, perf_actv_ptc_acc

-- Perfect/future participles

futr_actv_ptc = stem .. "ūrus"

if typeinfo.subtypes.passimpers then

perf_pasv_ptc_lemma = stem .. "um"

perf_pasv_ptc = perf_pasv_ptc_lemma

perf_pasv_ptc_acc = perf_pasv_ptc_lemma

else

perf_pasv_ptc_lemma = stem .. "us"

if typeinfo.subtypes.mp then

perf_pasv_ptc = stem .. "ī"

perf_pasv_ptc_acc = stem .. "ōs"

elseif typeinfo.subtypes.fp then

perf_pasv_ptc = stem .. "ae"

perf_pasv_ptc_acc = stem .. "ās"

elseif typeinfo.subtypes.np then

perf_pasv_ptc = stem .. "a"

perf_pasv_ptc_acc = perf_pasv_ptc

elseif typeinfo.subtypes.f then

perf_pasv_ptc = stem .. "a"

perf_pasv_ptc_acc = stem .. "am"

elseif typeinfo.subtypes.n then

perf_pasv_ptc = stem .. "um"

perf_pasv_ptc_acc = perf_pasv_ptc

else

perf_pasv_ptc = perf_pasv_ptc_lemma

perf_pasv_ptc_acc = stem .. "um"

end

end

perf_pasv_inf = make_raw_link(perf_pasv_ptc_lemma,

perf_pasv_ptc_acc ~= perf_pasv_ptc_lemma and perf_pasv_ptc_acc or nil) .. " esse"

futr_pasv_inf = make_raw_link(stem .. "um") .. " īrī"

-- Exceptions

local mortu = {

["conmortu"] = true,

["commortu"] = true,

["dēmortu"] = true,

["ēmortu"] = true,

["inmortu"] = true,

["immortu"] = true,

["inēmortu"] = true,

["intermortu"] = true,

["permortu"] = true,

["praemortu"] = true,

["superēmortu"] = true

}

local ort = {

["ort"] = true,

["abort"] = true,

["adort"] = true,

["coort"] = true,

["exort"] = true,

["hort"] = true,

["obort"] = true

}

if mortu[stem] then

futr_actv_ptc = stem:gsub("mortu$", "moritūrus")

elseif ort[stem] then

futr_actv_ptc = stem:gsub("ort$", "oritūrus")

elseif stem == "mortu" then

-- FIXME, are we sure about this?

futr_actv_inf = {}

futr_actv_ptc = "moritūrus"

end

if not futr_actv_inf then

futr_actv_inf = make_raw_link(futr_actv_ptc, futr_actv_ptc:gsub("us$", "um")) .. " esse"

end

add_form(data, "futr_actv_inf", "", futr_actv_inf)

add_form(data, "perf_pasv_inf", "", perf_pasv_inf)

add_form(data, "futr_pasv_inf", "", futr_pasv_inf)

add_form(data, "futr_actv_ptc", "", futr_actv_ptc)

add_form(data, "perf_pasv_ptc", "", perf_pasv_ptc)

-- Supine itself

add_form(data, "sup_acc", stem, "um")

add_form(data, "sup_abl", stem, "ū")

end

end

-- Functions for generating the inflection table

-- Convert FORM (one or more forms) to a string of links. If the form is empty

-- (see form_is_empty), the return value will be "—".

local function show_form(form, accel)

if not form then

return "—"

end

if type(form) ~= "table" then

form = {form}

end

for key, subform in ipairs(form) do

if form_is_empty(subform) then

form[key] = "—"

elseif reconstructed and not subform:find(NAMESPACE .. ":Latin/") then

form[key] = make_link({lang = lang, term = NAMESPACE .. ":Latin/" .. subform, alt = subform})

elseif subform:find("[%[%]]") then

-- Don't put accelerators on forms already containing links such as

-- the perfect passive infinitive and future active infinitive, or

-- the participles wrongly get tagged as infinitives as well as

-- participles.

form[key] = make_link({lang = lang, term = subform})

else

form[key] = make_link({lang = lang, term = subform, accel = accel})

end

end

return table.concat(form, ", ")

end

parts_to_tags = {

['1s'] = {'1', 's'},

['2s'] = {'2', 's'},

['3s'] = {'3', 's'},

['1p'] = {'1', 'p'},

['2p'] = {'2', 'p'},

['3p'] = {'3', 'p'},

['actv'] = {'act'},

['pasv'] = {'pass'},

['pres'] = {'pres'},

['impf'] = {'impf'},

['futr'] = {'fut'},

['perf'] = {'perf'},

['plup'] = {'plup'},

['futp'] = {'fut', 'perf'},

['indc'] = {'ind'},

['subj'] = {'sub'},

['impr'] = {'imp'},

['inf'] = {'inf'},

['ptc'] = {'part'},

['ger'] = {'ger'},

['sup'] = {'sup'},

['nom'] = {'nom'},

['gen'] = {'gen'},

['dat'] = {'dat'},

['acc'] = {'acc'},

['abl'] = {'abl'},

}

-- Call show_form() the forms in each non-generic slot (where a

-- generic slot is something like pres_actv_indc that covers a whole

-- row of slots), converting the forms to a string consisting of

-- comma-separated links with accelerators in them.

local function convert_forms_into_links(data)

local accel_lemma = data.actual_lemma[1]

for slot in iter_slots(false, false) do

local slot_parts = rsplit(slot, "_")

local tags = {}

for _, part in ipairs(slot_parts) do

for _, tag in ipairs(parts_to_tags[part]) do

table.insert(tags, tag)

end

end

local accel_slot = table.concat(tags, "|")

local accel = {form = accel_slot, lemma = accel_lemma}

data.forms[slot] = show_form(data.forms[slot], accel)

end

end

function export.get_valid_forms(raw_forms)

local valid_forms = {}

if raw_forms then

if type(raw_forms) ~= "table" then

raw_forms = {raw_forms}

end

for _, subform in ipairs(raw_forms) do

if not form_is_empty(subform) then

table.insert(valid_forms, subform)

end

end

end

return valid_forms

end

function export.get_lemma_forms(data, do_linked)

local linked_prefix = do_linked and "linked_" or ""

for _, slot in ipairs(potential_lemma_slots) do

local lemma_forms = export.get_valid_forms(data.forms[linked_prefix .. slot])

if #lemma_forms > 0 then

return lemma_forms

end

end

return nil

end

local function get_displayable_lemma(lemma_forms)

if not lemma_forms then

return "—"

end

local lemma_links = {}

for _, subform in ipairs(lemma_forms) do

table.insert(lemma_links, make_link({lang = lang, alt = subform}, "term"))

end

return table.concat(lemma_links, ", ")

end

-- Make the table

make_table = function(data)

local pagename = PAGENAME

if reconstructed then

pagename = pagename:gsub("Latin/","")

end

data.actual_lemma = export.get_lemma_forms(data)

convert_forms_into_links(data)

return [=[

style="width: 100%; background: #EEE; border: 1px solid #AAA; font-size: 95%; text-align: center;" class="inflection-table vsSwitcher" data-toggle-category="inflection"
colspan="8" class="vsToggleElement" style="background: #CCC; text-align: left;" |    Conjugation of ]=] .. get_displayable_lemma(data.actual_lemma) .. (#data.title > 0 and " (" .. table.concat(data.title, ", ") .. ")" or "") .. [=[

]=] .. make_indc_rows(data) .. make_subj_rows(data) .. make_impr_rows(data) .. make_nonfin_rows(data) .. make_vn_rows(data) .. [=[

]=].. make_footnotes(data)

end

local tenses = {

["pres"] = "present",

["impf"] = "imperfect",

["futr"] = "future",

["perf"] = "perfect",

["plup"] = "pluperfect",

["futp"] = "future perfect",

}

local voices = {

["actv"] = "active",

["pasv"] = "passive",

}

--[[

local moods = {

["indc"] = "indicative",

["subj"] = "subjunctive",

["impr"] = "imperative",

}

--]]

local nonfins = {

["inf"] = "infinitives",

["ptc"] = "participles",

}

--[[

local verbalnouns = {

["ger"] = "gerund",

["sup"] = "supine",

}

--]]

--[[

local cases = {

["nom"] = "nominative",

["gen"] = "genitive",

["dat"] = "dative",

["acc"] = "accusative",

["abl"] = "ablative",

}

--]]

make_indc_rows = function(data)

local indc = {}

for _, v in ipairs({"actv", "pasv"}) do

local group = {}

local nonempty = false

for _, t in ipairs({"pres", "impf", "futr", "perf", "plup", "futp"}) do

local row = {}

local notempty = false

if data.forms[t .. "_" .. v .. "_indc"] then

row = "\n! colspan=\"6\" style=\"background: #CCC\" |" .. data.forms[t .. "_" .. v .. "_indc"]

nonempty = true

notempty = true

else

for col, p in ipairs({"1s", "2s", "3s", "1p", "2p", "3p"}) do

local slot = p .. "_" .. t .. "_" .. v .. "_indc"

row[col] = "\n| " .. data.forms[slot] .. (

data.form_footnote_indices[slot] == nil and "" or

'' .. data.form_footnote_indices[slot]..""

)

-- show_form() already called so can just check for "—"

if data.forms[slot] ~= "—" then

nonempty = true

notempty = true

end

end

row = table.concat(row)

end

if notempty then

table.insert(group, "\n! style=\"background:#c0cfe4\" | " .. tenses[t] .. row)

end

end

if nonempty and #group > 0 then

table.insert(indc, "\n|- class=\"vsHide\"\n! rowspan=\"" .. tostring(#group) .. "\" style=\"background:#c0cfe4\" | " .. voices[v] .. "\n" .. table.concat(group, "\n|- class=\"vsHide\""))

end

end

return

[=[

|- class="vsHide"

! colspan="2" rowspan="2" style="background:#c0cfe4" | indicative

! colspan="3" style="background:#c0cfe4" | singular

! colspan="3" style="background:#c0cfe4" | plural

|- class="vsHide"

! style="background:#c0cfe4;width:12.5%" | first

! style="background:#c0cfe4;width:12.5%" | second

! style="background:#c0cfe4;width:12.5%" | third

! style="background:#c0cfe4;width:12.5%" | first

! style="background:#c0cfe4;width:12.5%" | second

! style="background:#c0cfe4;width:12.5%" | third

]=] .. table.concat(indc)

end

make_subj_rows = function(data)

local subj = {}

for _, v in ipairs({"actv", "pasv"}) do

local group = {}

local nonempty = false

for _, t in ipairs({"pres", "impf", "perf", "plup"}) do

local row = {}

local notempty = false

if data.forms[t .. "_" .. v .. "_subj"] then

row = "\n! colspan=\"6\" style=\"background: #CCC\" |" .. data.forms[t .. "_" .. v .. "_subj"]

nonempty = true

notempty = true

else

for col, p in ipairs({"1s", "2s", "3s", "1p", "2p", "3p"}) do

local slot = p .. "_" .. t .. "_" .. v .. "_subj"

row[col] = "\n| " .. data.forms[slot] .. (

data.form_footnote_indices[slot] == nil and "" or

'' .. data.form_footnote_indices[slot]..""

)

-- show_form() already called so can just check for "—"

if data.forms[slot] ~= "—" then

nonempty = true

notempty = true

end

end

row = table.concat(row)

end

if notempty then

table.insert(group, "\n! style=\"background:#c0e4c0\" | " .. tenses[t] .. row)

end

end

if nonempty and #group > 0 then

table.insert(subj, "\n|- class=\"vsHide\"\n! rowspan=\"" .. tostring(#group) .. "\" style=\"background:#c0e4c0\" | " .. voices[v] .. "\n" .. table.concat(group, "\n|- class=\"vsHide\""))

end

end

return

[=[

|- class="vsHide"

! colspan="2" rowspan="2" style="background:#c0e4c0" | subjunctive

! colspan="3" style="background:#c0e4c0" | singular

! colspan="3" style="background:#c0e4c0" | plural

|- class="vsHide"

! style="background:#c0e4c0;width:12.5%" | first

! style="background:#c0e4c0;width:12.5%" | second

! style="background:#c0e4c0;width:12.5%" | third

! style="background:#c0e4c0;width:12.5%" | first

! style="background:#c0e4c0;width:12.5%" | second

! style="background:#c0e4c0;width:12.5%" | third

]=] .. table.concat(subj)

end

make_impr_rows = function(data)

local impr = {}

local has_impr = false

for _, v in ipairs({"actv", "pasv"}) do

local group = {}

local nonempty = false

for _, t in ipairs({"pres", "futr"}) do

local row = {}

if data.forms[t .. "_" .. v .. "_impr"] then

row = "\n! colspan=\"6\" style=\"background: #CCC\" |" .. data.forms[t .. "_" .. v .. "_impr"]

nonempty = true

else

for col, p in ipairs({"1s", "2s", "3s", "1p", "2p", "3p"}) do

local slot = p .. "_" .. t .. "_" .. v .. "_impr"

row[col] = "\n| " .. data.forms[slot]

-- show_form() already called so can just check for "—"

if data.forms[slot] ~= "—" then

nonempty = true

end

end

row = table.concat(row)

end

table.insert(group, "\n! style=\"background:#e4d4c0\" | " .. tenses[t] .. row)

end

if nonempty and #group > 0 then

has_impr = true

table.insert(impr, "\n|- class=\"vsHide\"\n! rowspan=\"" .. tostring(#group) .. "\" style=\"background:#e4d4c0\" | " .. voices[v] .. "\n" .. table.concat(group, "\n|- class=\"vsHide\""))

end

end

if not has_impr then

return ""

end

return

[=[

|- class="vsHide"

! colspan="2" rowspan="2" style="background:#e4d4c0" | imperative

! colspan="3" style="background:#e4d4c0" | singular

! colspan="3" style="background:#e4d4c0" | plural

|- class="vsHide"

! style="background:#e4d4c0;width:12.5%" | first

! style="background:#e4d4c0;width:12.5%" | second

! style="background:#e4d4c0;width:12.5%" | third

! style="background:#e4d4c0;width:12.5%" | first

! style="background:#e4d4c0;width:12.5%" | second

! style="background:#e4d4c0;width:12.5%" | third

]=] .. table.concat(impr)

end

make_nonfin_rows = function(data)

local nonfin = {}

for _, f in ipairs({"inf", "ptc"}) do

local row = {}

for col, t in ipairs({"pres_actv", "perf_actv", "futr_actv", "pres_pasv", "perf_pasv", "futr_pasv"}) do

local slot = t .. "_" .. f

--row[col] = "\n| " .. data.forms[slot]

row[col] = "\n| " .. data.forms[slot] .. (

data.form_footnote_indices[slot] == nil and "" or

'' .. data.form_footnote_indices[slot] ..""

)

end

row = table.concat(row)

table.insert(nonfin, "\n|- class=\"vsHide\"\n! style=\"background:#e2e4c0\" colspan=\"2\" | " .. nonfins[f] .. row)

end

return

[=[

|- class="vsHide"

! colspan="2" rowspan="2" style="background:#e2e4c0" | non-finite forms

! colspan="3" style="background:#e2e4c0" | active

! colspan="3" style="background:#e2e4c0" | passive

|- class="vsHide"

! style="background:#e2e4c0;width:12.5%" | present

! style="background:#e2e4c0;width:12.5%" | perfect

! style="background:#e2e4c0;width:12.5%" | future

! style="background:#e2e4c0;width:12.5%" | present

! style="background:#e2e4c0;width:12.5%" | perfect

! style="background:#e2e4c0;width:12.5%" | future

]=] .. table.concat(nonfin)

end

make_vn_rows = function(data)

local vn = {}

local has_vn = false

local row = {}

for col, slot in ipairs({"ger_gen", "ger_dat", "ger_acc", "ger_abl", "sup_acc", "sup_abl"}) do

-- show_form() already called so can just check for "—"

if data.forms[slot] ~= "—" then

has_vn = true

end

row[col] = "\n| " .. data.forms[slot] .. (

data.form_footnote_indices[slot] == nil and "" or

'' .. data.form_footnote_indices[slot] .. ""

)

end

row = table.concat(row)

if has_vn then

table.insert(vn, "\n|- class=\"vsHide\"" .. row)

end

if not has_vn then

return ""

end

return

[=[

|- class="vsHide"

! colspan="2" rowspan="3" style="background:#e0e0b0" | verbal nouns

! colspan="4" style="background:#e0e0b0" | gerund

! colspan="2" style="background:#e0e0b0" | supine

|- class="vsHide"

! style="background:#e0e0b0;width:12.5%" | genitive

! style="background:#e0e0b0;width:12.5%" | dative

! style="background:#e0e0b0;width:12.5%" | accusative

! style="background:#e0e0b0;width:12.5%" | ablative

! style="background:#e0e0b0;width:12.5%" | accusative

! style="background:#e0e0b0;width:12.5%" | ablative]=] .. table.concat(vn)

end

make_footnotes = function(data)

local tbl = {}

local i = 0

for k,v in pairs(data.footnotes) do

i = i + 1

tbl[i] = ''..tostring(k)..''..v..'
' end

return table.concat(tbl)

end

override = function(data, args)

for slot in iter_slots(true, false) do

if args[slot] then

data.forms[slot] = mw.text.split(args[slot], "/")

end

end

end

checkexist = function(data)

if NAMESPACE ~= '' then return end

local outerbreak = false

for _, conjugation in pairs(data.forms) do

if conjugation then

if type(conjugation) == 'string' then

conjugation = {conjugation}

end

for _, conj in ipairs(conjugation) do

if not cfind(conj, " ") then

local title = lang:makeEntryName(conj)

local t = mw.title.new(title)

if t and not t.exists then

table.insert(data.categories, 'Latin verbs with red links in their conjugation tables')

outerbreak = true

break

end

end

end

end

if outerbreak then

break

end

end

end

checkirregular = function(args,data)

local apocopic = mw.ustring.sub(args[1],1,-2)

apocopic = mw.ustring.gsub(apocopic,'[^aeiouyāēīōūȳ]+$','')

if args[1] and args[2] and not mw.ustring.find(args[2],'^'..apocopic) then

table.insert(data.categories,'Latin stem-changing verbs')

end

end

-- functions for creating external search hyperlinks

flatten_values = function(T)

function noaccents(x)

return mw.ustring.gsub(mw.ustring.toNFD(x),'[^%w]+',"")

end

function cleanup(x)

return noaccents(string.gsub(string.gsub(string.gsub(x, '%[', ), '%]', ), ' ', '+'))

end

local tbl = {}

for _, v in pairs(T) do

if type(v) == "table" then

local FT = flatten_values(v)

for _, V in pairs(FT) do

tbl[#tbl+1] = cleanup(V)

end

else

if string.find(v, '<') == nil then

tbl[#tbl+1] = cleanup(v)

end

end

end

return tbl

end

link_google_books = function(verb, forms, domain)

function partition_XS_into_N(XS, N)

local count = 0

local mensae = {}

for _, v in pairs(XS) do

if count % N == 0 then mensae[#mensae+1] = {} end

count = count + 1

mensae[#mensae][#(mensae[#mensae])+1] = v end

return mensae end

function forms_N_to_link(fs, N, args, site)

return '[https://www.google.com/search?'..args..'&q='..site..'+%22'.. table.concat(fs, "%22+OR+%22") ..'%22 '..N..']' end

function make_links_txt(fs, N, site)

local args = site == "Books" and "tbm=bks&lr=lang_la" or ""

local links = {}

for k,v in pairs(partition_XS_into_N(fs, N)) do

links[#links+1] = forms_N_to_link(v,k,args,site=="Books" and "" or site) end

return table.concat(links, ' - ') end

return "Google "..domain.." forms of "..verb.." : "..make_links_txt(forms, 30, domain)

end

return export

-- For Vim, so we get 4-space tabs

-- vim: set ts=4 sw=4 noet: