モジュール:User:Bigballlover69/pa-verb-conj
このモジュールについての説明文ページを モジュール:User:Bigballlover69/pa-verb-conj/doc に作成できます
local export = {}
--[=[
Authorship: Aryaman Arora <AryamanA>, based on work by Ben Wing <benwing2>
]=]
--[=[
combine_stem_ending_tr
TERMINOLOGY:
-- "slot" = A particular combination of person/number/gender/tense/etc.
Example slot names for verbs are "inf_mp" (masculine plural infinitive),
"prog" (undeclined progressive form), "pfv_ind_fut_2sm" (second-person singular
masculine perfective indicative future). Each slot is filled with zero or
more forms.
-- "form" = The conjugated Punjabi form representing the value of a given slot.
-- "lemma" = The dictionary form of a given Punjabi term. Generally the direct
masculine singular infinitive, but may occasionally be another form if
that form is missing.
]=]
--[=[
FIXME:
]=]
local lang = require("Module:languages").getByCode("pa")
local m_table = require("Module:table")
local m_links = require("Module:links")
local m_string_utilities = require("Module:string utilities")
local m_script_utilities = require("Module:script utilities")
local iut = require("Module:inflection utilities")
local m_para = require("Module:parameters")
local com = require("Module:User:Bigballlover69/pa-common-test")
local u = mw.ustring.char
local rsplit = mw.text.split
local rfind = mw.ustring.find
local rmatch = mw.ustring.match
local rgmatch = mw.ustring.gmatch
local rsubn = mw.ustring.gsub
local ulen = mw.ustring.len
local usub = mw.ustring.sub
local uupper = mw.ustring.upper
local ulower = mw.ustring.lower
-- vowel diacritics; don't display nicely on their own
local AA = u(0x0a3e)
local AI = u(0x0a48)
local AU = u(0x0a4c)
local E = u(0x0a47)
local I = u(0x0a3f)
local II = u(0x0a40)
local O = u(0x0a4b)
local U = u(0x0a41)
local UU = u(0x0a42)
local R = u(0x0a43) --nonexistent
local VIRAMA = u(0x0a4d)
local TILDE = u(0x0303)
local M = 'ੰ'
local N = u(0x0a02)
local EN = E .. N
local IIN = II .. N
local UUM = UU .. M
local function term_link(hi, tr)
return m_links.full_link({term = hi, tr = tr, lang = lang}, "term")
end
local sii_note = "[Some dialects conjugate " .. term_link("ਸੀ") .. " for person and number (from left to right): " .. term_link("ਸਾਂ") .. ", " .. term_link("ਸੈ") .. ", " .. term_link("ਸੋ") .. ", " .. term_link("ਸਾਂ") .. ", " .. term_link("ਸਨ") .. "]"
-- 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
-- version of rsubn() that returns a 2nd argument boolean indicating whether
-- a substitution was made.
local function rsubb(term, foo, bar)
local retval, nsubs = rsubn(term, foo, bar)
return retval, nsubs > 0
end
local function tag_text(text)
return m_script_utilities.tag_text(text, lang)
end
local irreg_perf = {
["ਦੇ"] = "ਦਿੱਤ*",
["ਲੇ"] = "ਲਿੱਤ*",
["ਸੌ"] = "ਸੁੱਤ*",
["ਨਹਾਉ"] = "ਨਹਾਤ*",
["ਪੀ"] = "ਪੀਤ*",
["ਸੀ"] = "ਸੀਤ*",
["ਕਰ"] = "ਕੀਤ*",
["ਜਾ"] = "ਗ",
["ਖਾ"] = "ਖਾਦ*",
["ਮਰ"] = "ਮੋ",
["ਧੋ"] = "ਧੋਤ*",
}
local irreg_subj = {
}
local irreg_polite_imp = {
}
local verb_slots_impers = {
inf = "inf",
inf_obl = "obl|inf",
stem = "stem",
conj = "conj|form",
prog = "prog|form",
}
local verb_slots_pers = {
}
-- Add entries for a slot with only gender/number variants.
-- `slot_prefix` is the prefix of the slot, typically specifying the tense/aspect;
-- `tag_suffix` is the set of inflection tags to add after the gender/number tags,
-- or "-" to use "-" as the inflection tags (which indicates that no accelerator entry
-- should be generated); and `verb_slots` is the table (personal or impersonal) to
-- add the entries to.
local function add_slot_gendered(slot_prefix, tag_suffix, verb_slots)
verb_slots = verb_slots or verb_slots_pers
verb_slots[slot_prefix .. "_ms"] = tag_suffix == "-" and "-" or "m|s|" .. tag_suffix
verb_slots[slot_prefix .. "_mp"] = tag_suffix == "-" and "-" or "m|p|" .. tag_suffix
verb_slots[slot_prefix .. "_fs"] = tag_suffix == "-" and "-" or "f|s|" .. tag_suffix
verb_slots[slot_prefix .. "_fp"] = tag_suffix == "-" and "-" or "f|p|" .. tag_suffix
end
-- Same as add_slot_gendered() but specifically for participles. This changes the inflection
-- tags used, because the masculine singular entry is really only for direct masculine singular,
-- and the masculine plural entry is also for oblique masculine singular.
local function add_slot_gendered_part(slot_prefix, tag_suffix, verb_slots)
verb_slots = verb_slots or verb_slots_pers
verb_slots[slot_prefix .. "_ms"] = tag_suffix == "-" and "-" or "dir|m|s|" .. tag_suffix
verb_slots[slot_prefix .. "_mp"] = tag_suffix == "-" and "-" or "m|p|" .. tag_suffix .. "|;|obl|m|s|" .. tag_suffix
verb_slots[slot_prefix .. "_fs"] = tag_suffix == "-" and "-" or "f|s|" .. tag_suffix
verb_slots[slot_prefix .. "_fp"] = tag_suffix == "-" and "-" or "f|p|" .. tag_suffix
end
-- Compute the inflection tags associated with a given person/number/gender combination.
local function personal_tags(slot_prefix, tag_suffix, persnum, gender)
gender = gender and gender .. "|" or ""
local suffix = gender .. tag_suffix
if persnum == "2s" then -- only for imperatives
return "2|s|intim|" .. suffix
elseif persnum == "23s" then
return "2|s|intim|" .. suffix .. "|;|3|s|" .. suffix
elseif persnum == "1p" then
return "1|p|" .. suffix .. "|;|2|formal|" .. suffix
elseif persnum == "2p" then
return "2|fam|" .. suffix
elseif persnum == "3p" then
return "3|p|" .. suffix .. "|;|2|formal|" .. suffix
else
-- 1s, 3s or 1p
return persnum:gsub("^(.)(.)$", "%1|%2") .. "|" .. suffix
end
end
-- Return the possible person/number combinations given the slot prefix.
local function persnum_values(slot_prefix)
if slot_prefix:find("^imp_") then
return {"2s", "2p", "3p"}
else
return {"1s", "23s", "1p", "3p", "2p"}
end
end
-- Add entries for a slot with only person/number variants. See `add_slot_gendered()`.
local function add_slot_personal(slot_prefix, tag_suffix, verb_slots)
verb_slots = verb_slots or verb_slots_pers
for _, persnum in ipairs(persnum_values(slot_prefix)) do
local slot = slot_prefix .. "_" .. persnum
if tag_suffix == "-" then
verb_slots[slot] = "-"
else
verb_slots[slot] = personal_tags(slot_prefix, tag_suffix, persnum)
end
end
end
-- Add entries for a slot with person/number/gender variants. See `add_slot_gendered()`.
local function add_slot_gendered_personal(slot_prefix, tag_suffix, verb_slots)
verb_slots = verb_slots or verb_slots_pers
for _, persnum in ipairs(persnum_values(slot_prefix)) do
for _, gender in ipairs({"m", "f"}) do
local slot = slot_prefix .. "_" .. persnum .. gender
if tag_suffix == "-" then
verb_slots[slot] = "-"
else
verb_slots[slot] = personal_tags(slot_prefix, tag_suffix, persnum, gender)
end
end
end
end
add_slot_gendered_part("inf", "inf|part", verb_slots_impers)
add_slot_gendered_part("hab", "hab|part", verb_slots_impers)
add_slot_gendered_part("pfv", "pfv|part", verb_slots_impers)
add_slot_gendered_part("agent", "prospective//agentive|part", verb_slots_impers)
add_slot_gendered_part("adj_pfv", "-", verb_slots_impers)
add_slot_gendered_part("adj_hab", "-", verb_slots_impers)
add_slot_personal("ind_pres", "pres|ind") -- only for होना
add_slot_personal("ind_impf", "impf|ind") -- only for होना
add_slot_gendered("ind_perf", "perf|ind")
add_slot_gendered_personal("ind_fut", "fut|ind")
add_slot_gendered_personal("presum", "presumptive")
add_slot_personal("subj_pres", "pres|subj") -- only for होना
add_slot_personal("subj_fut", "fut|subj")
add_slot_gendered("cfact", "cfact")
add_slot_personal("imp_reg", "reg|imp")
add_slot_personal("imp_pol", "pol|imp")
add_slot_gendered_personal("hab_ind_pres", "-")
add_slot_gendered("hab_ind_past", "-")
add_slot_gendered_personal("hab_presum", "-")
add_slot_gendered_personal("hab_subj", "-")
add_slot_gendered("hab_cfact", "-")
for _, mood in ipairs({"pfv", "prog"}) do
add_slot_gendered_personal(mood .. "_ind_pres", "-")
add_slot_gendered(mood .. "_ind_past", "-")
add_slot_gendered_personal(mood .. "_ind_fut", "-")
add_slot_gendered_personal(mood .. "_presum", "-")
add_slot_gendered_personal(mood .. "_subj_pres", "-")
add_slot_gendered(mood .. "_cfact", "-")
end
verb_slots_impers["inf_ms_linked"] = verb_slots_impers["inf_ms"]
local all_verb_slots = {}
for k, v in pairs(verb_slots_impers) do
all_verb_slots[k] = v
end
for k, v in pairs(verb_slots_pers) do
all_verb_slots[k] = v
end
-- Add one inflected form to `base.forms`, specifically to the list of forms associated with
-- the slot `slot` in the table in `base.forms`. Each element of the list is an object of the
-- form {form=FORM, translit=TRANSLIT, footnotes=FOOTNOTES}, where TRANSLIT is missing if no
-- manual translit needs to be given and FOOTNOTES is missing if there aren't any footnotes.
-- If FOOTNOTES is present it is a list of footnotes, where each footnote is e.g. "[rare or archaic]",
-- i.e. surrounded by brackets, with the first character lowercase and no final period.
-- (The brackets are automatically removed, the first character capitalized and a final period added.)
--
-- `stem` is the Devanagari stem to add the ending to.
-- `translit_stem` is the transliteration of `stem`, or nil to use the default transliteration.
-- `ending` is the Devanagari ending to add to the stem, possibly with sandhi changes to the
-- stem or ending.
-- `footnotes` is a list of associated footnotes in the same format as FOOTNOTES above, or nil.
-- `double_word` if given causes the resulting form to be doubled with a hyphen in between the two
-- parts, for use with the progressive form (e.g. करते-करते of verb करना).
local function add(base, stem, translit_stem, slot, ending, footnotes, double_word)
local function doadd(new_stem, new_translit_stem, new_ending, slot_footnotes)
new_ending = new_ending or ending
if rfind(new_ending, "ਹਨ$") then slot_footnotes = iut.combine_footnotes(slot_footnotes, {"[colloquially, " .. term_link("ਹਨ") .. " is always " .. term_link("ਨੇ") .. " in the Majhi dialect]"}) end
if rfind(new_ending, ".ਸੀ$") then slot_footnotes = iut.combine_footnotes(slot_footnotes, sii_note) end
if new_ending and base.notlast then
-- If we're not the last verb in a multiword expression, chop off
-- anything after a space. This is to handle verbs like [[हिलना-डुलना]],
-- which have e.g. nonaspectual subjunctive 1sg masc हिलूँ-डुलूँ
-- but perfective future indicative 1sg masc हिला-डुला हूँगा. Also, there
-- are some special cases:
-- (1) the conjunctive form should be e.g. हिल-डुलकर or हिल-डुलके
-- (2) the future indicative should be e.g. 1sg हिलूँ-डुलूँगा
-- (3) the future imperative 3pl should be e.g. हिलिये-डुलियेगा
-- (4) the agentive should be e.g. हिलने-डुलनेवाला
if slot == "conj" then
new_ending = ""
elseif slot:find("^ind_pol") then
new_ending = rsub(new_ending, "ਗ.*$", "") -- गा, गे or गी
elseif slot == "imp_pol_3p" then
new_ending = rsub(new_ending, "गा$", "")--??
elseif slot:find("^agent") then
new_ending = rsub(new_ending, "ਵਾਲ.*$", "") -- वाला, वाले, वाली, वालीं
else
new_ending = rsub(new_ending, " .*", "")
end
end
com.add_form(base, new_stem or stem, new_translit_stem or translit_stem, slot,
new_ending, iut.combine_footnotes(slot_footnotes, footnotes), "link words", double_word)
end
if ending then
if rfind(stem, "^ਗ$") then -- irregular ga stem
ending = rsubn(ending, "^" .. E, "ਏ")
ending = rsubn(ending, "^" .. II, "ਈ")
ending = rsubn(ending, "^" .. I .. "ਆਂ", "ਇਆਂ")
end
if rfind(stem, "\*$") then -- some irregular stems should force -iā to turn into -ā
stem = rsubn(stem, "\*$", "")
if rfind(ending, "^" .. I .. "ਆ$") then
doadd(stem, nil, AA)
return
elseif rfind(ending, "^" .. I .. "ਆ ") then
local m = rsubn(ending, "^" .. I .. "ਆ", AA)
doadd(stem, nil, m)
return
end
end
if rfind(stem, "..[" .. U .. "ਉ]$") then
if rfind(ending, "^[" .. AA .. I .. II .. U .. UU .. E .. AI .. O .. AU .. "]") or rfind(ending, "^ ") or rfind(ending, "^$") then
stem = rsubn(stem, "[" .. U .. "ਉ]$", "")
end
end
if rfind(ending, "^ਦ") and rfind(stem, "[" .. AA .. I .. II .. U .. UU .. E .. AI .. O .. AU .. "ਅਆਇਈਉਊਏਐਓਔ]$") and stem ~= "ਧੋ" then
if rfind(stem, "^ਹੋ$") then
stem = "ਹੁ"
end
if rfind(stem, "[" .. AA .. I .. U .. UU .. "ਅਆਇ]$") then doadd(stem .. M)
else doadd(stem .. N) end
return
end
if rfind(ending, "^[" .. AA .. E .. "]") and rfind(stem, "[" .. AA .. "ਆ]$") and not (slot:find('perf') or slot:find('pfv')) then
doadd(stem .. "ਵ")
if rfind(ending, "^" .. E) then
local m = rsubn(ending, "^" .. E, "ਏ")
doadd(stem, nil, m, {"[usually less common]"})
end
return
end
if rfind(ending, "^[" .. O .. AA .. E .. "]") and rfind(stem, "[" .. O .. "ਓ]$") then
doadd(stem .. "ਵ")
return
end
if rfind(stem, "[" .. AI .. "ਐ]$") then
if rfind(ending, "^" .. I .. "ਆ$") or rfind(ending, "^" .. I .. "ਆ ") then
local n = rsubn(stem, AI .. "$", I)
n = rsubn(n, "ਐ" .. "$", "ਇ")
doadd(n, nil, AA)
return
elseif rfind(ending, "^[" .. AA .. E .. "]") and not (slot:find('perf') or slot:find('pfv')) then
local n = rsubn(stem, "[" .. AI .. "ਐ]$", "")
doadd(n .. "ਵ")
if rfind(ending, "^" .. E) then
local m = rsubn(ending, "^" .. E, "ਏ")
doadd(n, nil, m, {"[usually less common]"})
end
return
elseif rfind(ending, "^[" .. AA .. I .. II .. U .. UU .. E .. AI .. O .. AU .. "]") then
local n = rsubn(stem, "[" .. AI .. "ਐ]$", "")
local m = rsubn(ending, "^[" .. AA .. I .. II .. U .. UU .. E .. AI .. O .. AU .. "]", com.diacritic_to_independent)
doadd(n, nil, m)
return
end
end
if rfind(stem, ".ਹਿ$") then
if rfind(ending, "^" .. I .. "ਆ$") then
local n = rsubn(stem, "ਹਿ$", I .. "ਹ")
doadd(n, nil, AA)
return
elseif rfind(ending, "^" .. I .. "ਆ ") then
local n = rsubn(stem, "ਹਿ$", I .. "ਹ")
local m = rsubn(ending, "^" .. I .. "ਆ", AA)
doadd(n, nil, m)
return
elseif rfind(ending, "^[" .. AA .. I .. II .. U .. UU .. E .. AI .. O .. AU .. "]") then
local n = rsubn(stem, "ਹਿ$", "ਹ")
doadd(n)
return
end
end
if rfind(stem, "[ਰਣ]$") then
if rfind(ending, "^ ?ਣ") then
local n = rsubn(ending, "^ਣ", "ਨ")
doadd(stem, nil, n)
return
end
end
end
doadd()
end
-- Add the conjugation for a tense/aspect row with gender/number variants only.
local function add_conj_gendered(base, slot_prefix, stem, translit_stem, m_s, m_p, f_s, f_p, footnotes)
if not stem then
stem = base.stem
translit_stem = base.stem_translit
end
add(base, stem, translit_stem, slot_prefix .. "_ms", m_s, footnotes)
add(base, stem, translit_stem, slot_prefix .. "_mp", m_p, footnotes)
add(base, stem, translit_stem, slot_prefix .. "_fs", f_s, footnotes)
add(base, stem, translit_stem, slot_prefix .. "_fp", f_p, footnotes)
end
-- Add the conjugation for a tense/aspect row with person/number variants only.
local function add_conj_personal(base, slot_prefix, stem, translit_stem, s1, s23, p1, p3, p2, footnotes)
if not stem then
stem = base.stem
translit_stem = base.stem_translit
end
add(base, stem, translit_stem, slot_prefix .. "_1s", s1, footnotes)
add(base, stem, translit_stem, slot_prefix .. "_23s", s23, footnotes)
add(base, stem, translit_stem, slot_prefix .. "_1p", p1, footnotes)
add(base, stem, translit_stem, slot_prefix .. "_3p", p3, footnotes)
add(base, stem, translit_stem, slot_prefix .. "_2p", p2, footnotes)
end
-- Add the conjugation for a tense/aspect row with person/number/gender variants.
local function add_conj_gendered_personal(base, slot_prefix, stem, translit_stem,
s1m, s23m, p1m, p3m, p2m, s1f, s23f, p1f, p3f, p2f, footnotes)
if not stem then
stem = base.stem
translit_stem = base.stem_translit
end
add(base, stem, translit_stem, slot_prefix .. "_1sm", s1m, footnotes)
add(base, stem, translit_stem, slot_prefix .. "_23sm", s23m, footnotes)
add(base, stem, translit_stem, slot_prefix .. "_1pm", p1m, footnotes)
add(base, stem, translit_stem, slot_prefix .. "_3pm", p3m, footnotes)
add(base, stem, translit_stem, slot_prefix .. "_2pm", p2m, footnotes)
add(base, stem, translit_stem, slot_prefix .. "_1sf", s1f, footnotes)
add(base, stem, translit_stem, slot_prefix .. "_23sf", s23f, footnotes)
add(base, stem, translit_stem, slot_prefix .. "_1pf", p1f, footnotes)
add(base, stem, translit_stem, slot_prefix .. "_3pf", p3f, footnotes)
add(base, stem, translit_stem, slot_prefix .. "_2pf", p2f, footnotes)
end
local function handle_derived_slots_and_overrides(base)
-- No overrides implemented currently.
-- process_slot_overrides(base)
-- Compute linked versions of potential lemma slots, for use in {{hi-verb}}.
-- We substitute the original lemma (before removing links) for forms that
-- are the same as the lemma, if the original lemma has links.
-- (NOTE: Not currently used by {{hi-verb}}.)
for _, slot in ipairs({"inf_ms"}) do
iut.insert_forms(base.forms, slot .. "_linked", iut.map_forms(base.forms[slot], function(form, translit)
if form == base.orig_lemma_no_links and translit == base.lemma_translit
and rfind(base.orig_lemma, "%[%[") then
return base.orig_lemma, base.lemma_translit
else
return form, translit
end
end))
end
end
local conjs = {}
local conjprops = {}
conjs["normal"] = function(base)
local function fetch_irreg(irreg_table)
if irreg_table[base.stem] then
local stem = irreg_table[base.stem]
return stem, nil
else
return base.stem, base.stem_translit
end
end
local perf, trperf = fetch_irreg(irreg_perf)
local subj, trsubj = fetch_irreg(irreg_subj)
local polite_imp, tr_polite_imp = fetch_irreg(irreg_polite_imp)
-- Undeclined forms
add(base, base.stem, base.stem_translit, "stem", "")
add(base, base.stem, base.stem_translit, "inf", "ਣਾ")
add(base, base.stem, base.stem_translit, "inf_obl", "ਣ")
add(base, base.stem, base.stem_translit, "conj", "ਕੇ")
-- Normally progressive form is doubled (e.g. करते-करते), but not in multiword
-- expressions like हिलना-डुलना.
add(base, base.stem, base.stem_translit, "prog", "ਦੇ", nil, not base.multiword)
-- Participles
add_conj_gendered(base, "hab", nil, nil, "ਦਾ", "ਦੇ", "ਦੀ", "ਦਿਆਂ")
add_conj_gendered(base, "pfv", perf, trperf, I .. "ਆ", E, II, I .. "ਆਂ")
add_conj_gendered(base, "agent", nil, nil, "ਣ ਵਾਲ਼ਾ", "ਣ ਵਾਲ਼ੇ", "ਣ ਵਾਲ਼ੀ", "ਣ ਵਾਲ਼ਿਆਂ", "[many dialects do not have the " .. term_link("ਲ਼") .. " phoneme, instead replacing it with " .. term_link("ਲ") .. "]")
add_conj_gendered(base, "adj_pfv", perf, trperf, I .. "ਆ ਹੋਇਆ", E .. " ਹੋਏ", II .. " ਹੋਈ", I .. "ਆਂ ਹੋਇਆਂ")
add_conj_gendered(base, "adj_hab", nil, nil, "ਦਾ ਹੋਇਆ", "ਦੇ ਹੋਏ", "ਦੀ ਹੋਈ", "ਦਿਆਂ ਹੋਇਆਂ")
-- Non-aspectual
add_conj_gendered(base, "ind_perf", perf, trperf, I .. "ਆ", E, II, I .. "ਆਂ")
add_conj_personal(base, "subj_fut", subj, trsubj, AA .. N, E, AA .. N, "ਣ", O)
add_conj_gendered_personal(base, "ind_fut", subj, trsubj,
AA .. N .. "ਗਾ", E .. "ਗਾ", AA .. N .. "ਗੇ", "ਣਗੇ", O .. "ਗੇ",
AA .. N .. "ਗੀ", E .. "ਗੀ", AA .. N .. "ਗਿਆਂ", "ਣਗਿਆਂ", O .. "ਗਿਆਂ")
add(base, subj, trsubj, "ind_fut_1sm", UU .. N .. "ਗਾ", "[dialectal]")
add(base, subj, trsubj, "ind_fut_1sf", UU .. N .. "ਗੀ", "[dialectal]")
add(base, subj, trsubj, "subj_fut_1s", UU .. N, "[dialectal]")
if base.stem == "ਹੋ" then
add_conj_gendered_personal(base, "presum", "", "", "ਹੋਵਾਂਗਾ", "ਹੋਵੇਗਾ", "ਹੋਵਾਂਗੇ", "ਹੋਣਗੇ", "ਹੋਵੋਗੇ", "ਹੋਵਾਂਗੀ", "ਹੋਵੇਗੀ", "ਹੋਵਾਂਗਿਆਂ", "ਹੋਣਗਿਆਂ", "ਹੋਵੋਗਿਆ")
add_conj_personal(base, "ind_pres", "", "", "ਹਾਂ", "ਹੈ", "ਹਾਂ", "ਹਨ", "ਹੋ")
add_conj_personal(base, "ind_impf", "", "", "ਸੀ", "ਸੀ", "ਸੀ", "ਸੀ", "ਸੀ")
add_conj_personal(base, "ind_impf", "", "", "ਸਾਂ", "ਸੈ", "ਸਾਂ", "ਸਨ", "ਸੋ", "[dialectal]")
add_conj_personal(base, "subj_pres", "", "", "ਹੋਵਾਂ", "ਹੋਵੇ", "ਹੋਇਏ", "ਹੋਣ", "ਹੋਵੋ")
end
add_conj_gendered(base, "cfact", nil, nil, "ਦਾ", "ਦੇ", "ਦੀ", "ਦਿਆਂ")
add(base, base.stem, base.stem_translit, "imp_reg_2s", "")
add(base, subj, trsubj, "imp_reg_2p", O)
add(base, subj, trsubj, "imp_pol_2s", II .. N)
add(base, subj, trsubj, "imp_pol_2p", I .. "ਓ")
-- Habitual
add_conj_gendered_personal(base, "hab_ind_pres", nil, nil,
"ਦਾ ਹਾਂ", "ਦਾ ਹੈ", "ਦੇ ਹਾਂ", "ਦੇ ਹਨ", "ਦੇ ਹੋ",
"ਦੀ ਹਾਂ", "ਦੀ ਹੈ", "ਦਿਆਂ ਹਾਂ", "ਦਿਆਂ ਹਨ", "ਦਿਆਂ ਹੋ")
add_conj_gendered(base, "hab_ind_past", nil, nil, "ਦਾ ਸੀ", "ਦੇ ਸੀ", "ਦੀ ਸੀ", "ਦਿਆਂ ਸੀ")
add_conj_gendered_personal(base, "hab_presum", nil, nil,
"ਦਾ ਹੋਵਾਂਗਾ", "ਦਾ ਹੋਵੇਗਾ", "ਦੇ ਹੋਵਾਂਗੇ", "ਦੇ ਹੋਣਗੇ", "ਦੇ ਹੋਵੋਗੇ",
"ਦੀ ਹੋਵਾਂਗੀ", "ਦੀ ਹੋਵੇਗੀ", "ਦਿਆਂ ਹੋਵਾਂਗਿਆਂ", "ਦਿਆਂ ਹੋਣਗਿਆਂ", "ਦਿਆਂ ਹੋਵੋਗਿਆਂ")
add_conj_gendered_personal(base, "hab_subj", nil, nil,
"ਦਾ ਹੋਵਾਂ", "ਦਾ ਹੋਵੇ", "ਦੇ ਹੋਇਏ", "ਦੇ ਹੋਣ", "ਦੇ ਹੋਵੋ",
"ਦੀ ਹੋਵਾਂ", "ਦੀ ਹੋਵੇ", "ਦਿਆਂ ਹੋਇਏ", "ਦਿਆਂ ਹੋਣ", "ਦਿਆਂ ਹੋਵੋ")
add_conj_gendered(base, "hab_cfact", nil, nil,
"ਦਾ ਹੁੰਦਾ", "ਦੇ ਹੁੰਦੇ", "ਦੀ ਹੁੰਦੀ", "ਦਿਆਂ ਹੁੰਦਿਆਂ")
-- Perfective
add_conj_gendered_personal(base, "pfv_ind_pres", perf, trperf,
I .. "ਆ ਹਾਂ", I .. "ਆ ਹੈ", E .. " ਹਾਂ", E .. " ਹਨ", E .. " ਹੋ",
II .. " ਹਾਂ", II .. " ਹੈ", I .. "ਆਂ ਹਾਂ", I .. "ਆਂ ਹਨ", I .. "ਆਂ ਹੋ")
add_conj_gendered(base, "pfv_ind_past", perf, trperf,
I .. "ਆ ਸੀ", E .. " ਸੀ",
II .. " ਸੀ", I .. "ਆਂ ਸੀ")
add_conj_gendered_personal(base, "pfv_ind_fut", perf, trperf,
I .. "ਆ ਹੋਵਾਂਗਾ", I .. "ਆ ਹੋਵੇਗਾ", E .. " ਹੋਵਾਂਗੇ", E .. " ਹੋਣਗੇ", E .. " ਹੋਵੋਗੇ",
II .. " ਹੋਵਾਂਗਾ", II .. " ਹੋਵੇਗਾ", I .. "ਆਂ ਹੋਵਾਂਗੇ", I .. "ਆਂ ਹੋਣਗੇ", I .. "ਆਂ ਹੋਵੋਗੇ")
add_conj_gendered_personal(base, "pfv_presum", perf, trperf,
I .. "ਆ ਹੋਵਾਂਗਾ", I .. "ਆ ਹੋਵੇਗਾ", E .. " ਹੋਵਾਂਗੇ", E .. " ਹੋਣਗੇ", E .. " ਹੋਵੋਗੇ",
II .. " ਹੋਵਾਂਗਾ", II .. " ਹੋਵੇਗਾ", I .. "ਆਂ ਹੋਵਾਂਗੇ", I .. "ਆਂ ਹੋਣਗੇ", I .. "ਆਂ ਹੋਵੋਗੇ")
add_conj_gendered_personal(base, "pfv_subj_pres", perf, trperf,
I .. "ਆ ਹੋਵਾਂ", I .. "ਆ ਹੋਵੇ", E .. " ਹੋਇਏ", E .. " ਹੋਣ", E .. " ਹੋਵੋ",
II .. " ਹੋਵਾਂ", II .. " ਹੋਵੇ", I .. "ਆਂ ਹੋਇਏ", I .. "ਆਂ ਹੋਣ", I .. "ਆਂ ਹੋਵੋ")
add_conj_gendered(base, "pfv_cfact", perf, trperf, I .. "ਆ ਹੁੰਦਾ", E .. " ਹੁੰਦੇ", II .. " ਹੁੰਦੀ", I .. "ਆਂ ਹੁੰਦਿਆਂ")
-- Progressive
add_conj_gendered_personal(base, "prog_ind_pres", nil, nil,
" ਰਿਹਾ ਹਾਂ", " ਰਿਹਾ ਹੈ", " ਰਹੇ ਹਾਂ", " ਰਹੇ ਹਨ", " ਰਹੇ ਹੋ",
" ਰਹੀ ਹਾਂ", " ਰਹੀ ਹੈ", " ਰਹਿਆਂ ਹਾਂ", " ਰਹਿਆਂ ਹਨ", " ਰਹਿਆਂ ਹੋ")
add_conj_gendered(base, "prog_ind_past", nil, nil,
" ਰਿਹਾ ਸੀ", " ਰਹੇ ਸੀ",
" ਰਹੀ ਸੀ", " ਰਹਿਆਂ ਸੀ")
add_conj_gendered_personal(base, "prog_ind_fut", nil, nil,
" ਰਿਹਾ ਹੋਵਾਂਗਾ", " ਰਿਹਾ ਹੋਵੇਗਾ", " ਰਹੇ ਹੋਵਾਂਗੇ", " ਰਹੇ ਹੋਣਗੇ", " ਰਹੇ ਹੋਵੋਗੇ",
" ਰਹੀ ਹੋਵਾਂਗੀ", " ਰਹੀ ਹੋਵੇਗੀ", " ਰਹਿਆਂ ਹੋਵਾਂਗਿਆਂ", " ਰਹਿਆਂ ਹੋਣਗਿਆਂ", " ਰਹਿਆਂ ਹੋਵੋਗਿਆਂ")
add_conj_gendered_personal(base, "prog_presum", nil, nil,
" ਰਿਹਾ ਹੋਵਾਂਗਾ", " ਰਿਹਾ ਹੋਵੇਗਾ", " ਰਹੇ ਹੋਵਾਂਗੇ", " ਰਹੇ ਹੋਣਗੇ", " ਰਹੇ ਹੋਵੋਗੇ",
" ਰਹੀ ਹੋਵਾਂਗੀ", " ਰਹੀ ਹੋਵੇਗੀ", " ਰਹਿਆਂ ਹੋਵਾਂਗਿਆਂ", " ਰਹਿਆਂ ਹੋਣਗਿਆਂ", " ਰਹਿਆਂ ਹੋਵੋਗਿਆਂ")
add_conj_gendered_personal(base, "prog_subj_pres", nil, nil,
" ਰਿਹਾ ਹੋਵਾਂ", " ਰਿਹਾ ਹੋਵੇ", " ਰਹੇ ਹੋਇਏ", " ਰਹੇ ਹੋਣ", " ਰਹੇ ਹੋਵੋ",
" ਰਹੀ ਹੋਵਾਂ", " ਰਹੀ ਹੋਵੇ", " ਰਹਿਆਂ ਹੋਇਏ", " ਰਹਿਆਂ ਹੋਣ", " ਰਹਿਆਂ ਹੋਵੋ")
add_conj_gendered(base, "prog_cfact", nil, nil, " ਰਿਹਾ ਹੁੰਦਾ", " ਰਹੇ ਹੁੰਦੇ", " ਰਹੀ ਹੁੰਦੀ", " ਰਹਿਆਂ ਹੁੰਦਿਆਂ")
end
--[=[
Parse an indicator spec (text consisting of angle brackets and zero or more
dot-separated indicators within them). Return value is an object of the form
{
forms = {}, -- forms for a single spec alternant; see `forms` below
-- The following additional fields are added by other functions:
orig_lemma = "ORIGINAL-LEMMA", -- as given by the user or taken from pagename
orig_lemma_no_links = "ORIGINAL-LEMMA-NO-LINKS", -- links removed
lemma = "LEMMA", -- `orig_lemma_no_links`, converted to singular form if plural
phon_lemma = "LEMMA-PHONETIC-RESPELLING", -- as specified by the user; may be missing
lemma_translit = "LEMMA-TRANSLIT", -- translit of phon_lemma (if present)
forms = {
SLOT = {
{
form = "FORM",
footnotes = {"FOOTNOTE", "FOOTNOTE", ...} -- may be missing
},
...
},
...
},
conj = "CONJ", -- declension, e.g. "normal" (the only one currently implemented)
}
]=]
local function parse_indicator_spec(angle_bracket_spec)
local inside = rmatch(angle_bracket_spec, "^<(.*)>$")
assert(inside)
local base = {overrides = {}, forms = {}}
if inside ~= "" then
local segments = iut.parse_balanced_segment_run(inside, "[", "]")
local dot_separated_groups = iut.split_alternating_runs(segments, "%.")
for i, dot_separated_group in ipairs(dot_separated_groups) do
-- No indicators allowed currently.
local part = dot_separated_group[1]
error("Unrecognized indicator '" .. part .. "': '" .. inside .. "'")
end
end
return base
end
local function detect_indicator_spec(base)
base.conj = "normal"
if rfind(base.lemma, "ਨਾ$") then
base.lemma = rsubn(base.lemma, "ਨਾ$", "ਣਾ")
end
base.stem, base.stem_translit = com.strip_ending(base, "ਣਾ")
end
local function detect_all_indicator_specs(alternant_multiword_spec)
iut.map_word_specs(alternant_multiword_spec, function(base)
detect_indicator_spec(base)
end)
-- Set notlast=true on verbs that aren't the last one in a multiword expression, and
-- multiword=true on all verbs in multiword expressions (as well as at top level), so
-- we can properly handle verbs like [[हिलना-डुलना]].
for i, alternant_or_word_spec in ipairs(alternant_multiword_spec.alternant_or_word_specs) do
if alternant_or_word_spec.alternants then
for _, multiword_spec in ipairs(alternant_or_word_spec.alternants) do
for j, word_spec in ipairs(multiword_spec.word_specs) do
if j < #multiword_spec.word_specs then
word_spec.notlast = true
end
if #multiword_spec.word_specs > 1 then
word_spec.multiword = true
alternant_multiword_spec.multiword = true
end
end
end
else
if i < #alternant_multiword_spec.alternant_or_word_specs then
alternant_or_word_spec.notlast = true
end
if #alternant_multiword_spec.alternant_or_word_specs > 1 then
alternant_or_word_spec.multiword = true
alternant_multiword_spec.multiword = true
end
end
end
end
local function conjugate_verb(base)
if not conjs[base.conj] then
error("Internal error: Unrecognized conjugation type '" .. base.conj .. "'")
end
conjs[base.conj](base)
if base.multiword then
-- See comment in add_variant_codes() for the purpose of this.
com.add_variant_codes(base)
end
handle_derived_slots_and_overrides(base)
end
-- Compute the categories to add the verb to, as well as the annotation to display in the
-- conjugation title bar. We combine the code to do these functions as both categories and
-- title bar contain similar information.
local function compute_categories_and_annotation(alternant_multiword_spec)
local cats = {}
local function insert(cattype)
cattype = rsub(cattype, "~", alternant_multiword_spec.pos)
m_table.insertIfNot(cats, "Punjabi " .. cattype)
end
local annotation
if alternant_multiword_spec.manual then
alternant_multiword_spec.annotation = ""
else
local function do_word_spec(base)
if base.lemma_translit and lang:transliterate(base.lemma) ~= base.lemma_translit then
insert("~ with phonetic respelling")
end
end
iut.map_word_specs(alternant_multiword_spec, function(base)
do_word_spec(base)
end)
end
alternant_multiword_spec.categories = cats
end
-- Convert forms from their list/object form (see the comments to add() for how this works)
-- to strings that can be directly filled into the table. Approximately, each form is converted
-- to a formatted link with accelerators and the results are concatenated, followed by an newline
-- and then the formatted transliterations.
local function show_forms(alternant_multiword_spec)
local lemmas = alternant_multiword_spec.forms.inf_ms or {}
local props = {
lang = lang,
}
if alternant_multiword_spec.multiword then
-- Remove variant codes that were added to ensure only parallel variants in
-- multiword expressions like [[हिलना-डुलना]] get generated. See com.add_variant_codes()
-- for more information.
props.canonicalize = function(form)
return com.remove_variant_codes(form)
end
end
iut.show_forms_with_translit(alternant_multiword_spec.forms, lemmas,
verb_slots_impers, props, alternant_multiword_spec.footnotes_impers)
alternant_multiword_spec.forms.footnote_impers = alternant_multiword_spec.forms.footnote
iut.show_forms_with_translit(alternant_multiword_spec.forms, lemmas,
verb_slots_pers, props, alternant_multiword_spec.footnotes_pers)
alternant_multiword_spec.forms.footnote_pers = alternant_multiword_spec.forms.footnote
end
-- Generate the conjugation table. This should be called after show_forms() has converted
-- each form to a formatted string.
local function make_table(alternant_multiword_spec)
local table_spec_impersonal = [=[
<div class="NavFrame" style="display: table;">
<div class="NavHead hi-table-title" style="background: #d9ebff;">Impersonal forms of {inf_raw}</div>
<div class="NavContent">
{\op}| class="inflection-table inflection-hi inflection-verb" data-toggle-category="inflection"
|-
| class="hi-tense-aspect-cell"colspan=100% | ''Undeclined''
|-
| class="hi-tense-aspect-cell" colspan=2 | ''Stem''
| colspan="100%" | {stem}
|-
| class="hi-tense-aspect-cell" colspan=2 | ''Infinitive''
| colspan="100%" | {inf}
|-
| class="hi-tense-aspect-cell" colspan=2 | ''Oblique Infinitive''
| colspan="100%" | {inf_obl}
|-
| class="hi-tense-aspect-cell" colspan=2 | ''Conjunctive''
| colspan="100%" | {conj}
|-
| class="hi-tense-aspect-cell" colspan=2 | ''Progressive''
| colspan="100%" | {prog}
|-
| class="hi-tense-aspect-cell" colspan=100% | ''Participles''
|-
|- class="hi-part-gender-number-header"
| class="hi-tense-aspect-cell" colspan=2 |
| {dir} {m} {s}
| {m} {p}<br />{obl} {m} {s}
| {f} {s}
| {f} {p}
|-
| class="hi-tense-aspect-cell" colspan=2 | ''Infinitive''
| {inf_ms}
| {inf_mp}
| {inf_fs}
| {inf_fp}
|-
| class="hi-tense-aspect-cell" colspan=2 | ''Habitual''
| {hab_ms}
| {hab_mp}
| {hab_fs}
| {hab_fp}
|-
| class="hi-tense-aspect-cell" colspan=2 | ''Perfective''
| {pfv_ms}
| {pfv_mp}
| {pfv_fs}
| {pfv_fp}
|-
| class="hi-tense-aspect-cell" colspan=2 | ''Prospective<br>Agentive''
| {agent_ms}
| {agent_mp}
| {agent_fs}
| {agent_fp}
|-
| class="hi-tense-aspect-cell" rowspan=2 | ''Adjectival''
| class="hi-tense-aspect-cell" | ''Perfective''
| {adj_pfv_ms}
| {adj_pfv_mp}
| {adj_pfv_fs}
| {adj_pfv_fp}
|-
| class="hi-tense-aspect-cell" | ''Habitual''
| {adj_hab_ms}
| {adj_hab_mp}
| {adj_hab_fs}
| {adj_hab_fp}
|{\cl}{notes_clause}</div></div>]=]
local person_number_header_two_row = [=[
|- class="hi-table-header"
| rowspan=2 |
| rowspan=2 |
| class="hi-mf-cell" rowspan=2 |
]=]
local person_number_header_sg_pl_headers = [=[
| colspan=3 | '''Singular'''
| colspan=1 | '''Singular/Plural'''
| colspan=2 | '''Plural/Formal'''
]=]
local person_number_header_table_div = [=[
|- class="hi-table-header"
]=]
local person_number_header_pers_num_headers = [=[
| '''1<sup>st</sup>'''<br><span lang="pa" class="Guru">[[ਮੈਂ]]</span>
| '''2<sup>nd</sup> intimate'''<br><span lang="pa" class="Guru">[[ਤੂੰ]]</span>
| '''3<sup>rd</sup>'''<br><span lang="pa" class="Guru">[[ਇਹ]]/[[ਉਹ]]</span>
| '''2<sup>nd</sup> familiar'''<br><span lang="pa" class="Guru">[[ਤੁਸੀਂ]]</span>
| '''1<sup>st</sup>'''<br><span lang="pa" class="Guru">[[ਅਸੀਂ]]</span>
| '''2<sup>nd</sup> formal, 3<sup>rd</sup>'''<br><span lang="pa" class="Guru">[[ਇਹ]]/[[ਉਹ]]/[[ਆਪ]]</span>
]=]
-- Regular person-number header used at the top of the table and in the middle.
local person_number_header =
person_number_header_table_div .. person_number_header_two_row .. person_number_header_sg_pl_headers ..
person_number_header_table_div .. person_number_header_pers_num_headers
-- Reversed person-number header used at the bottom of the table. "Reversed" means that
-- the two rows are in reversed order; but internally we can't switch the order of everything
-- (e.g. the double-row cells at the left side), so we need to break up the header into multiple
-- parts and only reverse certain parts.
local reversed_person_number_header =
person_number_header_table_div .. person_number_header_two_row .. person_number_header_pers_num_headers ..
person_number_header_table_div .. person_number_header_sg_pl_headers
local table_spec_personal = [=[
<div class="NavFrame" style="display: table;>
<div class="NavHead hi-table-title" style="background: #d9ebff;">Personal forms of {inf_raw}</div>
<div class="NavContent">
{\op}| class="inflection-table inflection-hi inflection-verb" data-toggle-category="inflection"
|-
| class="hi-sec-div" rowspan=1 colspan=100% | ''Non-Aspectual''
{person_number_header}{pres_impf_table}| class="hi-tense-aspect-cell" rowspan=2 colspan=1 | {PERF}
| class="hi-mf-cell" | {m}
| colspan=3 | {ind_perf_ms}
| colspan=3 | {ind_perf_mp}
|- class="hi-row-f"
| class="hi-mf-cell" | {f}
| colspan=3 | {ind_perf_fs}
| colspan=3 | {ind_perf_fp}
|- class="hi-row-m"
| class="hi-tense-aspect-cell" rowspan=2 colspan=1 | {FUT}
| class="hi-mf-cell" | {m}
| {ind_fut_1sm}
| colspan=2 | {ind_fut_23sm}
| {ind_fut_2pm}
| {ind_fut_1pm}
| {ind_fut_3pm}
|- class="hi-row-f"
| class="hi-mf-cell" | {f}
| {ind_fut_1sf}
| colspan=2 | {ind_fut_23sf}
| {ind_fut_2pf}
| {ind_fut_1pf}
| {ind_fut_3pf}
{presum_table}{subj_table}
|- class="hi-row-m"
| class="hi-tense-aspect-cell" rowspan=2 colspan=1 | ''Contrafactual''
| class="hi-tense-aspect-cell" rowspan=2 colspan=1 | {PST}
| class="hi-mf-cell" | {m}
| colspan=3 | {cfact_ms}
| colspan=3 | {cfact_mp}
|- class="hi-row-f"
| class="hi-mf-cell" | {f}
| colspan=3 | {cfact_fs}
| colspan=3 | {cfact_fp}
|-
| class="hi-tense-aspect-cell" rowspan=2 colspan=1 | ''Imperative''
| class="hi-tense-aspect-cell" rowspan=1 colspan=1 | {REG}
| class="hi-mf-cell" | {mf}
|
| {imp_reg_2s}
|
| {imp_reg_2p}
|
| {imp_reg_2p}
|-
| class="hi-tense-aspect-cell" rowspan=1 colspan=1 | {POL}
| class="hi-mf-cell" | {mf}
|
| {imp_pol_2s}
|
| {imp_pol_2p}
|
| {imp_pol_2p}
|-
| class="hi-sec-div" rowspan=1 colspan=100% | ''Habitual''
|- class="hi-row-m"
| class="hi-tense-aspect-cell" rowspan=4 colspan=1 | ''Indicative''
| class="hi-tense-aspect-cell" rowspan=2 colspan=1 | {PRS}
| class="hi-mf-cell" | {m}
| {hab_ind_pres_1sm}
| colspan=2 | {hab_ind_pres_23sm}
| {hab_ind_pres_2pm}
| {hab_ind_pres_1pm}
| {hab_ind_pres_3pm}
|- class="hi-row-f"
| class="hi-mf-cell" | {f}
| {hab_ind_pres_1sf}
| colspan=2 | {hab_ind_pres_23sf}
| {hab_ind_pres_2pf}
| {hab_ind_pres_1pf}
| {hab_ind_pres_3pf}
|- class="hi-row-m"
| class="hi-tense-aspect-cell" rowspan=2 colspan=1 | {PST}
| class="hi-mf-cell" | {m}
| colspan=3 | {hab_ind_past_ms}
| colspan=3 | {hab_ind_past_mp}
|- class="hi-row-f"
| class="hi-mf-cell" | {f}
| colspan=3 | {hab_ind_past_fs}
| colspan=3 | {hab_ind_past_fp}
|- class="hi-row-m"
| class="hi-tense-aspect-cell" rowspan=2 colspan=1 | ''Presumptive''
| class="hi-tense-aspect-cell" rowspan=2 colspan=1 | {PRS_PST}
| class="hi-mf-cell" | {m}
| {hab_presum_1sm}
| colspan=2 | {hab_presum_23sm}
| {hab_presum_2pm}
| {hab_presum_1pm}
| {hab_presum_3pm}
|- class="hi-row-f"
| class="hi-mf-cell" | {f}
| {hab_presum_1sf}
| colspan=2 | {hab_presum_23sf}
| {hab_presum_2pf}
| {hab_presum_1pf}
| {hab_presum_3pf}
|- class="hi-row-m"
| class="hi-tense-aspect-cell" rowspan=2 colspan=1 | ''Subjunctive''
| class="hi-tense-aspect-cell" rowspan=2 colspan=1 | {PRS}
| class="hi-mf-cell" | {m}
| {hab_subj_1sm}
| colspan=2 | {hab_subj_23sm}
| {hab_subj_2pm}
| {hab_subj_1pm}
| {hab_subj_3pm}
|- class="hi-row-f"
| class="hi-mf-cell" | {f}
| {hab_subj_1sf}
| colspan=2 | {hab_subj_23sf}
| {hab_subj_2pf}
| {hab_subj_1pf}
| {hab_subj_3pf}
|- class="hi-row-m"
| class="hi-tense-aspect-cell" rowspan=2 colspan=1 | ''Contrafactual''
| class="hi-tense-aspect-cell" rowspan=2 colspan=1 | {PST}
| class="hi-mf-cell" | {m}
| colspan=3 | {hab_cfact_ms}
| colspan=3 | {hab_cfact_mp}
|- class="hi-row-f"
| class="hi-mf-cell" | {f}
| colspan=3 | {hab_cfact_fs}
| colspan=3 | {hab_cfact_fp}
|-
| class="hi-sec-div" rowspan=1 colspan=100% | ''Perfective''
{person_number_header}|- class="hi-row-m"
| class="hi-tense-aspect-cell" rowspan=6 colspan=1 | ''Indicative''
| class="hi-tense-aspect-cell" rowspan=2 colspan=1 | {PRS}
| class="hi-mf-cell" | {m}
| {pfv_ind_pres_1sm}
| colspan=2 | {pfv_ind_pres_23sm}
| {pfv_ind_pres_2pm}
| {pfv_ind_pres_1pm}
| {pfv_ind_pres_3pm}
|- class="hi-row-f"
| class="hi-mf-cell" | {f}
| {pfv_ind_pres_1sf}
| colspan=2 | {pfv_ind_pres_23sf}
| {pfv_ind_pres_2pf}
| {pfv_ind_pres_1pf}
| {pfv_ind_pres_3pf}
|- class="hi-row-m"
| class="hi-tense-aspect-cell" rowspan=2 colspan=1 | {PST}
| class="hi-mf-cell" | {m}
| colspan=3 | {pfv_ind_past_ms}
| colspan=3 | {pfv_ind_past_mp}
|- class="hi-row-f"
| class="hi-mf-cell" | {f}
| colspan=3 | {pfv_ind_past_fs}
| colspan=3 | {pfv_ind_past_fp}
|- class="hi-row-m"
| class="hi-tense-aspect-cell" rowspan=2 colspan=1 | {FUT}
| class="hi-mf-cell" | {m}
| {pfv_ind_fut_1sm}
| colspan=2 | {pfv_ind_fut_23sm}
| {pfv_ind_fut_2pm}
| {pfv_ind_fut_1pm}
| {pfv_ind_fut_3pm}
|- class="hi-row-f"
| class="hi-mf-cell" | {f}
| {pfv_ind_fut_1sf}
| colspan=2 | {pfv_ind_fut_23sf}
| {pfv_ind_fut_2pf}
| {pfv_ind_fut_1pf}
| {pfv_ind_fut_3pf}
|- class="hi-row-m"
| class="hi-tense-aspect-cell" rowspan=2 colspan=1 | ''Presumptive''
| class="hi-tense-aspect-cell" rowspan=2 colspan=1 | {PRS_PST}
| class="hi-mf-cell" | {m}
| {pfv_presum_1sm}
| colspan=2 | {pfv_presum_23sm}
| {pfv_presum_2pm}
| {pfv_presum_1pm}
| {pfv_presum_3pm}
|- class="hi-row-f"
| class="hi-mf-cell" | {f}
| {pfv_presum_1sf}
| colspan=2 | {pfv_presum_23sf}
| {pfv_presum_2pf}
| {pfv_presum_1pf}
| {pfv_presum_3pf}
|- class="hi-row-m"
| class="hi-tense-aspect-cell" rowspan=2 colspan=1 | ''Subjunctive''
| class="hi-tense-aspect-cell" rowspan=2 colspan=1 | {PRS}
| class="hi-mf-cell" | {m}
| {pfv_subj_pres_1sm}
| colspan=2 | {pfv_subj_pres_23sm}
| {pfv_subj_pres_2pm}
| {pfv_subj_pres_1pm}
| {pfv_subj_pres_3pm}
|- class="hi-row-f"
| class="hi-mf-cell" | {f}
| {pfv_subj_pres_1sf}
| colspan=2 | {pfv_subj_pres_23sf}
| {pfv_subj_pres_2pf}
| {pfv_subj_pres_1pf}
| {pfv_subj_pres_3pf}
|- class="hi-row-m"
| class="hi-tense-aspect-cell" rowspan=2 colspan=1 | ''Contrafactual''
| class="hi-tense-aspect-cell" rowspan=2 colspan=1 | {PST}
| class="hi-mf-cell" | {m}
| colspan=3 | {pfv_cfact_ms}
| colspan=3 | {pfv_cfact_mp}
|- class="hi-row-f"
| class="hi-mf-cell" | {f}
| colspan=3 | {pfv_cfact_fs}
| colspan=3 | {pfv_cfact_fp}
|-
| class="hi-sec-div" rowspan=1 colspan=100% | ''Progressive''
|- class="hi-row-m"
| class="hi-tense-aspect-cell" rowspan=6 colspan=1 | ''Indicative''
| class="hi-tense-aspect-cell" rowspan=2 colspan=1 | {PRS}
| class="hi-mf-cell" | {m}
| {prog_ind_pres_1sm}
| colspan=2 | {prog_ind_pres_23sm}
| {prog_ind_pres_2pm}
| {prog_ind_pres_1pm}
| {prog_ind_pres_3pm}
|- class="hi-row-f"
| class="hi-mf-cell" | {f}
| {prog_ind_pres_1sf}
| colspan=2 | {prog_ind_pres_23sf}
| {prog_ind_pres_2pf}
| {prog_ind_pres_1pf}
| {prog_ind_pres_3pf}
|- class="hi-row-m"
| class="hi-tense-aspect-cell" rowspan=2 colspan=1 | {PST}
| class="hi-mf-cell" | {m}
| colspan=3 | {prog_ind_past_ms}
| colspan=3 | {prog_ind_past_mp}
|- class="hi-row-f"
| class="hi-mf-cell" | {f}
| colspan=3 | {prog_ind_past_fs}
| colspan=3 | {prog_ind_past_fp}
|- class="hi-row-m"
| class="hi-tense-aspect-cell" rowspan=2 colspan=1 | {FUT}
| class="hi-mf-cell" | {m}
| {prog_ind_fut_1sm}
| colspan=2 | {prog_ind_fut_23sm}
| {prog_ind_fut_2pm}
| {prog_ind_fut_1pm}
| {prog_ind_fut_3pm}
|- class="hi-row-f"
| class="hi-mf-cell" | {f}
| {prog_ind_fut_1sf}
| colspan=2 | {prog_ind_fut_23sf}
| {prog_ind_fut_2pf}
| {prog_ind_fut_1pf}
| {prog_ind_fut_3pf}
|- class="hi-row-m"
| class="hi-tense-aspect-cell" rowspan=2 colspan=1 | ''Presumptive''
| class="hi-tense-aspect-cell" rowspan=2 colspan=1 | {PRS_PST_FUT}
| class="hi-mf-cell" | {m}
| {prog_presum_1sm}
| colspan=2 | {prog_presum_23sm}
| {prog_presum_2pm}
| {prog_presum_1pm}
| {prog_presum_3pm}
|- class="hi-row-f"
| class="hi-mf-cell" | {f}
| {prog_presum_1sf}
| colspan=2 | {prog_presum_23sf}
| {prog_presum_2pf}
| {prog_presum_1pf}
| {prog_presum_3pf}
|- class="hi-row-m"
| class="hi-tense-aspect-cell" rowspan=2 colspan=1 | ''Subjunctive''
| class="hi-tense-aspect-cell" rowspan=2 colspan=1 | {PRS}
| class="hi-mf-cell" | {m}
| {prog_subj_pres_1sm}
| colspan=2 | {prog_subj_pres_23sm}
| {prog_subj_pres_2pm}
| {prog_subj_pres_1pm}
| {prog_subj_pres_3pm}
|- class="hi-row-f"
| class="hi-mf-cell" | {f}
| {prog_subj_pres_1sf}
| colspan=2 | {prog_subj_pres_23sf}
| {prog_subj_pres_2pf}
| {prog_subj_pres_1pf}
| {prog_subj_pres_3pf}
|- class="hi-row-m"
| class="hi-tense-aspect-cell" rowspan=2 colspan=1 | ''Contrafactual''
| class="hi-tense-aspect-cell" rowspan=2 colspan=1 | {PST}
| class="hi-mf-cell" | {m}
| colspan=3 | {prog_cfact_ms}
| colspan=3 | {prog_cfact_mp}
|- class="hi-row-f"
| class="hi-mf-cell" | {f}
| colspan=3 | {prog_cfact_fs}
| colspan=3 | {prog_cfact_fp}
{reversed_person_number_header}|{\cl}{notes_clause}</div></div>]=]
local pres_impf_table = [=[
|-
| class="hi-tense-aspect-cell" rowspan=6 colspan=1 | ''Indicative''
| class="hi-tense-aspect-cell" rowspan=1 colspan=1 | {PRS}
| class="hi-mf-cell" | {mf}
| {ind_pres_1s}
| colspan=2 | {ind_pres_23s}
| {ind_pres_2p}
| {ind_pres_1p}
| {ind_pres_3p}
|- class="hi-row-m"
| class="hi-tense-aspect-cell" colspan=1 | {IMPF}
| class="hi-mf-cell" | {mf}
| {ind_impf_1s}
| colspan=2 | {ind_impf_23s}
| {ind_impf_2p}
| {ind_impf_1p}
| {ind_impf_3p}
|- class="hi-row-m"
]=]
local pres_impf_table_missing = [=[
|- class="hi-row-m"
| class="hi-tense-aspect-cell" rowspan=4 colspan=1 | ''Indicative''
]=]
local presum_table = [=[
|- class="hi-row-m"
| class="hi-tense-aspect-cell" rowspan=2 colspan=1 | ''Presumptive''
| class="hi-tense-aspect-cell" rowspan=2 colspan=1 | {PRS_PST_FUT}
| class="hi-mf-cell" | {m}
| {presum_1sm}
| colspan=2 | {presum_23sm}
| {presum_2pm}
| {presum_1pm}
| {presum_3pm}
|- class="hi-row-f"
| class="hi-mf-cell" | {f}
| {presum_1sf}
| colspan=2 | {presum_23sf}
| {presum_2pf}
| {presum_1pf}
| {presum_3pf}
]=]
local combined_subj = [=[
|-
| class="hi-tense-aspect-cell" rowspan=1 colspan=1 | ''Subjunctive''
| class="hi-tense-aspect-cell" rowspan=1 colspan=1 | {FUT}
| class="hi-mf-cell" | {mf}
| {subj_fut_1s}
| colspan=2 | {subj_fut_23s}
| {subj_fut_2p}
| {subj_fut_1p}
| {subj_fut_3p}]=]
local split_subj = [=[
|-
| class="hi-tense-aspect-cell" rowspan=1 colspan=1 | ''Subjunctive''
| class="hi-tense-aspect-cell" rowspan=1 colspan=1 | {PRS}
| class="hi-mf-cell" | {mf}
| {subj_pres_1s}
| colspan=2 | {subj_pres_23s}
| {subj_pres_2p}
| {subj_pres_1p}
| {subj_pres_3p}]=]
local notes_template = [===[
<div class="hi-footnote-outer-div">
<div class="hi-footnote-inner-div">
{footnote}
</div></div>
]===]
local forms = alternant_multiword_spec.forms
local function make_gender_abbr(title, text)
return '<span class="gender"><abbr title="' .. title .. '">' .. text .. '</abbr></span>'
end
local function make_tense_aspect_abbr(title, text)
local template = [=[
''<abbr style="font-variant: small-caps; text-transform: lowercase;" title="{title}">{text}</abbr>'']=]
return m_string_utilities.format(template, {title = title, text = text})
end
forms.m = make_gender_abbr("masculine gender", "m")
forms.f = make_gender_abbr("feminine gender", "f")
forms.mf = forms.m .. "<br />" .. forms.f
forms.s = make_gender_abbr("singular number", "s")
forms.p = make_gender_abbr("plural number", "p")
forms.dir = make_gender_abbr("direct", "dir")
forms.obl = make_gender_abbr("oblique", "obl")
forms.PERF = make_tense_aspect_abbr("Perfect", "PERF")
forms.IMPF = make_tense_aspect_abbr("Imperfect", "IMPF")
forms.PST = make_tense_aspect_abbr("Past", "PST")
forms.FUT = make_tense_aspect_abbr("Future", "FUT")
forms.PRS = make_tense_aspect_abbr("Present", "PRS")
forms.PRS_FUT = make_tense_aspect_abbr("Present/Future", "PRS<br />FUT")
forms.PRS_PST = make_tense_aspect_abbr("Present/Past", "PRS<br />PST")
forms.PRS_PST_FUT = make_tense_aspect_abbr("Present/Past/Future", "PRS<br />PST<br />FUT")
forms.REG = make_tense_aspect_abbr("Regular", "REG")
forms.POL = make_tense_aspect_abbr("Polite", "POL")
forms.inf_raw = tag_text(forms.lemma)
-- Now format the impersonal table.
forms.footnote = forms.footnote_impers
forms.notes_clause = forms.footnote ~= "" and
m_string_utilities.format(notes_template, forms) or ""
local formatted_table_impers = m_string_utilities.format(table_spec_impersonal, forms)
-- Now format the personal table.
forms.footnote = forms.footnote_pers
forms.notes_clause = forms.footnote ~= "" and
m_string_utilities.format(notes_template, forms) or ""
if forms.ind_pres_1s ~= "—" then -- होना
forms.subj_table = m_string_utilities.format(split_subj, forms)
forms.pres_impf_table = m_string_utilities.format(pres_impf_table, forms)
forms.presum_table = m_string_utilities.format(presum_table, forms)
else
forms.subj_table = m_string_utilities.format(combined_subj, forms)
forms.pres_impf_table = pres_impf_table_missing
forms.presum_table = ""
end
forms.person_number_header = person_number_header
forms.reversed_person_number_header = reversed_person_number_header
local formatted_table_pers = m_string_utilities.format(table_spec_personal, forms)
-- Concatenate both.
return require("Module:TemplateStyles")("Module:User:Bigballlover69/hi-verb/style.css") .. formatted_table_impers .. formatted_table_pers
end
-- Implementation of template 'pa-verb cat'.
-- NOTE: Not currently used.
function export.catboiler(frame)
local SUBPAGENAME = mw.title.getCurrentTitle().subpageText
local params = {
[1] = {},
}
local args = m_para.process(frame:getParent().args, params)
local function get_pos()
local pos = rmatch(SUBPAGENAME, "^Punjabi.- ([^ ]*)s ")
if not pos then
pos = rmatch(SUBPAGENAME, "^Punjabi.- ([^ ]*)s$")
end
if not pos then
error("Invalid category name, should be e.g. \"Punjabi verbs with ...\" or \"Punjabi ... verbs\"")
end
return pos
end
local function get_sort_key()
local pos, sort_key = rmatch(SUBPAGENAME, "^Punjabi.- ([^ ]*)s with (.*)$")
if sort_key then
return sort_key
end
pos, sort_key = rmatch(SUBPAGENAME, "^Punjabi ([^ ]*)s (.*)$")
if sort_key then
return sort_key
end
return rsub(SUBPAGENAME, "^Punjabi ", "")
end
local cats = {}, pos
-- Insert the category CAT (a string) into the categories. String will
-- have "Punjabi " prepended and ~ substituted for the plural part of speech.
local function insert(cat, atbeg)
local fullcat = "Punjabi " .. rsub(cat, "~", pos .. "s")
if atbeg then
table.insert(cats, 1, fullcat)
else
table.insert(cats, fullcat)
end
end
local maintext
while true do
if args[1] then
maintext = "~ " .. args[1]
pos = get_pos()
break
end
error("Unrecognized Punjabi verb category name")
end
insert("~|" .. get_sort_key(), "at beginning")
local categories = {}
for _, cat in ipairs(cats) do
table.insert(categories, "[[Category:" .. cat .. "]]")
end
return "This category contains Punjabi " .. rsub(maintext, "~", pos .. "s")
.. "\n" ..
mw.getCurrentFrame():expandTemplate{title="hi-categoryTOC", args={}}
.. table.concat(categories, "")
end
-- Externally callable function to parse and conjugate a verb given user-specified arguments.
-- Return value is WORD_SPEC, an object where the conjugated forms are in `WORD_SPEC.forms`
-- for each slot. If there are no values for a slot, the slot key will be missing. The value
-- for a given slot is a list of objects {form=FORM, translit=TRANSLIT, footnotes=FOOTNOTES}.
function export.do_generate_forms(parent_args, pos, from_headword, def)
local params = {
[1] = {},
footnote_impers = {list = true},
footnote_pers = {list = true},
title = {},
}
if from_headword then
params["lemma"] = {list = true}
params["id"] = {}
end
local args = m_para.process(parent_args, params)
local PAGENAME = mw.title.getCurrentTitle().text
if not args[1] then
if PAGENAME == "pa-conj" then
args[1] = def or "ਵੇਖਣਾ"
else
args[1] = PAGENAME
-- If pagename has spaces in it, add links around each word
if args[1]:find(" ") then
args[1] = "[[" .. rsub(args[1], " ", "]] [[") .. "]]"
end
end
end
local parse_props = {
parse_indicator_spec = parse_indicator_spec,
lang = lang,
transliterate_respelling = com.transliterate_respelling,
allow_default_indicator = true,
allow_blank_lemma = true,
}
local alternant_multiword_spec = iut.parse_inflected_text(args[1], parse_props)
alternant_multiword_spec.title = args.title
alternant_multiword_spec.footnotes_impers = args.footnote_impers
alternant_multiword_spec.footnotes_pers = args.footnote_pers
alternant_multiword_spec.pos = pos or "verbs"
alternant_multiword_spec.args = args
com.normalize_all_lemmas(alternant_multiword_spec)
detect_all_indicator_specs(alternant_multiword_spec)
local inflect_props = {
slot_table = all_verb_slots,
lang = lang,
inflect_word_spec = conjugate_verb,
-- Return the variant code that was added to ensure only parallel variants in
-- multiword expressions like [[हिलना-डुलना]] get generated. See com.add_variant_codes()
-- for more information.
get_variants = alternant_multiword_spec.multiword and com.get_variants or nil,
-- We add links around the generated verbal forms rather than allow the entire multiword
-- expression to be a link, so ensure that user-specified links get included as well.
include_user_specified_links = true,
}
iut.inflect_multiword_or_alternant_multiword_spec(alternant_multiword_spec, inflect_props)
compute_categories_and_annotation(alternant_multiword_spec)
return alternant_multiword_spec
end
-- Entry point for {{hi-conj}}. Template-callable function to parse and conjugate a verb given
-- user-specified arguments and generate a displayable table of the conjugated forms.
function export.show(frame)
local parent_args = frame:getParent().args
local alternant_multiword_spec = export.do_generate_forms(parent_args)
show_forms(alternant_multiword_spec)
return make_table(alternant_multiword_spec) .. require("Module:utilities").format_categories(alternant_multiword_spec.categories, lang)
end
-- Concatenate all forms of all slots into a single string of the form
-- "SLOT=FORM,FORM,...|SLOT=FORM,FORM,...|...". Each FORM is either a string in Devanagari or
-- (if manual translit is present) a specification of the form "FORM//TRANSLIT" where FORM is the
-- Devanagari representation of the form and TRANSLIT its manual transliteration. Embedded pipe symbols
-- (as might occur in embedded links) are converted to <!>. If INCLUDE_PROPS is given, also include
-- additional properties (currently, none). This is for use by bots.
local function concat_forms(alternant_spec, include_props)
local ins_text = {}
for slot, _ in pairs(verb_slots_with_linked) do
local formtext = iut.concat_forms_in_slot(alternant_spec.forms[slot])
if formtext then
table.insert(ins_text, slot .. "=" .. formtext)
end
end
return table.concat(ins_text, "|")
end
-- Template-callable function to parse and conjugate a verb given user-specified arguments and return
-- the forms as a string of the same form as documented in concat_forms() above.
function export.generate_forms(frame)
local include_props = frame.args["include_props"]
local parent_args = frame:getParent().args
local alternant_spec = export.do_generate_forms(parent_args)
return concat_forms(alternant_spec, include_props)
end
return export