Module:he-verb-ng

--[=[

TODO: - Implement support for hollow roots in nif`al. - Implement support for geminate roots in pa`al, nif`al, hif`il, and huf`al. - Implement smarter ktiv male spellings. - Implement support for mixed binyanim (such as for ניגש and יכול). - Implement support for alternative forms.

Reference:

Input parameters: 1: binyan abbreviation p: first root letter a: second root letter l: third root letter

Root letters may be prefixed with ':' to include them literally, in which case they will not be   parsed as hollow or weak and no dageshes will be added to or removed from them. Any of the final form codes or intermediate data below can also be given explicitly in the input.

Binyan abbreviations: pa: pa`al pi: pi`el po: po`el/polel pu: pu`al poal: po`al/polal hif: hif`il huf: huf`al nif: nif`al hit: hitpa`el hitpo: hitpo`el/hitpolel hitpu: hitpu`al *rare modern coinage

Tense abbreviations: inf: to-infinitive imp: imperative fut: future (a.k.a. imperfect or prefix conjugation) pres: present (a.k.a. active participle) past: past (a.k.a. perfect or suffix conjugation) noun: action noun pp: passive participle

Gender abbreviations: s: singular *first person only p: plural *first person only ms: masculine singular fs: feminine singular mp: masculine plural fp: feminine plural

Person abbreviations: 1: first person 2: second person 3: third person

Exhaustive list of final form codes:

inf noun *optional pp *optional

imp_ms imp_fs imp_mp imp_fp *obsolete

fut_1s fut_2ms *always equal to fut_3fs fut_2fs fut_3ms fut_3fs *always equal to fut_2ms fut_1p fut_2mp fut_2fp *obsolete and always equal to fut_3fp fut_3mp fut_3fp *obsolete and always equal to fut_2fp

past_1s past_2ms past_2fs past_3ms past_3fs past_1p past_2mp past_2fp past_3mp past_3fp *obsolete before Biblical Hebrew, therefore equal to past_3mp

pres_ms pres_fs pres_mp pres_fp

Intermediate data:

root_p root_a root_l

gem *whether to treat as geminate

imp_pre_stem imp_prs_stem imp_mid_stem imp_fin_stem imp_suf_stem imp_ffp_stem

fut_gem fut_char *characteristic vowel [a,i,u], pa`al only (default: u)       fut_pre_stem fut_prs_stem fut_1sp_stem fut_mid_stem fut_fin_stem fut_suf_stem fut_ffp_stem

pres_gem pres_short *if not empty, use the pa`el-present, pa`al only pres_stem

past_gem past_char *characteristic vowel [a,i,u], pa`al only (default: a)       past_pre_stem past_2p_pre_stem past_stem past_3_stem past_3ms_stem past_3fs_stem past_2p_stem

]=]

local m_utilities = require("Module:utilities") local m_links = require("Module:links") local m_strutils = require("Module:string utilities")

local export = {} local get_stems_for = {}

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

local convert_root_char = { ["א"] = "א", ["ב"] = "ב", ["בּ"] = "בּ", -- always hard ["בֿ"] = "בֿ", -- always soft ["ג"] = "ג", ["גּ"] = "גּ", -- always hard ["גֿ"] = "גֿ", -- always soft ["ד"] = "ד", ["דּ"] = "דּ", -- always hard ["דֿ"] = "דֿ", -- always soft ["ה"] = "ה", ["ו"] = "ו", ["ז"] = "ז", ["ח"] = "ח", ["ט"] = "ט", ["י"] = "י", ["כ"] = "כ", ["כּ"] = "כּ", -- always hard ["כֿ"] = "כֿ", -- always soft ["ל"] = "ל", ["מ"] = "מ", ["נ"] = "נ", ["ס"] = "ס", ["ע"] = "ע", ["פ"] = "פ", ["פּ"] = "פּ", -- always hard ["פֿ"] = "פֿ", -- always soft ["צ"] = "צ", ["ק"] = "ק", ["ר"] = "ר", ["ש"] = "שׁ", -- assume shin ["שׁ"] = "שׁ", -- shin ["שׂ"] = "שׂ", -- sin ["ת"] = "ת", ["תּ"] = "תּ", -- always hard ["תֿ"] = "תֿ", -- always soft }

local convert_final_root_char = { ["ה"] = "י", -- make defective ["הּ"] = "ה", -- remove mappiq ["ו"] = "י", -- make defective ["ך"] = "כ", -- normalize final ["ךּ"] = "כּ", -- always hard, normalize final ["ךֿ"] = "כֿ", -- always soft, normalize final ["ם"] = "מ", -- normalize final ["ן"] = "נ", -- normalize final ["ף"] = "פ", -- normalize final ["ףּ"] = "פּ", -- always hard, normalize final ["ףֿ"] = "פֿ", -- always soft, normalize final ["ץ"] = "צ", -- normalize final }

local forms_itp = { ["שׁ"] = "שְׁתּ", ["שׂ"] = "שְׂתּ", ["ס"] = "סְתּ", ["ז"] = "זְדּ", ["צ"] = "צְט", ["ת"] = {"ית", "תּ"}, ["ד"] = {"יד", "דּ"}, ["ט"] = {"יט", "טּ"}, }

local forms_etp = { ["ת"] = "תּ", ["ד"] = "דּ", ["ט"] = "טּ", }

local forms = { ["בֿ"] = "ב", ["גֿ"] = "ג", ["דֿ"] = "ד", ["כֿ"] = "כ", ["פֿ"] = "פ", ["תֿ"] = "ת", }

local forms_initial = { ["ב"] = "בּ", ["ג"] = "גּ", ["ד"] = "דּ", ["כ"] = "כּ", ["פ"] = "פּ", ["ת"] = "תּ", }

local non_doubling_letters = { ["א"] = 1, ["ה"] = 2, ["ח"] = 3, ["ע"] = 2, ["ר"] = 1, }

local forms_final_furtive = { ["ה"] = "הַּ", ["ח"] = "חַ", ["ע"] = "עַ", }

local forms_final = { ["ה"] = "הּ", ["כ"] = "ךְ", ["כּ"] = "ךְּ", ["כֿ"] = "ךְ", ["מ"] = "ם", ["נ"] = "ן", ["פ"] = "ף", ["פֿ"] = "ף", ["צ"] = "ץ", }

local short_gem_vowel = { ["a"] = "ַ", ["i"] = {"י", "ִ"}, ["u"] = {"ו", "ֻ"}, ["e"] = "ֶ", ["o"] = {"ו", "ָ"}, }

local lengthened_gem_vowel = { ["a"] = "ָ", ["i"] = {"י", "ֵ"}, ["u"] = {"ו", "ֹ"}, ["e"] = {"י", "ֵ"}, ["o"] = {"ו", "ֹ"}, }

local mixed_gem_vowel = { ["a"] = "ַ", ["i"] = {"י", "ִ"}, ["u"] = {"ו", "ֹ"}, ["e"] = "ֶ", ["o"] = {"ו", "ֹ"}, }

local stressed_gem_vowel = { ["a"] = "ַ", ["i"] = "ֵ", ["u"] = {"ו", "ֹ"}, ["e"] = "ֵ", ["o"] = {"ו", "ֹ"}, }

local doubling_type = { [1] = lengthened_gem_vowel, [2] = mixed_gem_vowel, [3] = short_gem_vowel, }

local gutturals = { ["א"] = true, ["ה"] = true, ["ח"] = true, ["ע"] = true, }

local char_vowel = { ["a"] = "ַ", ["i"] = "ֵ", ["u"] = {"ו", "ֹ"}, ["A"] = "ָ", ["I"] = "ִי", ["U"] = "וּ", ["E"] = "ֵ", ["O"] = "וֹ", }

local char_vowel_open = { ["a"] = "ָ", ["i"] = "ֵ", ["u"] = {"ו", "ֹ"}, ["A"] = "ָ", ["I"] = "ִי", ["U"] = "וּ", ["E"] = "ֵ", ["O"] = "וֹ", }

local char_vowel_short = { ["a"] = "ַ", ["i"] = "ֵ", ["u"] = {"ו", "ֹ"}, ["A"] = "ַ", ["I"] = "ֵ", ["U"] = {"ו", "ֹ"}, ["E"] = "ֵ", ["O"] = {"ו", "ֹ"}, }

local char_vowel_open_short = { ["a"] = "ָ", ["i"] = "ֵ", ["u"] = {"ו", "ֹ"}, ["A"] = "ָ", ["I"] = "ֵ", ["U"] = {"ו", "ֹ"}, ["E"] = "ֵ", ["O"] = {"ו", "ֹ"}, }

local char_vowel_closed = { ["a"] = "ַ", ["i"] = "ַ", ["u"] = {"ו", "ֹ"}, ["A"] = "ַ", ["I"] = "ַ", ["U"] = {"ו", "ֹ"}, ["E"] = "ַ", ["O"] = {"ו", "ֹ"}, }

local char_vowel_unstressed = { ["a"] = "ַ", ["i"] = "ַ", ["u"] = {"ו", "ָ"}, ["A"] = "ַ", ["I"] = "ַ", ["U"] = {"ו", "ָ"}, ["E"] = "ַ", ["O"] = {"ו", "ָ"}, }

local char_vowel_open_fp = { ["a"] = "ֶ", ["i"] = "ֶ", ["u"] = {"ו", "ֹ"}, ["A"] = "ֶ", ["I"] = "ֶ", ["U"] = {"ו", "ֹ"}, ["E"] = "ֶ", ["O"] = {"ו", "ֹ"}, }

local char_vowel_reduce = { ["a"] = nil, ["i"] = nil, ["u"] = nil, ["A"] = "ָ", ["I"] = "ִי", ["U"] = "וּ", ["E"] = "ֵ", ["O"] = "וֹ", }

local chataf_vowel = { ["a"] = "ֲ", ["i"] = "ֱ", ["u"] = {"ו", "ֳ"}, }

local monophthongize = { ["י"] = "ֵי", ["ו"] = "וֹ", }

local function gen_link(x) if type(x) == "table" then local pg = (lang:makeEntryName(x[1])) if pg == (lang:makeEntryName(x[2])) then return m_links.full_link({lang = lang, term = pg, alt = x[2]}) else return m_links.full_link({lang = lang, term = pg, alt = pg .. " / " .. x[2]}) end else if x == "-" then return "—" -- m-dash else return m_links.full_link({lang = lang, term = x}) end end end

local function process_args(args) for key, value in pairs(args) do       local i = mw.ustring.find(value, "[\\/]") if i then args[key] = {mw.ustring.sub(value, 1, i - 1), mw.ustring.sub(value, i + 1)} end end end

local function append_parts_2(a, b)   if type(a) == "table" then if type(b) == "table" then return {a[1] .. b[1], a[2] .. b[2]} else return {a[1] .. (lang:makeEntryName(b)), a[2] .. b}       end else if type(b) == "table" then return {(lang:makeEntryName(a)) .. b[1], a .. b[2]} else return a .. b       end end end

local function append_parts(a, ...) for _, b in ipairs({...}) do       a = append_parts_2(a, b)    end return a end

local function equal(a, b)   if type(a) == "table" then return type(b) == "table" and a[1] == b[1] and a[2] == b[2] else return a == b   end end

local function attach_t(x, novowel, assim_t) local is_table = (type(x) == "table") local wv = is_table and x[2] or x   if mw.ustring.sub(wv, -2) == "תְ" then if is_table then return {x[1] .. "ת", mw.ustring.sub(wv, 1, -2) .. (novowel and "ְּ" or "ּ")} else return append_parts(mw.ustring.sub(wv, 1, -2), {"ת", (novowel and "ְּ" or "ּ")}) end elseif assim_t and mw.ustring.sub(wv, -2) == "נְ" and (not is_table or mw.ustring.sub(x[1], -1) == "נ") then if is_table then return {mw.ustring.sub(x[1], 1, -2) .. "ת", mw.ustring.sub(wv, 1, -3) .. (novowel and "תְּ" or "תּ")} else return mw.ustring.sub(wv, 1, -3) .. (novowel and "תְּ" or "תּ") end else local dagesh = (mw.ustring.sub(wv, -1) == "ְ") return append_parts(x, dagesh and (novowel and "תְּ" or "תּ") or "ת") end end

local function attach_n(x) local is_table = (type(x) == "table") local wv = is_table and x[2] or x   if mw.ustring.sub(wv, -2) == "נְ" then if is_table then return {x[1], mw.ustring.sub(wv, 1, -2) .. "ּ"}       else return mw.ustring.sub(wv, 1, -2) .. "ּ"       end else return append_parts(x, "נ") end end

local function get_form_initial(letter) if type(letter) == "table" then return letter elseif mw.ustring.sub(letter, 1, 1) == ":" then return mw.ustring.sub(letter, 2) else return forms_initial[letter] or forms[letter] or letter end end

local function get_form_itp(letter) return forms_itp[letter] or append_parts("תְ", get_form_initial(letter)) end

local function get_form_etp(letter) return forms_etp[letter] or forms_itp[letter] or append_parts("תְ", get_form_initial(letter)) end

local function get_form_medial(letter) if type(letter) == "table" then return letter elseif mw.ustring.sub(letter, 1, 1) == ":" then return mw.ustring.sub(letter, 2) else return forms[letter] or letter end end

local dagesh_or_rafe = {["ּ"] = true, ["ֿ"] = true} local function add_dagesh(letter) if type(letter) == "table" then return letter elseif mw.ustring.sub(letter, 1, 1) == ":" then return get_form_medial(letter) elseif non_doubling_letters[letter] or dagesh_or_rafe[mw.ustring.sub(letter, -1)] then return get_form_medial(letter) else -- TODO: Handle geresh return get_form_medial(letter) .. "ּ"   end end

local function get_form_double(letter, vowel, force_lengthening, stressed) local lengthen = non_doubling_letters[letter] if force_lengthening then lengthen = lengthen and 1 end if stressed then vowel = vowel and (lengthen and vowel == "a" and "ָ" or stressed_gem_vowel[vowel]) or "" else vowel = vowel and (lengthen and doubling_type[lengthen][vowel] or short_gem_vowel[vowel]) or "" end return append_parts(vowel, add_dagesh(letter)) end

local function get_form_final(letter, char) if type(letter) == "table" then return letter elseif mw.ustring.sub(letter, 1, 1) == ":" then return mw.ustring.sub(letter, 2) else return (char ~= "a" and char ~= "A" and forms_final_furtive[letter]) or forms_final[letter] or forms[letter] or letter end end

local function get_elet_ending(letter) if letter == "א" then return "ֵאת" else local vowel = gutturals[letter] and "ַ" or "ֶ" return append_parts(vowel, get_form_medial(letter), vowel, "ת") end end

local function ends_in_guttural(letter) if type(letter) == "table" then letter = letter[2] end return gutturals[mw.ustring.sub(letter, -1)] end

local function shva_na(letter, vowel) return ends_in_guttural(letter) and chataf_vowel[vowel or "a"] or "ְ" end

local function reduce(char, chataf) return char_vowel_reduce[char] or chataf and "ֲ" or "ְ" end

local letters    = "[א-ת]" local not_letters = "[^א-ת]" local modifiers  = "[ּֿׁׂׄ׳]?" local separators = "[-־ %.,!|]?" local root_regex = "(" .. letters .. modifiers .. ")" .. separators

local function parse_root_part(part, last) if mw.ustring.sub(part, 1, 1) == ":" then return part end local letters = {} local len = 0 local subber = function(letter) table.insert(letters, letter) len = len + 1 return "" end local scraps = mw.ustring.gsub(part, root_regex, subber) if scraps ~= "" then return ":" .. part end if len < 1 then return nil elseif len == 1 then return part else local ret = "" for i, letter in ipairs(letters) do           local letterx = last and i == len and convert_final_root_char[letter] or convert_root_char[letter] if not letterx then error("Unrecognized root letter '" .. letter .. "'.") end ret = append_parts(ret, get_form_medial(letterx), i == len and "" or "ְ") end if type(ret) == "table" then return ret else return ":" .. ret end end end

local function parse_root(args) if args[2] == "" then args[2] = nil end if args[3] == "" then args[3] = nil end if args[4] == "" then args[4] = nil end if args[3] then args["p"] = args["p"] or parse_root_part(args[2]) args["a"] = args["a"] or parse_root_part(args[3]) args["l"] = args["l"] or parse_root_part(args[4], true) elseif args[2] then local radicals = {} local len = 0 local subber = function(radical) table.insert(radicals, radical) len = len + 1 return "" end local scraps = mw.ustring.gsub(args[2], root_regex, subber) if scraps ~= "" then error("Unrecognized characters in root.") end if len < 3 then error("Root must have at least three letters.") elseif len == 3 then args["p"] = args["p"] or radicals[1] args["a"] = args["a"] or radicals[2] args["l"] = args["l"] or radicals[3] elseif len == 4 then args["p"] = args["p"] or radicals[1] args["a"] = args["a"] or radicals[2] args["a2"] = args["a2"] or radicals[3] args["l"] = args["l"] or radicals[4] elseif len > 4 then error("Roots with more than four letters must be explicitly delimited.") end end end

local function convert_root(args) for _, x in ipairs({"p", "a", "a2", "l"}) do       if args[x] then local root_x = "root_" .. x           if not args[root_x] then if mw.ustring.sub(args[x], 1, 1) == ":" then args[root_x] = args[x] else args[root_x] = x == "l" and convert_final_root_char[args[x]] or convert_root_char[args[x]] if not args[root_x] then error("Unrecognized root letter '" .. args[x] .. "'.") end end end end end if args["root_a2"] then local a = append_parts(get_form_medial(args["root_a"]), "ְ", get_form_initial(args["root_a2"])) if type(a) ~= "table" then a = ":" .. a       end args["root_a"] = a       args["root_a2"] = nil end end

local function conjugate(args) args["imp_pre_stem"] = args["imp_pre_stem"] or args["fut_pre_stem"] args["imp_mid_stem"] = args["imp_mid_stem"] or args["fut_mid_stem"] args["imp_fin_stem"] = args["imp_fin_stem"] or args["fut_fin_stem"] args["imp_suf_stem"] = args["imp_suf_stem"] or args["fut_suf_stem"] args["imp_prs_stem"] = args["imp_prs_stem"] or args["fut_prs_stem"] args["imp_ffp_stem"] = args["imp_ffp_stem"] or args["fut_ffp_stem"] local fp_long = args["fp_long"] and args["fp_long"] ~= "-" if fp_long then args["fut_long_stem"] = append_parts(args["fut_long_stem"] or args["fut_suf_stem"], "ֶי") args["imp_long_stem"] = append_parts(args["imp_long_stem"] or args["imp_suf_stem"], "ֶי") end if args["imp"] ~= "-" then if not args["imp_ms"] then args["imp_ms"] = append_parts(args["imp_pre_stem"], args["imp_mid_stem"], args["imp_fin_stem"]) end if not args["imp_fs"] then args["imp_fs"] = append_parts(args["imp_prs_stem"] or args["imp_pre_stem"], args["imp_mid_stem"], args["imp_suf_stem"], "ִי") end if not args["imp_mp"] then args["imp_mp"] = append_parts(args["imp_prs_stem"] or args["imp_pre_stem"], args["imp_mid_stem"], args["imp_suf_stem"], "וּ") end if not args["imp_fp"] then args["imp_fp"] = append_parts(fp_long and (args["imp_long_pre_stem"] or args["imp_prs_stem"]) or args["imp_pre_stem"], args["imp_mid_stem"], attach_n(fp_long and args["imp_long_stem"] or args["imp_ffp_stem"]), "ָה") end end

if args["fut"] ~= "-" then if not args["fut_1s"] then args["fut_1s"] = append_parts("א", args["fut_1sp_stem"] or args["fut_pre_stem"], args["fut_mid_stem"], args["fut_fin_stem"]) end if not args["fut_2ms"] then args["fut_2ms"] = append_parts("תּ", args["fut_pre_stem"], args["fut_mid_stem"], args["fut_fin_stem"]) end if not args["fut_2fs"] then args["fut_2fs"] = append_parts("תּ", args["fut_prs_stem"] or args["fut_pre_stem"], args["fut_mid_stem"], args["fut_suf_stem"], "ִי") end if not args["fut_3ms"] then args["fut_3ms"] = append_parts("י", args["fut_pre_stem"], args["fut_mid_stem"], args["fut_fin_stem"]) end if not args["fut_3fs"] then args["fut_3fs"] = args["fut_2ms"] end if not args["fut_1p"] then args["fut_1p"] = append_parts("נ", args["fut_pre_stem"], args["fut_mid_stem"], args["fut_fin_stem"]) end if not args["fut_2mp"] then args["fut_2mp"] = append_parts("תּ", args["fut_prs_stem"] or args["fut_pre_stem"], args["fut_mid_stem"], args["fut_suf_stem"], "וּ") end if not args["fut_2fp"] then args["fut_2fp"] = append_parts("תּ", fp_long and (args["fut_long_pre_stem"] or args["fut_prs_stem"]) or args["fut_pre_stem"], args["fut_mid_stem"], attach_n(fp_long and args["fut_long_stem"] or args["fut_ffp_stem"]), "ָה") end if not args["fut_3mp"] then args["fut_3mp"] = append_parts("י", args["fut_prs_stem"] or args["fut_pre_stem"], args["fut_mid_stem"], args["fut_suf_stem"], "וּ") end if not args["fut_3fp"] then args["fut_3fp"] = append_parts("תּ", fp_long and (args["fut_long_pre_stem"] or args["fut_prs_stem"]) or args["fut_pre_stem"], args["fut_mid_stem"], attach_n(fp_long and args["fut_long_stem"] or args["fut_ffp_stem"]), "ָה") end end

if args["pres"] ~= "-" then args["pres_pre_stem"] = args["pres_pre_stem"] or "" args["pres_prs_stem"] = args["pres_prs_stem"] or args["pres_pre_stem"] if not args["pres_ms"] then args["pres_ms"] = append_parts(args["pres_pre_stem"], args["pres_ms_stem"]) end if not args["pres_fs"] then args["pres_fs_stem"] = args["pres_fs_stem"] or append_parts(args["pres_suf_stem"], "ָה") args["pres_fs"] = append_parts(args["pres_prs_stem"], args["pres_fs_stem"]) end if not args["pres_mp"] then args["pres_mp"] = append_parts(args["pres_prs_stem"], args["pres_suf_stem"], "ִים") end if not args["pres_fp"] then args["pres_fp"] = append_parts(args["pres_prs_stem"], args["pres_suf_stem"], "וֹת") end end

if args["past"] ~= "-" then args["past_pre_stem"] = args["past_pre_stem"] or "" args["past_2p_pre_stem"] = args["past_2p_pre_stem"] or args["past_pre_stem"] local past_long = args["past_long"] and args["past_long"] ~= "-" if past_long then args["past_stem"] = append_parts(args["past_long_stem"] or args["past_3_stem"] or args["past_stem"], "וֹ") args["past_2p_stem"] = args["past_stem"] args["past_long_pre_stem"] = args["past_long_pre_stem"] or args["root_l"] == "י" and args["past_pre_stem"] or args["past_2p_pre_stem"] else args["past_2p_stem"] = args["past_2p_stem"] or args["past_stem"] end local assim_t = args["assim_t"] and args["assim_t"] ~= "-" if not args["past_1s"] then args["past_1s"] = append_parts(past_long and args["past_long_pre_stem"] or args["past_pre_stem"], attach_t(args["past_stem"], false, assim_t), "ִי") end if not args["past_2ms"] then args["past_2ms"] = append_parts(past_long and args["past_long_pre_stem"] or args["past_pre_stem"], attach_t(args["past_stem"], false, assim_t), "ָ") end if not args["past_2fs"] then args["past_2fs"] = append_parts(past_long and args["past_long_pre_stem"] or args["past_pre_stem"], attach_t(args["past_stem"], true, assim_t)) end if not args["past_3ms"] then args["past_3ms"] = append_parts(args["past_pre_stem"], args["past_3ms_stem"]) end if not args["past_3fs"] then args["past_3fs"] = append_parts(args["past_3fs_pre_stem"] or args["past_3_pre_stem"] or args["past_pre_stem"], args["past_3fs_stem"] or args["past_3_stem"], "ָה") end if not args["past_1p"] then args["past_1p"] = append_parts(past_long and args["past_long_pre_stem"] or args["past_pre_stem"], attach_n(args["past_stem"]), "וּ") end if not args["past_2mp"] then args["past_2mp"] = append_parts(past_long and args["past_long_pre_stem"] or args["past_2p_pre_stem"], attach_t(args["past_2p_stem"], false, assim_t), "ֶם") end if not args["past_2fp"] then args["past_2fp"] = append_parts(past_long and args["past_long_pre_stem"] or args["past_2p_pre_stem"], attach_t(args["past_2p_stem"], false, assim_t), "ֶן") end if not args["past_2mp2"] then args["past_2mp2"] = append_parts(past_long and args["past_long_pre_stem"] or args["past_pre_stem"], attach_t(args["past_stem"], false, assim_t), "ֶם") end if not args["past_2fp2"] then args["past_2fp2"] = append_parts(past_long and args["past_long_pre_stem"] or args["past_pre_stem"], attach_t(args["past_stem"], false, assim_t), "ֶן") end if not args["past_3mp"] then args["past_3mp"] = append_parts(args["past_3_pre_stem"] or args["past_pre_stem"], args["past_3_stem"], "וּ") end if not args["past_3fp"] then args["past_3fp"] = args["past_3mp"] end end

args["inf"] = args["inf"] or "-"

args["heading"] = "Conjugation of " .. gen_link(args["past_3ms"]) end

local function get_imp_stem_endings(args, root_l, char, chataf, keep_long_vowel, guttural_force_patach) if root_l == "א" then args["imp_fin_stem"] = args["imp_fin_stem"] or append_parts(keep_long_vowel and char_vowel_open[char] or char_vowel_open_short[char], "א") args["imp_suf_stem"] = args["imp_suf_stem"] or append_parts(reduce(char, chataf), "א") args["imp_ffp_stem"] = args["imp_ffp_stem"] or append_parts(char_vowel_open_fp[char], "א") args["imp_long_stem"] = args["imp_long_stem"] or append_parts(char == "a" and char_vowel_open[char] or reduce(char, chataf), "א") elseif root_l == "י" then args["imp_fin_stem"] = args["imp_fin_stem"] or "ֵה" args["imp_suf_stem"] = args["imp_suf_stem"] or "" args["imp_ffp_stem"] = args["imp_ffp_stem"] or "ֶי" else args["imp_fin_stem"] = args["imp_fin_stem"] or append_parts(keep_long_vowel and char_vowel[char] or guttural_force_patach and gutturals[root_l] and "ַ" or char_vowel_short[char], get_form_final(root_l, guttural_force_patach and (not keep_long_vowel) and gutturals[root_l] and "a" or char)) args["imp_suf_stem"] = args["imp_suf_stem"] or append_parts(reduce(char, chataf), get_form_medial(root_l)) args["imp_ffp_stem"] = args["imp_ffp_stem"] or append_parts(gutturals[root_l] and "ַ" or char_vowel_short[char], get_form_medial(root_l), "ְ") args["imp_long_stem"] = args["imp_long_stem"] or append_parts(char == "a" and char_vowel_open[char] or reduce(char, chataf), get_form_medial(root_l)) end end

local function get_fut_stem_endings(args, root_l, char, chataf) if root_l == "א" then args["fut_fin_stem"] = args["fut_fin_stem"] or append_parts(char_vowel_open[char], "א") args["fut_suf_stem"] = args["fut_suf_stem"] or append_parts(reduce(char, chataf), "א") args["fut_ffp_stem"] = args["fut_ffp_stem"] or append_parts(char_vowel_open_fp[char], "א") args["fut_long_stem"] = args["fut_long_stem"] or append_parts(char == "a" and char_vowel_open[char] or reduce(char, chataf), "א") elseif root_l == "י" then args["fut_fin_stem"] = args["fut_fin_stem"] or "ֶה" args["fut_suf_stem"] = args["fut_suf_stem"] or "" args["fut_ffp_stem"] = args["fut_ffp_stem"] or "ֶי" else args["fut_fin_stem"] = args["fut_fin_stem"] or append_parts(char_vowel[char], get_form_final(root_l, char)) args["fut_suf_stem"] = args["fut_suf_stem"] or append_parts(reduce(char, chataf), get_form_medial(root_l)) args["fut_ffp_stem"] = args["fut_ffp_stem"] or append_parts(gutturals[root_l] and "ַ" or char_vowel_short[char], get_form_medial(root_l), "ְ") args["fut_long_stem"] = args["fut_long_stem"] or append_parts(char == "a" and char_vowel_open[char] or reduce(char, chataf), get_form_medial(root_l)) end end

local function get_pres_stem_endings(args, root_l, char, chataf, use_elet, use_et) if root_l == "י" then args["pres_ms_stem"] = args["pres_ms_stem"] or "ֶה" args["pres_suf_stem"] = args["pres_suf_stem"] or "" if use_et then args["pres_fs_stem"] = args["pres_fs_stem"] or "ֵית" end else args["pres_ms_stem"] = args["pres_ms_stem"] or append_parts(char_vowel_open[char], get_form_final(root_l, char)) args["pres_suf_stem"] = args["pres_suf_stem"] or append_parts(char == "a" and char_vowel_open[char] or reduce(char, chataf), get_form_medial(root_l)) if use_elet then args["pres_fs_stem"] = args["pres_fs_stem"] or get_elet_ending(root_l) end end end

local function get_past_stem_endings(args, root_l, char, chataf, kca, use_e) if root_l == "א" then args["past_stem"] = args["past_stem"] or append_parts(kca and char_vowel_open[char] or "ֵ", "א") args["past_3ms_stem"] = args["past_3ms_stem"] or append_parts(char_vowel_open[char], "א") args["past_3_stem"] = args["past_3_stem"] or append_parts(reduce(char, chataf), "א") args["past_long_stem"] = args["past_long_stem"] or append_parts(char == "a" and char_vowel_open[char] or reduce(char, chataf), "א") elseif root_l == "י" then args["past_stem"] = args["past_stem"] or use_e and "ֵי" or "ִי" args["past_3ms_stem"] = args["past_3ms_stem"] or "ָה" args["past_3fs_stem"] = args["past_3fs_stem"] or append_parts(reduce("a", chataf), "ת") args["past_3_stem"] = args["past_3_stem"] or "" else args["past_stem"] = args["past_stem"] or append_parts(char_vowel_closed[char], get_form_medial(root_l), "ְ") args["past_2p_stem"] = args["past_2p_stem"] or append_parts(char_vowel_unstressed[char], get_form_medial(root_l), "ְ") args["past_3ms_stem"] = args["past_3ms_stem"] or append_parts(char_vowel[char], get_form_final(root_l, char)) args["past_3_stem"] = args["past_3_stem"] or append_parts(reduce(char, chataf), get_form_medial(root_l)) args["past_long_stem"] = args["past_long_stem"] or append_parts(char == "a" and char_vowel_open[char] or reduce(char, chataf), get_form_medial(root_l)) end end

local function get_imp_stem_endings_gem(args, root_l, char) if root_l == "א" then args["imp_fin_stem"] = args["imp_fin_stem"] or append_parts(char == "a" and "ָ" or stressed_gem_vowel[char], "א") args["imp_suf_stem"] = args["imp_suf_stem"] or append_parts(char == "a" and "ָ" or stressed_gem_vowel[char], "א") args["imp_ffp_stem"] = args["imp_ffp_stem"] or append_parts(char ~= "u" and char ~= "o" and "ֶ" or stressed_gem_vowel[char], "א") else args["imp_fin_stem"] = args["imp_fin_stem"] or append_parts(stressed_gem_vowel[char], get_form_final(root_l, char)) args["imp_suf_stem"] = args["imp_suf_stem"] or get_form_double(root_l, char, true, true) args["imp_ffp_stem"] = args["imp_ffp_stem"] or append_parts(gutturals[root_l] and "ַ" or stressed_gem_vowel[char], get_form_medial(root_l), "ְ") args["imp_long_stem"] = args["imp_long_stem"] or get_form_double(root_l, char, true) end end

local function get_fut_stem_endings_gem(args, root_l, char) if root_l == "א" then args["fut_fin_stem"] = args["fut_fin_stem"] or append_parts(char == "a" and "ָ" or stressed_gem_vowel[char], "א") args["fut_suf_stem"] = args["fut_suf_stem"] or get_form_double("א", char) args["fut_ffp_stem"] = args["fut_ffp_stem"] or append_parts(char ~= "u" and char ~= "o" and "ֶ" or stressed_gem_vowel[char], "א") else args["fut_fin_stem"] = args["fut_fin_stem"] or append_parts(stressed_gem_vowel[char], get_form_final(root_l, char)) args["fut_suf_stem"] = args["fut_suf_stem"] or get_form_double(root_l, char, true, true) args["fut_ffp_stem"] = args["fut_ffp_stem"] or append_parts(gutturals[root_l] and "ַ" or stressed_gem_vowel[char], get_form_medial(root_l), "ְ") args["fut_long_stem"] = args["fut_long_stem"] or get_form_double(root_l, char, true) end end

local function get_pres_stem_endings_gem(args, root_l, char, short_a) if root_l == "א" then args["pres_ms_stem"] = args["pres_ms_stem"] or append_parts(char == "a" and "ָ" or stressed_gem_vowel[char], "א") args["pres_suf_stem"] = args["pres_suf_stem"] or get_form_double("א", char) else args["pres_ms_stem"] = args["pres_ms_stem"] or append_parts(char == "a" and (not short_a) and "ָ" or stressed_gem_vowel[char], get_form_final(root_l, char)) args["pres_suf_stem"] = args["pres_suf_stem"] or get_form_double(root_l, char, true) end end

local function get_past_stem_endings_gem(args, root_l, char) if root_l == "א" then args["past_stem"] = args["past_stem"] or append_parts(char == "a" and "ָ" or stressed_gem_vowel[char], "א") args["past_3ms_stem"] = args["past_3ms_stem"] or append_parts(char == "a" and "ָ" or stressed_gem_vowel[char], "א") args["past_3_stem"] = args["past_3_stem"] or get_form_double("א", char) else args["past_stem"] = args["past_stem"] or append_parts((char == "u" or char == "o") and {"ו", "ֹ"} or "ַ", get_form_medial(root_l), "ְ") args["past_2p_stem"] = args["past_2p_stem"] or append_parts((char == "u" or char == "o") and {"ו", "ָ"} or "ַ", get_form_medial(root_l), "ְ") args["past_3ms_stem"] = args["past_3ms_stem"] or append_parts(stressed_gem_vowel[char], get_form_final(root_l, char)) args["past_3_stem"] = args["past_3_stem"] or get_form_double(root_l, char, true, true) args["past_long_stem"] = args["past_long_stem"] or get_form_double(root_l, char, true) end end

get_stems_for["pa"] = function(args, categories) local root_p = args["root_p"] local root_a = args["root_a"] local root_l = args["root_l"]

if args["hollow"] ~= "-" then local past_char = args["past_char"] or "A" local fut_char = args["fut_char"] or (root_a == "י" and "I") or "U" local imp_char = args["imp_char"] or fut_char local inf_char = args["inf_char"] or fut_char local pres_char = args["pres_char"] or past_char

args["inf"] = args["inf"] or append_parts("לָ", get_form_medial(root_p), char_vowel[inf_char], get_form_final(root_l, inf_char)) args["noun"] = args["noun"] or append_parts(get_form_initial(root_p), "ִי", get_form_medial(root_l), "ָה")

args["imp_pre_stem"] = args["imp_pre_stem"] or get_form_initial(root_p) args["fut_pre_stem"] = args["fut_pre_stem"] or append_parts("ָ", get_form_medial(root_p)) args["fut_long_pre_stem"] = args["fut_long_pre_stem"] or append_parts("ְ", get_form_medial(root_p)) args["fut_mid_stem"] = args["fut_mid_stem"] or "" get_imp_stem_endings(args, root_l, imp_char, gutturals[root_p], true) get_fut_stem_endings(args, root_l, fut_char, gutturals[root_p])

args["pres_pre_stem"] = args["pres_pre_stem"] or get_form_initial(root_p) get_pres_stem_endings(args, root_l, pres_char, gutturals[root_p], false, false)

args["past_pre_stem"] = args["past_pre_stem"] or get_form_initial(root_p) get_past_stem_endings(args, root_l, past_char, gutturals[root_p], true, false) elseif false then -- reserved for special cases else local past_char = args["past_char"] or "a" local fut_char = args["fut_char"] local imp_char = args["imp_char"] local inf_char = args["inf_char"] local pres_char = args["pres_char"]

local if_ = nil local ef_ = nil local suf_if_ = nil if args["assim"] ~= "-" then fut_char = fut_char or ((args["elide"] ~= "-" or gutturals[root_l]) and "a") or "u" if_ = get_form_double(root_a, "i", true) ef_ = get_form_double(root_a, "e", true) elseif args["elide"] ~= "-" then if root_p == "א" then fut_char = fut_char or "a" if_ = append_parts("ֹא", get_form_medial(root_a)) ef_ = append_parts({"ו", "ֹ"}, get_form_medial(root_a)) else fut_char = fut_char or (gutturals[root_l] and root_l ~= "א" and "a") or "i" if_ = append_parts("ֵ", get_form_medial(root_a)) end elseif monophthongize[root_p] then fut_char = fut_char or "a" if_ = append_parts("ִי", get_form_medial(root_a)) elseif gutturals[root_p] then fut_char = fut_char or ((gutturals[root_l] or gutturals[root_a]) and "a") or "u" local v1 = (root_p == "א" or (root_l == "י" and root_p ~= "ע") or (root_l ~= "י" and fut_char == "a")) and "ֶ" or "ַ" if args["nochataf"] then if root_a == "י" then v1 = "ִ" end if_ = append_parts(v1, get_form_medial(root_p), "ְ", get_form_initial(root_a)) ef_ = append_parts("ֶ", get_form_medial(root_p), "ְ", get_form_initial(root_a)) else local v2 = v1 == "ֶ" and "ֱ" or "ֲ" if_ = append_parts(v1, get_form_medial(root_p), v2, get_form_medial(root_a)) ef_ = append_parts("ֶ", get_form_medial(root_p), "ֱ", get_form_medial(root_a)) suf_if_ = append_parts(v1, get_form_medial(root_p), v1, get_form_medial(root_a)) end else fut_char = fut_char or ((gutturals[root_l] or gutturals[root_a]) and "a") or "u" if_ = append_parts("ִ", get_form_medial(root_p), "ְ", get_form_initial(root_a)) ef_ = append_parts("ֶ", get_form_medial(root_p), "ְ", get_form_initial(root_a)) end

local inf_if_ = nil local p_ = nil if args["elide"] ~= "-" and root_p ~= "א" then inf_char = inf_char or "i" imp_char = imp_char or fut_char args["inf"] = args["inf"] or append_parts("לָ", get_form_medial(root_a), get_elet_ending(root_l)) p_ = get_form_initial(root_a) elseif gutturals[root_p] then inf_char = inf_char or "u" imp_char = imp_char or (root_p == "א" and args["elide"] ~= "-" and (((gutturals[root_l] or gutturals[root_a]) and "a") or "u")) or fut_char local v1 = (root_p == "א" or (root_l ~= "י" and inf_char == "a")) and "ֶ" or "ַ" if args["nochataf"] then if root_a == "י" then v1 = "ִ" end inf_if_ = append_parts(v1, get_form_medial(root_p), "ְ", get_form_initial(root_a)) else local v2 = v1 == "ֶ" and "ֱ" or "ֲ" inf_if_ = append_parts(v1, get_form_medial(root_p), v2, get_form_medial(root_a)) end p_ = append_parts(get_form_initial(root_p), root_p == "א" and "ֱ" or "ֲ", get_form_medial(root_a)) if root_l ~= "י" and root_p == "א" and gutturals[root_a] then args["imp_prs_stem"] = args["imp_prs_stem"] or append_parts(get_form_initial(root_p), "ֶ", get_form_medial(root_a)) args["imp_suf_stem"] = args["imp_suf_stem"] or append_parts("ֱ", get_form_medial(root_l)) end else inf_char = inf_char or "u" imp_char = imp_char or fut_char inf_if_ = if_ p_ = append_parts(get_form_initial(root_p), shva_na(root_p), get_form_medial(root_a)) end

args["inf"] = args["inf"] or append_parts("ל", inf_if_, root_l == "י" and "וֹת" or append_parts(char_vowel[inf_char], get_form_final(root_l, inf_char))) args["noun"] = args["noun"] or append_parts(get_form_initial(root_p), shva_na(root_p), get_form_medial(root_a), "ִי", root_l == "י" and "ּ" or get_form_medial(root_l), "ָה") args["pp"] = args["pp"] or append_parts(get_form_initial(root_p), "ָ", get_form_medial(root_a), "וּ", get_form_final(root_l, "U"))

args["imp_pre_stem"] = args["imp_pre_stem"] or p_       if root_l ~= "י" and (args["elide"] == "-" or root_p == "א") then if gutturals[root_a] then args["imp_prs_stem"] = args["imp_prs_stem"] or append_parts(get_form_initial(root_p), "ַ", get_form_medial(root_a)) if imp_char ~= "u" and imp_char ~= "i" then args["imp_long_pre_stem"] = args["imp_long_pre_stem"] or args["imp_pre_stem"] end args["imp_suf_stem"] = args["imp_suf_stem"] or append_parts("ֲ", get_form_medial(root_l)) else args["imp_prs_stem"] = args["imp_prs_stem"] or append_parts(get_form_initial(root_p), "ִ", get_form_medial(root_a)) end end args["fut_pre_stem"] = args["fut_pre_stem"] or if_ args["fut_1sp_stem"] = args["fut_1sp_stem"] or ef_ if root_l ~= "י" then args["fut_prs_stem"] = args["fut_prs_stem"] or suf_if_ end args["fut_mid_stem"] = args["fut_mid_stem"] or "" get_imp_stem_endings(args, root_l, imp_char, ends_in_guttural(root_a)) get_fut_stem_endings(args, root_l, fut_char, ends_in_guttural(root_a))

if args["pres_short"] and args["pres_short"] ~= "" then -- pa`el args["pres_pre_stem"] = args["pres_pre_stem"] or append_parts(get_form_initial(root_p), "ָ", get_form_medial(root_a)) if root_l ~= "י" then args["pres_prs_stem"] = args["pres_prs_stem"] or append_parts(get_form_initial(root_p), shva_na(root_p), get_form_medial(root_a)) end get_pres_stem_endings(args, root_l, pres_char or "E", ends_in_guttural(root_a), false, false) else -- po`el args["pres_pre_stem"] = args["pres_pre_stem"] or append_parts(get_form_initial(root_p), "וֹ", get_form_medial(root_a)) get_pres_stem_endings(args, root_l, pres_char or "i", ends_in_guttural(root_a), true, false) end

args["past_pre_stem"] = args["past_pre_stem"] or append_parts(get_form_initial(root_p), "ָ", get_form_medial(root_a)) args["past_2p_pre_stem"] = args["past_2p_pre_stem"] or append_parts(get_form_initial(root_p), shva_na(root_p), get_form_medial(root_a)) if past_char == "i" or past_char == "u" then args["past_long_pre_stem"] = args["past_long_pre_stem"] or append_parts(get_form_initial(root_p), gutturals[root_a] and "ַ" or "ִ", get_form_medial(root_a)) end get_past_stem_endings(args, root_l, past_char, ends_in_guttural(root_a), true, false) end end

get_stems_for["pi"] = function(args, categories) local root_p = args["root_p"] local root_a = args["root_a"] local root_l = args["root_l"] local past_char = args["past_char"] or "i" local fut_char = args["fut_char"] or "i" local imp_char = args["imp_char"] or fut_char local inf_char = args["inf_char"] or fut_char local pres_char = args["pres_char"] or "i"

if false then -- reserved for special cases elseif false then -- reserved for special cases else args["inf"] = args["inf"] or append_parts("לְ", get_form_medial(root_p), get_form_double(root_a, "a"), root_l == "י" and "וֹת" or append_parts(char_vowel[inf_char], get_form_final(root_l, inf_char))) args["noun"] = args["noun"] or append_parts(get_form_initial(root_p), get_form_double(root_a, "i"), "וּ", get_form_final(root_l, "U"))

args["imp_pre_stem"] = args["imp_pre_stem"] or append_parts(get_form_initial(root_p), get_form_double(root_a, "a")) args["fut_pre_stem"] = args["fut_pre_stem"] or append_parts("ְ", get_form_medial(root_p), get_form_double(root_a, "a")) args["fut_1sp_stem"] = args["fut_1sp_stem"] or append_parts("ֲ", get_form_medial(root_p), get_form_double(root_a, "a")) args["fut_mid_stem"] = args["fut_mid_stem"] or "" get_imp_stem_endings(args, root_l, imp_char, ends_in_guttural(root_a)) get_fut_stem_endings(args, root_l, fut_char, ends_in_guttural(root_a))

args["pres_pre_stem"] = args["pres_pre_stem"] or append_parts("מְ", get_form_medial(root_p), get_form_double(root_a, "a")) get_pres_stem_endings(args, root_l, pres_char, ends_in_guttural(root_a), true, false)

args["past_pre_stem"] = args["past_pre_stem"] or append_parts(get_form_initial(root_p), get_form_double(root_a, "i")) get_past_stem_endings(args, root_l, past_char, ends_in_guttural(root_a), false, false) end end

get_stems_for["po"] = function(args, categories) local root_p = args["root_p"] local root_a = args["hollow"] == "-" and args["root_a"] or args["root_l"] local root_l = args["root_l"] local past_char = args["past_char"] or "i" local fut_char = args["fut_char"] or "i" local imp_char = args["imp_char"] or fut_char local inf_char = args["inf_char"] or fut_char local pres_char = args["pres_char"] or "i"

if false then -- reserved for special cases elseif false then -- reserved for special cases else args["inf"] = args["inf"] or append_parts("לְ", get_form_medial(root_p), "וֹ", get_form_medial(root_a), root_l == "י" and "וֹת" or append_parts(char_vowel[inf_char], get_form_final(root_l, inf_char))) -- args["noun"] = args["noun"] or append_parts(get_form_initial(root_p), "וֹ", get_form_medial(root_a), shva_na(root_a), get_form_medial(root_l), "וּת") args["noun"] = args["noun"] or append_parts(get_form_initial(root_p), "ִי", get_form_medial(root_a), "וּ", get_form_final(root_l, "U"))

args["imp_pre_stem"] = args["imp_pre_stem"] or append_parts(get_form_initial(root_p), "וֹ", get_form_medial(root_a)) args["fut_pre_stem"] = args["fut_pre_stem"] or append_parts("ְ", get_form_medial(root_p), "וֹ", get_form_medial(root_a)) args["fut_1sp_stem"] = args["fut_1sp_stem"] or append_parts("ֲ", get_form_medial(root_p), "וֹ", get_form_medial(root_a)) args["fut_mid_stem"] = args["fut_mid_stem"] or "" get_imp_stem_endings(args, root_l, imp_char, ends_in_guttural(root_a)) get_fut_stem_endings(args, root_l, fut_char, ends_in_guttural(root_a))

args["pres_pre_stem"] = args["pres_pre_stem"] or append_parts("מְ", get_form_medial(root_p), "וֹ", get_form_medial(root_a)) get_pres_stem_endings(args, root_l, pres_char, ends_in_guttural(root_a), true, false)

args["past_pre_stem"] = args["past_pre_stem"] or append_parts(get_form_initial(root_p), "וֹ", get_form_medial(root_a)) get_past_stem_endings(args, root_l, past_char, ends_in_guttural(root_a), false, false) end end

get_stems_for["pu"] = function(args, categories) local root_p = args["root_p"] local root_a = args["root_a"] local root_l = args["root_l"] local past_char = args["past_char"] or "a" local fut_char = args["fut_char"] or "a" local pres_char = args["pres_char"] or "a"

if false then -- reserved for special cases elseif false then -- reserved for special cases else args["imp"] = args["imp"] or "-" args["fut_pre_stem"] = args["fut_pre_stem"] or append_parts("ְ", get_form_medial(root_p), get_form_double(root_a, "u")) args["fut_1sp_stem"] = args["fut_1sp_stem"] or append_parts("ֲ", get_form_medial(root_p), get_form_double(root_a, "u")) args["fut_mid_stem"] = args["fut_mid_stem"] or "" get_fut_stem_endings(args, root_l, fut_char, ends_in_guttural(root_a))

args["pres_pre_stem"] = args["pres_pre_stem"] or append_parts("מְ", get_form_medial(root_p), get_form_double(root_a, "u")) get_pres_stem_endings(args, root_l, pres_char, ends_in_guttural(root_a), true, false)

args["past_pre_stem"] = args["past_pre_stem"] or append_parts(get_form_initial(root_p), get_form_double(root_a, "u")) get_past_stem_endings(args, root_l, past_char, ends_in_guttural(root_a), false, true) end end

get_stems_for["poal"] = function(args, categories) local root_p = args["root_p"] local root_a = args["hollow"] == "-" and args["root_a"] or args["root_l"] local root_l = args["root_l"] local past_char = args["past_char"] or "a" local fut_char = args["fut_char"] or "a" local pres_char = args["pres_char"] or "a"

if false then -- reserved for special cases elseif false then -- reserved for special cases else args["imp"] = args["imp"] or "-" args["fut_pre_stem"] = args["fut_pre_stem"] or append_parts("ְ", get_form_medial(root_p), "וֹ", get_form_medial(root_a)) args["fut_1sp_stem"] = args["fut_1sp_stem"] or append_parts("ֲ", get_form_medial(root_p), "וֹ", get_form_medial(root_a)) args["fut_mid_stem"] = args["fut_mid_stem"] or "" get_fut_stem_endings(args, root_l, fut_char, ends_in_guttural(root_a))

args["pres_pre_stem"] = args["pres_pre_stem"] or append_parts("מְ", get_form_medial(root_p), "וֹ", get_form_medial(root_a)) get_pres_stem_endings(args, root_l, pres_char, ends_in_guttural(root_a), true, false)

args["past_pre_stem"] = args["past_pre_stem"] or append_parts(get_form_initial(root_p), "וֹ", get_form_medial(root_a)) get_past_stem_endings(args, root_l, past_char, ends_in_guttural(root_a), false, true) end end

get_stems_for["hif"] = function(args, categories) local root_p = args["root_p"] local root_a = args["root_a"] local root_l = args["root_l"] local past_char = args["past_char"] or args["geminate"] ~= "-" and "i" or "I" local fut_char = args["fut_char"] or args["geminate"] ~= "-" and "i" or "I" local imp_char = args["imp_char"] or fut_char local inf_char = args["inf_char"] or fut_char local pres_char = args["pres_char"] or args["geminate"] ~= "-" and "i" or "I"

if args["hollow"] ~= "-" then args["inf"] = args["inf"] or append_parts("לְהָ", get_form_medial(root_p), char_vowel[inf_char], get_form_final(root_l, inf_char)) args["noun"] = args["noun"] or append_parts(gutturals[root_p] and "הֶ" or "הֲ", get_form_medial(root_p), "ָ", get_form_medial(root_l), "ָה")

args["imp_pre_stem"] = args["imp_pre_stem"] or append_parts("הָ", get_form_medial(root_p)) args["fut_pre_stem"] = args["fut_pre_stem"] or append_parts("ָ", get_form_medial(root_p)) args["imp_long_pre_stem"] = args["imp_long_pre_stem"] or append_parts(gutturals[root_p] and "הַ" or "הֲ", get_form_medial(root_p)) args["fut_long_pre_stem"] = args["fut_long_pre_stem"] or append_parts("ְ", get_form_medial(root_p)) args["fut_mid_stem"] = args["fut_mid_stem"] or "" get_imp_stem_endings(args, root_l, imp_char, gutturals[root_p], false, true) get_fut_stem_endings(args, root_l, fut_char, gutturals[root_p])

args["pres_pre_stem"] = args["pres_pre_stem"] or append_parts("מֵ", get_form_medial(root_p)) args["pres_prs_stem"] = args["pres_prs_stem"] or append_parts("מְ", get_form_medial(root_p)) get_pres_stem_endings(args, root_l, pres_char, gutturals[root_p], false, false)

args["past_pre_stem"] = args["past_pre_stem"] or append_parts("הֵ", get_form_medial(root_p)) args["past_2p_pre_stem"] = args["past_2p_pre_stem"] or append_parts(gutturals[root_p] and "הַ" or "הֲ", get_form_medial(root_p)) get_past_stem_endings(args, root_l, past_char, gutturals[root_p], false, true) elseif args["geminate"] ~= "-" then args["inf"] = args["inf"] or append_parts("לְהָ", get_form_medial(root_p), char_vowel[inf_char], get_form_final(root_l, inf_char)) --- args["noun"] = args["noun"] or append_parts(gutturals[root_p] and (non_doubling_letters[root_l] and "הֶ" or "הַ") or "הֲ", get_form_medial(root_p), get_form_double(root_l, "a", true), "ָה") args["noun"] = args["noun"] or append_parts(gutturals[root_p] and "הֶ" or "הֲ", get_form_medial(root_p), "ָ", get_form_medial(root_l), "ָה")

args["imp_pre_stem"] = args["imp_pre_stem"] or append_parts("הָ", get_form_medial(root_p)) args["fut_pre_stem"] = args["fut_pre_stem"] or append_parts("ָ", get_form_medial(root_p)) args["imp_long_pre_stem"] = args["imp_long_pre_stem"] or append_parts(gutturals[root_p] and "הַ" or "הֲ", get_form_medial(root_p)) args["fut_long_pre_stem"] = args["fut_long_pre_stem"] or append_parts("ְ", get_form_medial(root_p)) args["fut_mid_stem"] = args["fut_mid_stem"] or "" get_imp_stem_endings_gem(args, root_l, imp_char) get_fut_stem_endings_gem(args, root_l, fut_char)

args["pres_pre_stem"] = args["pres_pre_stem"] or append_parts("מֵ", get_form_medial(root_p)) args["pres_prs_stem"] = args["pres_prs_stem"] or append_parts("מְ", get_form_medial(root_p)) get_pres_stem_endings_gem(args, root_l, pres_char)

args["past_pre_stem"] = args["past_pre_stem"] or append_parts("הֵ", get_form_medial(root_p)) args["past_2p_pre_stem"] = args["past_2p_pre_stem"] or append_parts(gutturals[root_p] and "הַ" or "הֲ", get_form_medial(root_p)) get_past_stem_endings_gem(args, root_l, past_char) elseif false then -- reserved for special cases else local af_ = nil local if_ = nil if args["assim"] ~= "-" then af_ = append_parts(gutturals[root_a] and "ָ" or "ַ", add_dagesh(root_a)) if_ = append_parts(gutturals[root_a] and "ֵ" or "ִ", add_dagesh(root_a)) elseif monophthongize[root_p] then af_ = append_parts(monophthongize[root_p], get_form_medial(root_a)) if_ = af_ elseif gutturals[root_p] then if args["nochataf"] then af_ = append_parts("ַ", get_form_medial(root_p), "ְ", get_form_initial(root_a)) if_ = append_parts("ֶ", get_form_medial(root_p), "ְ", get_form_initial(root_a)) else af_ = append_parts("ַ", get_form_medial(root_p), "ֲ", get_form_medial(root_a)) if_ = append_parts("ֶ", get_form_medial(root_p), "ֱ", get_form_medial(root_a)) end else af_ = append_parts("ַ", get_form_medial(root_p), "ְ", get_form_initial(root_a)) if_ = append_parts(root_a == "א" and root_l == "י" and "ֶ" or "ִ", get_form_medial(root_p), "ְ", get_form_initial(root_a)) end

args["inf"] = args["inf"] or append_parts("לְה", af_, root_l == "י" and "וֹת" or append_parts(char_vowel[inf_char], get_form_final(root_l, inf_char))) args["noun"] = args["noun"] or append_parts("ה", af_, "ָ", get_form_medial(root_l), "ָה")

args["imp_pre_stem"] = args["imp_pre_stem"] or append_parts("ה", af_) args["fut_pre_stem"] = args["fut_pre_stem"] or af_ args["fut_mid_stem"] = args["fut_mid_stem"] or "" get_imp_stem_endings(args, root_l, imp_char, ends_in_guttural(root_a), false, args["assim"] ~= "-") get_fut_stem_endings(args, root_l, fut_char, ends_in_guttural(root_a))

args["pres_pre_stem"] = args["pres_pre_stem"] or append_parts("מ", af_) get_pres_stem_endings(args, root_l, pres_char, ends_in_guttural(root_a), false, false)

args["past_pre_stem"] = args["past_pre_stem"] or append_parts("ה", if_) get_past_stem_endings(args, root_l, past_char, ends_in_guttural(root_a), false, true) end end

get_stems_for["huf"] = function(args, categories) local root_p = args["root_p"] local root_a = args["root_a"] local root_l = args["root_l"] local past_char = args["past_char"] or "a" local fut_char = args["fut_char"] or "a" local pres_char = args["pres_char"] or "a"

if args["hollow"] ~= "-" then args["imp"] = args["imp"] or "-" args["fut_pre_stem"] = args["fut_pre_stem"] or append_parts("וּ", get_form_medial(root_p)) args["fut_mid_stem"] = args["fut_mid_stem"] or "" get_fut_stem_endings(args, root_l, fut_char, gutturals[root_p])

args["pres_pre_stem"] = args["pres_pre_stem"] or append_parts("מוּ", get_form_medial(root_p)) get_pres_stem_endings(args, root_l, pres_char, gutturals[root_p], true, true)

args["past_pre_stem"] = args["past_pre_stem"] or append_parts("הוּ", get_form_medial(root_p)) get_past_stem_endings(args, root_l, past_char, gutturals[root_p], false, true) elseif args["geminate"] ~= "-" then args["imp"] = args["imp"] or "-" args["fut_pre_stem"] = args["fut_pre_stem"] or append_parts("וּ", get_form_medial(root_p)) args["fut_mid_stem"] = args["fut_mid_stem"] or "" get_fut_stem_endings_gem(args, root_l, fut_char)

args["pres_pre_stem"] = args["pres_pre_stem"] or append_parts("מוּ", get_form_medial(root_p)) get_pres_stem_endings_gem(args, root_l, pres_char)

args["past_pre_stem"] = args["past_pre_stem"] or append_parts("הוּ", get_form_medial(root_p)) get_past_stem_endings_gem(args, root_l, past_char) elseif false then -- reserved for special cases else local uf_ = nil if args["assim"] ~= "-" then uf_ = append_parts({"ו", "ֻ"}, add_dagesh(root_a)) elseif monophthongize[root_p] then uf_ = append_parts("וּ", get_form_medial(root_a)) elseif gutturals[root_p] then if args["nochataf"] then uf_ = append_parts({"ו", "ֻ"}, get_form_medial(root_p), "ְ", get_form_initial(root_a)) else uf_ = append_parts({"ו", "ָ"}, get_form_medial(root_p), "ֳ", get_form_medial(root_a)) end else uf_ = append_parts({"ו", "ֻ"}, get_form_medial(root_p), "ְ", get_form_initial(root_a)) end

args["imp"] = args["imp"] or "-" args["fut_pre_stem"] = args["fut_pre_stem"] or uf_ args["fut_mid_stem"] = args["fut_mid_stem"] or "" get_fut_stem_endings(args, root_l, fut_char, ends_in_guttural(root_a))

args["pres_pre_stem"] = args["pres_pre_stem"] or append_parts("מ", uf_) get_pres_stem_endings(args, root_l, pres_char, ends_in_guttural(root_a), true, true)

args["past_pre_stem"] = args["past_pre_stem"] or append_parts("ה", uf_) get_past_stem_endings(args, root_l, past_char, ends_in_guttural(root_a), false, true) end end

get_stems_for["nif"] = function(args, categories) local root_p = args["root_p"] local root_a = args["root_a"] local root_l = args["root_l"] local past_char = args["past_char"] or "a" local fut_char = args["fut_char"] or gutturals[root_l] and root_l ~= "א" and "a" or "i" local imp_char = args["imp_char"] or fut_char local inf_char = args["inf_char"] or fut_char local pres_char = args["pres_char"] or "a"

if false then -- reserved for special cases elseif false then -- reserved for special cases else local if_ = nil local suf_if_ = nil if args["assim"] ~= "-" then if_ = get_form_double(root_a, "i", true) elseif monophthongize[root_p] then if_ = append_parts(monophthongize[root_p], get_form_medial(root_a)) elseif gutturals[root_p] then local v1 = root_p == "ע" and root_l == "י" and "ַ" or "ֶ" if args["nochataf"] then if_ = append_parts(v1, get_form_medial(root_p), "ְ", get_form_initial(root_a)) else local v2 = v1 == "ַ" and "ֲ" or "ֱ" if_ = append_parts(v1, get_form_medial(root_p), v2, get_form_medial(root_a)) suf_if_ = append_parts(v1, get_form_medial(root_p), v1, get_form_medial(root_a)) end else if_ = append_parts("ִ", get_form_medial(root_p), "ְ", get_form_initial(root_a)) end

args["inf"] = args["inf"] or append_parts("לְה", get_form_double(root_p, "i", true), "ָ", get_form_medial(root_a), root_l == "י" and "וֹת" or append_parts(char_vowel[inf_char], get_form_final(root_l, inf_char))) if root_l == "י" then args["noun"] = args["noun"] or append_parts("ה", get_form_double(root_p, "i", true), "ָ", get_form_medial(root_a), "וּת") else args["noun"] = args["noun"] or append_parts("ה", get_form_double(root_p, "i", true), "ָ", get_form_medial(root_a), shva_na(root_a), get_form_medial(root_l), "וּת") end

args["imp_pre_stem"] = args["imp_pre_stem"] or append_parts("ה", get_form_double(root_p, "i", true), "ָ", get_form_medial(root_a)) args["fut_pre_stem"] = args["fut_pre_stem"] or append_parts(get_form_double(root_p, "i", true), "ָ", get_form_medial(root_a)) args["fut_1sp_stem"] = args["fut_1sp_stem"] or append_parts(get_form_double(root_p, "e", true), "ָ", get_form_medial(root_a)) args["fut_mid_stem"] = args["fut_mid_stem"] or "" get_imp_stem_endings(args, root_l, imp_char, ends_in_guttural(root_a)) get_fut_stem_endings(args, root_l, fut_char, ends_in_guttural(root_a))

args["pres_pre_stem"] = args["pres_pre_stem"] or append_parts("נ", if_) get_pres_stem_endings(args, root_l, pres_char, ends_in_guttural(root_a), true, true)

args["past_pre_stem"] = args["past_pre_stem"] or append_parts("נ", if_) if suf_if_ then local pres_stem_name = root_l == "י" and "past_3fs_pre_stem" or "past_3_pre_stem" args[pres_stem_name] = args[pres_stem_name] or append_parts("נ", suf_if_) end get_past_stem_endings(args, root_l, past_char, ends_in_guttural(root_a), false, true) end end

get_stems_for["hit"] = function(args, categories) local itp = get_form_itp(args["root_p"]) local etp = get_form_etp(args["root_p"]) local root_a = args["root_a"] local root_l = args["root_l"] local past_char = args["past_char"] or "i" local fut_char = args["fut_char"] or "i" local imp_char = args["imp_char"] or fut_char local inf_char = args["inf_char"] or fut_char local pres_char = args["pres_char"] or "i"

if false then -- reserved for special cases elseif false then -- reserved for special cases else args["inf"] = args["inf"] or append_parts("לְהִ", itp, get_form_double(root_a, "a"), root_l == "י" and "וֹת" or append_parts(char_vowel[inf_char], get_form_final(root_l, inf_char))) if root_l == "י" then args["noun"] = args["noun"] or append_parts("הִ", itp, get_form_double(root_a, "a"), "וּת") else args["noun"] = args["noun"] or append_parts("הִ", itp, get_form_double(root_a, "a"), shva_na(root_a), get_form_medial(root_l), "וּת") end

args["imp_pre_stem"] = args["imp_pre_stem"] or append_parts("הִ", itp, get_form_double(root_a, "a")) args["fut_pre_stem"] = args["fut_pre_stem"] or append_parts("ִ", itp, get_form_double(root_a, "a")) args["fut_1sp_stem"] = args["fut_1sp_stem"] or append_parts("ֶ", etp, get_form_double(root_a, "a")) args["fut_mid_stem"] = args["fut_mid_stem"] or "" get_imp_stem_endings(args, root_l, imp_char, ends_in_guttural(root_a)) get_fut_stem_endings(args, root_l, fut_char, ends_in_guttural(root_a))

args["pres_pre_stem"] = args["pres_pre_stem"] or append_parts("מִ", itp, get_form_double(root_a, "a")) get_pres_stem_endings(args, root_l, pres_char, ends_in_guttural(root_a), true, false)

args["past_pre_stem"] = args["past_pre_stem"] or append_parts("הִ", itp, get_form_double(root_a, "a")) get_past_stem_endings(args, root_l, past_char, ends_in_guttural(root_a), false, true) end end

get_stems_for["hitpo"] = function(args, categories) local itp = get_form_itp(args["root_p"]) local etp = get_form_etp(args["root_p"]) local root_a = args["hollow"] == "-" and args["root_a"] or args["root_l"] local root_l = args["root_l"] local past_char = args["past_char"] or "i" local fut_char = args["fut_char"] or "i" local imp_char = args["imp_char"] or fut_char local inf_char = args["inf_char"] or fut_char local pres_char = args["pres_char"] or "i"

if false then -- reserved for special cases elseif false then -- reserved for special cases else args["inf"] = args["inf"] or append_parts("לְהִ", itp, "וֹ", get_form_medial(root_a), root_l == "י" and "וֹת" or append_parts(char_vowel[inf_char], get_form_final(root_l, inf_char))) if root_l == "י" then args["noun"] = args["noun"] or append_parts("הִ", itp, "וֹ", get_form_medial(root_a), "וּת") else args["noun"] = args["noun"] or append_parts("הִ", itp, "וֹ", get_form_medial(root_a), shva_na(root_a), get_form_medial(root_l), "וּת") end

args["imp_pre_stem"] = args["imp_pre_stem"] or append_parts("הִ", itp, "וֹ", get_form_medial(root_a)) args["fut_pre_stem"] = args["fut_pre_stem"] or append_parts("ִ", itp, "וֹ", get_form_medial(root_a)) args["fut_1sp_stem"] = args["fut_1sp_stem"] or append_parts("ֶ", etp, "וֹ", get_form_medial(root_a)) args["fut_mid_stem"] = args["fut_mid_stem"] or "" get_imp_stem_endings(args, root_l, imp_char, ends_in_guttural(root_a)) get_fut_stem_endings(args, root_l, fut_char, ends_in_guttural(root_a))

args["pres_pre_stem"] = args["pres_pre_stem"] or append_parts("מִ", itp, "וֹ", get_form_medial(root_a)) get_pres_stem_endings(args, root_l, pres_char, ends_in_guttural(root_a), true, false)

args["past_pre_stem"] = args["past_pre_stem"] or append_parts("הִ", itp, "וֹ", get_form_medial(root_a)) get_past_stem_endings(args, root_l, past_char, ends_in_guttural(root_a), false, true) end end

get_stems_for["hitpu"] = function(args, categories) error("Binyan hitpu`al is not yet implemented.") end

local form_names = { ["inf"] = true, ["noun"] = true, ["pp"] = true,

["imp_ms"] = true, ["imp_fs"] = true, ["imp_mp"] = true, ["imp_fp"] = true,

["fut_1s"] = true, ["fut_2ms"] = true, ["fut_2fs"] = true, ["fut_3ms"] = true, ["fut_3fs"] = true, ["fut_1p"] = true, ["fut_2mp"] = true, ["fut_2fp"] = true, ["fut_3mp"] = true, ["fut_3fp"] = true,

["past_1s"] = true, ["past_2ms"] = true, ["past_2fs"] = true, ["past_3ms"] = true, ["past_3fs"] = true, ["past_1p"] = true, ["past_2mp"] = true, ["past_2fp"] = true, ["past_3mp"] = true, ["past_3fp"] = true,

["pres_ms"] = true, ["pres_fs"] = true, ["pres_mp"] = true, ["pres_fp"] = true, }

local optional_forms = { ["inf"] = true, ["noun"] = true, ["pp"] = true, }

local table_template = [===[

{heading}&emsp; {\op}| border="1" color="#cdcdcd" style="width:100%;border-collapse:collapse;line-height:2em;border:2px solid #000000;background:#fdfdfd;text-align:center" class="inflection-table" ! scope='row' colspan="2" style="background:#E4C0CF;border-right:2px solid" | non-finite forms {non_finite} ! colspan="2" rowspan="2" style="background:#E4C0CF;border-right:2px solid" | finite forms ! scope='col' colspan="2" style="background:#C0CFE4" | singular ! scope='col' colspan="2" style="background:#C0CFE4" | plural ! scope='col' style="background:#C0CFE4" | m. ! scope='col' style="background:#C0CFE4" | f. ! scope='col' style="background:#C0CFE4" | m. ! scope='col' style="background:#C0CFE4" | f. ! scope='row' rowspan="3" style="background:#E2E4C0;width:1px" | past ! scope='row' style="background:#C0CFE4;border-right:2px solid;width:1px" | first ! scope='row' style="background:#C0CFE4;border-right:2px solid" | second ! scope='row' style="background:#C0CFE4;border-right:2px solid" | third ! scope='row' colspan="2" style="background:#E2E4C0;border-right:2px solid" | present ! scope='row' rowspan="3" style="background:#E2E4C0" | future ! scope='row' style="background:#C0CFE4;border-right:2px solid" | first ! scope='row' style="background:#C0CFE4;border-right:2px solid" | second ! scope='row' style="background:#C0CFE4;border-right:2px solid" | third ! scope='row' colspan="2" style="background:#E2E4C0;border-right:2px solid" | imperative ]===]
 * colspan="4" style="text-align:left" |
 * - style="border-top:2px solid"
 * - style="border-top:2px solid"
 * colspan="2" | {past_1s} || colspan="2" | {past_1p}
 * {past_2ms} || {past_2fs} || {past_2mp}{2p_tag} || {past_2fp}{2p_tag}
 * {past_3ms} || {past_3fs} || colspan="2" | {past_3mp}
 * - style="border-top:2px solid"
 * {pres_ms} || {pres_fs} || {pres_mp} || {pres_fp}
 * - style="border-top:2px solid"
 * colspan="2" | {fut_1s} || colspan="2" | {fut_1p}
 * {fut_2ms} || {fut_2fs} || {fut_2mp} || {fut_2fp}{fp_tag}
 * {fut_3ms} || {fut_3fs} || {fut_3mp} || {fut_3fp}{fp_tag}
 * - style="border-top:2px solid"
 * {imp_ms} || {imp_fs} || {imp_mp} || {imp_fp}{fp_tag}
 * {\cl}

local non_finite = { ["inf"] = "* to-infinitive: {inf}\n", ["noun"] = "* action noun: {noun}\n", ["pp"] = "* passive participle: {pp}\n", }

local function make_table(args) for key, _ in pairs(form_names) do       args[key] = args[key] and gen_link(args[key]) or (not optional_forms[key]) and "—" end args["non_finite"] = m_strutils.format(non_finite["inf"], args) if args["noun"] then args["non_finite"] = args["non_finite"] .. m_strutils.format(non_finite["noun"], args) end if args["pp"] then args["non_finite"] = args["non_finite"] .. m_strutils.format(non_finite["pp"], args) end return m_strutils.format(table_template, args) end

local function track(binyan, args) local sub = nil local hollow = args["hollow"] ~= "-" local assim = args["assim"] ~= "-" local elide = args["elide"] ~= "-" and binyan == "pa" -- elide is only relevant to pa`al I think local geminate = args["geminate"] ~= "-" if binyan == "pa" or binyan == "nif" or binyan == "hif" or binyan == "huf" then if hollow then if assim or elide or geminate then sub = "?" else sub = "hollow" end elseif elide then if geminate then sub = "?" elseif assim then sub = "assim+elide" else sub = "elide" end elseif geminate then if assim then sub = "geminate+assim" else sub = "geminate" end elseif assim then sub = "assim" end end local m_debug = require('Module:debug') m_debug.track("he-conj/" .. binyan .. (sub and ("/" .. sub) or "")) if sub == "?" then m_debug.track("he-conj/incompatible-combination") end if args["past_long"] and args["past_long"] ~= "-" then m_debug.track("he-conj/past_long") end if args["past_long"] and args["fp_long"] ~= "-" then m_debug.track("he-conj/fp_long") end end

-- The main entry point. -- This is the only function that can be invoked from a template. function export.show(frame) local args = frame:getParent.args local binyan = args[1] or frame.args[1] or error("Binyan has not been specified. Please pass parameter 1 to the module invocation or parent template.") -- PAGENAME = mw.title.getCurrentTitle.text -- NAMESPACE = mw.title.getCurrentTitle.nsText

local categories = {}

parse_root(args) convert_root(args)

local root_p = args["root_p"] local root_a = args["root_a"] local root_l = args["root_l"]

if not (root_p and root_a and root_l) then error("Missing root letters.") end

args["hollow"] = args["hollow"] or ((root_a == "י" or root_a == "ו") and root_l ~= "י" and "+") or "-" args["geminate"] = args["geminate"] or ((root_a == root_l) and root_l ~= "י" and "+") or "-" args["assim"] = args["assim"] or (args["hollow"] == "-" and args["geminate"] == "-" and root_p == "נ" and not gutturals[root_a] and "+") or "-" args["elide"] = args["elide"] or (args["geminate"] and (args["assim"] ~= "-" == "-" or root_p == "י" or root_p == "ו") and root_l ~= "י" and "+") or "-"

track(binyan, args)

if binyan == "-" then -- do nothing, stems are given explicitly elseif get_stems_for[binyan] then get_stems_for[binyan](args, categories) else error("Unknown binyan code '" .. binyan .. "'") end

conjugate(args) -- finishes conjugation based on stems from get_stems_for[binyan]

local pre_notes = "" if args["past_2mp2"] and not equal(args["past_2mp"], args["past_2mp2"]) then args["2p_tag"] = "" args["fp_tag"] = "" pre_notes = pre_notes .. ""   else args["2p_tag"] = "" args["fp_tag"] = "" pre_notes = pre_notes .. ""   end args["notes"] = pre_notes .. (args["notes"] or "")

if args["bot"] or "" ~= "" then return make_bot_list(forms, sep ~= "") else return make_table(args, title) .. m_utilities.format_categories(categories, lang) end end

return export