text:
Module:pa-common

local export = {}

--[=[

Authorship: Ben Wing

]=]

local m_links = require("Module:links") local iut = require("Module:inflection utilities")

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

local current_title = mw.title.getCurrentTitle local PAGENAME = current_title.text

local u = mw.ustring.char local rsplit = mw.text.split local rfind = mw.ustring.find local rmatch = mw.ustring.match local rsubn = mw.ustring.gsub local usub = mw.ustring.sub

-- 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

-- 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)

export.diacritic_to_independent = { [AA] = "ਆ", [I] = "ਇ", [II] = "ਈ", [U] = "ਉ", [UU] = "ਊ", [R] = "?", [E] = "ਏ", [AI] = "ਐ", [O] = "ਓ", [AU] = "ਔ", }

local diacritic_list = {} local independent_list = {} for dia, ind in pairs(export.diacritic_to_independent) do	table.insert(independent_list, ind) table.insert(diacritic_list, dia) end

export.diacritics = table.concat(diacritic_list) export.independents = table.concat(independent_list) .. "ਅ" export.vowels = export.diacritics .. export.independents export.transliterated_diacritics = "aāãeẽiīĩoõuūũṛ" .. TILDE

-- variant codes export.VAR1 = u(0xFFF0) export.VAR2 = u(0xFFF1) export.VAR3 = u(0xFFF2) export.VAR4 = u(0xFFF3) export.VAR5 = u(0xFFF4) export.VAR6 = u(0xFFF5) export.var_code_c = "[" .. export.VAR1 .. export.VAR2 .. export.VAR3 .. export.VAR4 .. export.VAR5 .. export.VAR6 .. "]" export.not_var_code_c = "[^" .. export.VAR1 .. export.VAR2 .. export.VAR3 .. export.VAR4 .. export.VAR5 .. export.VAR6 .. "]"

export.index_to_variant_code = { [1] = export.VAR1, [2] = export.VAR2, [3] = export.VAR3, [4] = export.VAR4, [5] = export.VAR5, [6] = export.VAR6, }

function export.split_term_respelling(term) if rfind(term, "//") then local split = rsplit(term, "//") if #split ~= 2 then error("Term with respelling should have only one // in it: " .. term) end return unpack(split) else return term, nil end end

function export.transliterate_respelling(phon) if not phon then return nil end local hindi_range = "[ਁ-੶*]" -- 0x0900 to 0x097f; include *, which is a translit signal if rfind(phon, "^%-?" .. hindi_range) then return rsub((lang:transliterate(phon)), "%.", "") end return phon -- already transliterated end

function export.add_form(base, stem, translit_stem, slot, ending, footnotes, link_words, double_word) if not ending then return end

local function combine_stem_ending(stem, ending) local result if ending == "" then result = stem else if rfind(stem, VIRAMA .. "$") and rfind(base.lemma, VIRAMA .. "$") then stem = rsub(stem, VIRAMA .. "$", "") end if stem == "" or rfind(stem, "[" .. export.vowels .. "]$") then -- A diacritic at the beginning of the ending should be converted to its independent form -- if the stem does not end in a consonant. if rfind(ending, "^[" .. export.diacritics .. "]") then local ending_first = usub(ending, 1, 1) ending = (export.diacritic_to_independent[ending_first] or ending_first) .. usub(ending, 2) -- Diacritic e goes above the line and requires anusvara, but independent e does not -- go above the line and prefers chandrabindu in endings. end end -- Don't convert independent letters to diacritics after consonants because of cases like मई -- where the independent letter belongs after the consonant. result = stem .. ending end if link_words then -- Add links around the words. result = "" .. rsub(result, " ", " ") .. "" end if double_word then -- hack to support the progressive form of verbs, which is e.g. करते-करते return result .. "-" .. result else return result end end

local function combine_stem_ending_tr(stem, ending) local result if ending == "" then result = stem else -- When adding a non-null ending, remove final '-a' from the stem, but only -- if the transliterated lemma also ended in '-a'. This way, a noun like -- पुनश्च transliterated 'punaśca' "postscript" gets oblique plural transliterated -- 'punaścõ' with dropped '-a', but मई transliterated 'maī' "May" with -- transliterated stem 'ma' and ending singular ending '-ī' doesn't get the -- '-a' dropped. A third case we need to handle correctly is इंटरव्यू "interview"; -- if we truncate the final ू '-ū' and then transliterate, we get 'iṇṭarvya' -- with extra '-a' that may appear in the transliteration if we're not careful. --			-- HACK! Handle प्रातः correctly by checking specially for lemma_translit ending -- in -a or -aḥ and ending starting with a vowel. The proper way to do this -- correctly that handles all of the above cases requires access to the original -- (Devanagari) ending, and checks to see if the stem ends in '-a' and the ending -- begins with a Devanagari diacritic; in this case, it's correct to elide the '-a'. if base.lemma_translit and rfind(stem, "a$") and rfind(base.lemma_translit, "aḥ?$") and rfind(ending, "^[" .. export.transliterated_diacritics .. "]") then stem = rsub(stem, "a$", "") end result = stem .. ending end if double_word then -- hack to support the progressive form of verbs, which is e.g. करते-करते return result .. "-" .. result else return result end end

footnotes = iut.combine_footnotes(base.footnotes, footnotes) local ending_obj = iut.combine_form_and_footnotes(ending, footnotes) if translit_stem then stem = {form = stem, translit = translit_stem} end iut.add_forms(base.forms, slot, stem, ending_obj, combine_stem_ending, lang,		combine_stem_ending_tr) end

function export.strip_ending_from_stem(stem, translit_stem, ending) local new_stem = rmatch(stem, "^(.*)" .. ending .. "$") if not new_stem then error("Internal error: Lemma or stem " .. stem .. " should end in " .. ending) end local new_translit_stem if translit_stem then local ending_translit = (lang:transliterate(ending)) new_translit_stem = rmatch(translit_stem, "^(.*)" .. ending_translit .. "$") if not new_translit_stem then error("Unable to strip ending " .. ending .. " (transliterated " .. ending_translit .. ") from transliteration " .. translit_stem) end end return new_stem, new_translit_stem end

function export.strip_ending(base, ending) return export.strip_ending_from_stem(base.lemma, base.lemma_translit, ending) end

-- Normalize all lemmas, splitting out phonetic respellings and substituting -- the pagename for blank lemmas. Set `lemma_translit` to the transliteration of the -- respelling, or (if `always_transliterate` is given) to the transliteration of the -- lemma. `always_transliterate` should be specified for nouns and adjectives, where the -- lemma transliteration should be carried over to all remaining forms (hence since अंकल -- is transliterated 'aṅkal', the oblique plural अंकलों should be 'aṅkalõ' not #'aṅklõ', -- the default transliteration). But it should not be specified for verbs, where this -- carry-over doesn't apply: even though उगालना has transliteration 'ugalnā', the -- perfective participle उगला has default transliteration 'uglā' not the carry-over -- transliteration #'ugalā'. function export.normalize_all_lemmas(alternant_multiword_spec, always_transliterate) iut.map_word_specs(alternant_multiword_spec, function(base)		base.lemma, base.phon_lemma = export.split_term_respelling(base.lemma)		if base.lemma == "" then			base.lemma = PAGENAME		end		base.orig_lemma = base.lemma		base.orig_lemma_no_links = m_links.remove_links(base.lemma)		base.lemma = base.orig_lemma_no_links		if base.phon_lemma then			base.lemma_translit = export.transliterate_respelling(base.phon_lemma)		elseif always_transliterate then			base.lemma_translit = (lang:transliterate(base.lemma))		end	end) end

--[=[ Remove redundant translit. We need to do all declension of nouns and adjectives using manual translit because declined forms of nouns like अचकन "jacket" and कालाधन "black money" may need manual translit, even though the base form itself doesn't need manual translit. For example, अचकन has default translit ackan, which is correct, but the oblique plural अचकनों has default translit acaknõ, which is incorrect (correct is ackanõ, with stem translit as in the base). In general, such words need manual translit that forces the stem of the inflected form to have the same translit as the stem of the base form. We want to remove redundant manual translit so that accelerator-generated entries don't have unnecessary manual translit in them. Finally, we need to remove redundant manual translit at the very end, not as we decline each part of a multiword expression (which we used to do), because of cases like कालाधन, which declines as if written काला धन. Hence it has oblique plural कालेधनों, which has incorrect default translit kaledhnõ instead of correct kaledhanõ, even though the individual parts काले and धनों both have correct default translits. ]=] function export.remove_redundant_translit(alternant_multiword_spec) for slot, forms in pairs(alternant_multiword_spec.forms) do		alternant_multiword_spec.forms[slot] = iut.map_forms(forms, function(form, translit)			if translit and (lang:transliterate(m_links.remove_links(form))) == translit then				return form, nil			else				return form, translit			end		end) end end

function export.get_variants(form) return rsub(form, export.not_var_code_c, "") end

function export.remove_variant_codes(form) return rsub(form, export.var_code_c, "") end

-- Add variant codes to all slots with more than one form. The intention of variant -- codes is to prevent there being N^2 slot variants in a verb like हिलना-डुलना in -- slots that normally have N variants. Rather than combining all variants of हिलना -- with all variants of डुलना for the given slot, we only want to combine parallel -- variants. We implement this by tagging each variant with a "variant code" character -- and rejecting combinations with mismatching variant code characters. function export.add_variant_codes(base) for slot, forms in pairs(base.forms) do		if #forms > 1 then local index = 0 base.forms[slot] = iut.map_forms(forms, function(form, translit)				index = index + 1				local varcode = export.index_to_variant_code[index]				if not varcode then					error("Internal error: Encountered too many variants (" .. #forms .. "), no more variant codes available")				end				return form .. varcode, translit			end) end end end

return export

title: Module:pa-common


text: Citations:supercontacter

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

title: Citations:supercontacter


text: A-V

title: A-V


text: A/V

title: A/V


text:
တရုတ်မဆလာ

Noun

 * 1) five-spice powder

title: တရုတ်မဆလာ


text:
Module:pa-verb

local export = {}

--[=[

Authorship: Aryaman Arora , based on work by Ben Wing

]=]

--[=[ 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:pa-common")

local u = require("Module:string/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. -- 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 .) 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", "") if rfind(base.stem, "[ੜਰ](੍ਹ)?$") then add(base, base.stem, base.stem_translit, "inf", "ਨਾ") add(base, base.stem, base.stem_translit, "inf_obl", "ਨ") else add(base, base.stem, base.stem_translit, "inf", "ਣਾ") add(base, base.stem, base.stem_translit, "inf_obl", "ਣ") end 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, "ਣ ਵਾਲ਼ਾ", "ਣ ਵਾਲ਼ੇ", "ਣ ਵਾਲ਼ੀ", "ਣ ਵਾਲ਼ਿਆਂ", "[The presence of the" .. term_link("ਲ਼") .. " phoneme can vary by dialect " .. 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 = { lemmas = lemmas, slot_table = verb_slots_impers, lang = lang, include_translit = true, }	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(alternant_multiword_spec.forms, props) alternant_multiword_spec.forms.footnote_impers = alternant_multiword_spec.forms.footnote props.slot_table = verb_slots_pers iut.show_forms(alternant_multiword_spec.forms, props) 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 = [=[ Impersonal forms of {inf_raw} {\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 ! class="hi-tense-aspect-cell" colspan=2 | Infinitive ! class="hi-tense-aspect-cell" colspan=2 | Oblique Infinitive ! class="hi-tense-aspect-cell" colspan=2 | Conjunctive ! class="hi-tense-aspect-cell" colspan=2 | Progressive ! class="hi-tense-aspect-cell" colspan=100% | Participles ! {dir} {m} {s} ! {m} {p} {obl} {m} {s} ! {f} {s} ! {f} {p} ! class="hi-tense-aspect-cell" colspan=2 | Infinitive ! class="hi-tense-aspect-cell" colspan=2 | Habitual ! class="hi-tense-aspect-cell" colspan=2 | Perfective ! class="hi-tense-aspect-cell" colspan=2 | Prospective Agentive ! class="hi-tense-aspect-cell" rowspan=2 | Adjectival ! class="hi-tense-aspect-cell" | Perfective ! class="hi-tense-aspect-cell" | Habitual
 * colspan="100%" | {stem}
 * colspan="100%" | {inf}
 * colspan="100%" | {inf_obl}
 * colspan="100%" | {conj}
 * colspan="100%" | {prog}
 * - class="hi-part-gender-number-header"
 * class="hi-tense-aspect-cell" colspan=2 |
 * class="hi-tense-aspect-cell" colspan=2 |
 * {inf_ms}
 * {inf_mp}
 * {inf_fs}
 * {inf_fp}
 * {hab_ms}
 * {hab_mp}
 * {hab_fs}
 * {hab_fp}
 * {pfv_ms}
 * {pfv_mp}
 * {pfv_fs}
 * {pfv_fp}
 * {agent_ms}
 * {agent_mp}
 * {agent_fs}
 * {agent_fp}
 * {adj_pfv_ms}
 * {adj_pfv_mp}
 * {adj_pfv_fs}
 * {adj_pfv_fp}
 * {adj_hab_ms}
 * {adj_hab_mp}
 * {adj_hab_fs}
 * {adj_hab_fp}
 * {\cl}{notes_clause} ]=]

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 = [=[ ! 1st ਮੈਂ ! 2nd intimate ਤੂੰ ! 3rd ਇਹ/ਉਹ ! 2nd familiar ਤੁਸੀਂ ! 1st ਅਸੀਂ ! 2nd formal, 3rd ਇਹ/ਉਹ/ਆਪ ]=]

-- 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 = [=[ Personal forms of {inf_raw} {\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} ! class="hi-mf-cell" | {f} ! class="hi-tense-aspect-cell" rowspan=2 colspan=1 | {FUT} ! class="hi-mf-cell" | {m} ! class="hi-mf-cell" | {f} {presum_table}{subj_table} ! 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} ! class="hi-mf-cell" | {f} ! 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} ! class="hi-tense-aspect-cell" rowspan=1 colspan=1 | {POL} ! class="hi-mf-cell" | {mf} ! class="hi-sec-div" rowspan=1 colspan=100% | Habitual ! 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} ! class="hi-mf-cell" | {f} ! class="hi-tense-aspect-cell" rowspan=2 colspan=1 | {PST} ! class="hi-mf-cell" | {m} ! class="hi-mf-cell" | {f} ! 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} ! class="hi-mf-cell" | {f} ! 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} ! class="hi-mf-cell" | {f} ! 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} ! class="hi-mf-cell" | {f} ! 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} ! class="hi-mf-cell" | {f} ! class="hi-tense-aspect-cell" rowspan=2 colspan=1 | {PST} ! class="hi-mf-cell" | {m} ! class="hi-mf-cell" | {f} ! class="hi-tense-aspect-cell" rowspan=2 colspan=1 | {FUT} ! class="hi-mf-cell" | {m} ! class="hi-mf-cell" | {f} ! 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} ! class="hi-mf-cell" | {f} ! 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} ! class="hi-mf-cell" | {f} ! 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} ! class="hi-mf-cell" | {f} ! class="hi-sec-div" rowspan=1 colspan=100% | Progressive ! 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} ! class="hi-mf-cell" | {f} ! class="hi-tense-aspect-cell" rowspan=2 colspan=1 | {PST} ! class="hi-mf-cell" | {m} ! class="hi-mf-cell" | {f} ! class="hi-tense-aspect-cell" rowspan=2 colspan=1 | {FUT} ! class="hi-mf-cell" | {m} ! class="hi-mf-cell" | {f} ! 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} ! class="hi-mf-cell" | {f} ! 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} ! class="hi-mf-cell" | {f} ! 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} ! class="hi-mf-cell" | {f} {reversed_person_number_header}|{\cl}{notes_clause} ]=]
 * colspan=3 | {ind_perf_ms}
 * colspan=3 | {ind_perf_mp}
 * - class="hi-row-f"
 * colspan=3 | {ind_perf_fs}
 * colspan=3 | {ind_perf_fp}
 * - class="hi-row-m"
 * {ind_fut_1sm}
 * colspan=2 | {ind_fut_23sm}
 * {ind_fut_2pm}
 * {ind_fut_1pm}
 * {ind_fut_3pm}
 * - class="hi-row-f"
 * {ind_fut_1sf}
 * colspan=2 | {ind_fut_23sf}
 * {ind_fut_2pf}
 * {ind_fut_1pf}
 * {ind_fut_3pf}
 * - class="hi-row-m"
 * colspan=3 | {cfact_ms}
 * colspan=3 | {cfact_mp}
 * - class="hi-row-f"
 * colspan=3 | {cfact_fs}
 * colspan=3 | {cfact_fp}
 * {imp_reg_2s}
 * {imp_reg_2p}
 * {imp_reg_2p}
 * {imp_reg_2p}
 * {imp_reg_2p}
 * {imp_reg_2p}
 * {imp_pol_2s}
 * {imp_pol_2p}
 * {imp_pol_2p}
 * {imp_pol_2p}
 * {imp_pol_2p}
 * {imp_pol_2p}
 * - class="hi-row-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"
 * {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"
 * colspan=3 | {hab_ind_past_ms}
 * colspan=3 | {hab_ind_past_mp}
 * - class="hi-row-f"
 * colspan=3 | {hab_ind_past_fs}
 * colspan=3 | {hab_ind_past_fp}
 * - class="hi-row-m"
 * {hab_presum_1sm}
 * colspan=2 | {hab_presum_23sm}
 * {hab_presum_2pm}
 * {hab_presum_1pm}
 * {hab_presum_3pm}
 * - class="hi-row-f"
 * {hab_presum_1sf}
 * colspan=2 | {hab_presum_23sf}
 * {hab_presum_2pf}
 * {hab_presum_1pf}
 * {hab_presum_3pf}
 * - class="hi-row-m"
 * {hab_subj_1sm}
 * colspan=2 | {hab_subj_23sm}
 * {hab_subj_2pm}
 * {hab_subj_1pm}
 * {hab_subj_3pm}
 * - class="hi-row-f"
 * {hab_subj_1sf}
 * colspan=2 | {hab_subj_23sf}
 * {hab_subj_2pf}
 * {hab_subj_1pf}
 * {hab_subj_3pf}
 * - class="hi-row-m"
 * colspan=3 | {hab_cfact_ms}
 * colspan=3 | {hab_cfact_mp}
 * - class="hi-row-f"
 * colspan=3 | {hab_cfact_fs}
 * colspan=3 | {hab_cfact_fp}
 * {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"
 * {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"
 * colspan=3 | {pfv_ind_past_ms}
 * colspan=3 | {pfv_ind_past_mp}
 * - class="hi-row-f"
 * colspan=3 | {pfv_ind_past_fs}
 * colspan=3 | {pfv_ind_past_fp}
 * - class="hi-row-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"
 * {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"
 * {pfv_presum_1sm}
 * colspan=2 | {pfv_presum_23sm}
 * {pfv_presum_2pm}
 * {pfv_presum_1pm}
 * {pfv_presum_3pm}
 * - class="hi-row-f"
 * {pfv_presum_1sf}
 * colspan=2 | {pfv_presum_23sf}
 * {pfv_presum_2pf}
 * {pfv_presum_1pf}
 * {pfv_presum_3pf}
 * - class="hi-row-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"
 * {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"
 * colspan=3 | {pfv_cfact_ms}
 * colspan=3 | {pfv_cfact_mp}
 * - class="hi-row-f"
 * colspan=3 | {pfv_cfact_fs}
 * colspan=3 | {pfv_cfact_fp}
 * - class="hi-row-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"
 * {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"
 * colspan=3 | {prog_ind_past_ms}
 * colspan=3 | {prog_ind_past_mp}
 * - class="hi-row-f"
 * colspan=3 | {prog_ind_past_fs}
 * colspan=3 | {prog_ind_past_fp}
 * - class="hi-row-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"
 * {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"
 * {prog_presum_1sm}
 * colspan=2 | {prog_presum_23sm}
 * {prog_presum_2pm}
 * {prog_presum_1pm}
 * {prog_presum_3pm}
 * - class="hi-row-f"
 * {prog_presum_1sf}
 * colspan=2 | {prog_presum_23sf}
 * {prog_presum_2pf}
 * {prog_presum_1pf}
 * {prog_presum_3pf}
 * - class="hi-row-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"
 * {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"
 * colspan=3 | {prog_cfact_ms}
 * colspan=3 | {prog_cfact_mp}
 * - class="hi-row-f"
 * colspan=3 | {prog_cfact_fs}
 * colspan=3 | {prog_cfact_fp}

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} ! class="hi-tense-aspect-cell" colspan=1 | {IMPF} ! 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"
 * {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-tense-aspect-cell" rowspan=4 colspan=1 | Indicative ]=]
 * - class="hi-row-m"

local presum_table = [=[ ! 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} ! class="hi-mf-cell" | {f} ]=]
 * - class="hi-row-m"
 * {presum_1sm}
 * colspan=2 | {presum_23sm}
 * {presum_2pm}
 * {presum_1pm}
 * {presum_3pm}
 * - class="hi-row-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 = [===[ {footnote} ]===]

local forms = alternant_multiword_spec.forms

local function make_gender_abbr(title, text) return ' ' .. text .. ' '	end local function make_tense_aspect_abbr(title, text) local template = [=[ {text} ]=] 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 .. " " .. 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 FUT") forms.PRS_PST = make_tense_aspect_abbr("Present/Past", "PRS PST") forms.PRS_PST_FUT = make_tense_aspect_abbr("Present/Past/Future", "PRS PST 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: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, "") 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. 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

title: Module:pa-verb


text:
pragliwy

Etymology
From.

Adjective

 * 1) greedy, avaricious, covetous

title: pragliwy


text:
Module:User:Benwing2/category tree/poscatboiler/data/scripts

local raw_categories = {} local raw_handlers = {}

-- A list of Unicode blocks to which the characters of the script or scripts belong is created by this module -- and displayed in script category pages. local blocks_submodule = "Module:User:Benwing2/category tree/poscatboiler/data/scripts/blocks"

- --                                                                        -- --                               SCRIPT LABELS                             -- --                                                                        -- -

--[=[ The following values are recognized for each script label:

'description' A plain English description for the label. Special template substitutions are recognized; see below. 'umbrella_parents' A table listing one or more parent categories of the umbrella category 'LABELS by script' for this label. The format is as for regular raw categories (see Module:category tree/poscatboiler/data/documentation). 'umbrella_breadcrumb' The breadcrumb to use in the umbrella category 'LABELS by script'. Defaults to "by script". 'catfix' Same as the 'catfix' parameter for regular raw categories (see Module:category tree/poscatboiler/data/documentation). This specifies a language code to use to ensure that pages in the category are displayed in the right font and linked appropriately. If this is set, the 'catfix_sc' parameter will effectively be set with the script code in question.

Special template-like parameters can be used inside the 'description' field (as well as in the 'root_description', 'root_intro' and 'root_additional' variable values initialized below). These are replaced by the equivalent text.

multiple aliases (e.g. 'tt-Arab', 'ur-Arab', 'ku-Arab', etc.). ]=]
 * Script code.
 * A comma-separated list of all the alias codes for this script. This applies especially to Arabic, which has
 * The value "s" if lists more than one code, otherwise an empty string.
 * The name of the script that the category belongs to.
 * The name of the script's main category, which adds "script" to the regular name.
 * Same as for Morse code, otherwise adds "the" before.
 * The Wikipedia article for the script (if it is present in the language's data file), or else.

local script_labels = {}

script_labels["characters"] = { description = "All characters from, and their possible variations, such as versions with diacritics and combinations recognized as single characters in any language.", umbrella_parents = {"Fundamental"}, umbrella_breadcrumb = "Characters by script", catfix = "mul", }

script_labels["appendices"] = { description = "Appendices about .", umbrella_parents = {"Category:Appendices"}, }

script_labels["languages"] = { description = "Languages that use .", umbrella_parents = {"All languages"}, }

script_labels["templates"] = { description = "Templates with predefined contents for .", umbrella_parents = {"Templates"}, }

script_labels["modules"] = { description = "Modules with scripts for .", umbrella_parents = {"Modules"}, }

- --                                                                        -- --                              RAW CATEGORIES                             -- --                                                                        -- -

raw_categories["All scripts"] = { description = "This category contains the categories for every script (writing system) on Wiktionary.", additional = "See List of scripts for a full list.", parents = {"Fundamental"}, }

-- Types of writing systems listed in Module:writing systems/data. raw_categories["Scripts by type"] = { description = "Scripts classified by how they represent words.", parents = , }

raw_categories["Alphabetic writing systems"] = { description = "Scripts whose symbols represent individual speech sounds.", parents = {"Scripts by type"}, }

raw_categories["Abjads"] = { description = "Scripts whose basic symbols represent consonants. Some of these are impure abjads, which have letters for some vowels.", parents = {"Scripts by type"}, }

raw_categories["Abugidas"] = { description = "Scripts whose symbols represent consonant and vowel combinations. Symbols representing the same consonant combined with different vowels are for the most part similar in form.", parents = {"Scripts by type"}, }

raw_categories["Logographic writing systems"] = { description = "Scripts whose symbols represent individual words.", parents = {"Scripts by type"}, }

raw_categories["Pictographic writing systems"] = { description = "Scripts whose symbols represent individual words by using symbols that resemble the physical objects to which those words refer.", parents = {"Scripts by type"}, }

raw_categories["Syllabaries"] = { description = "Scripts whose symbols represent consonant and vowel combinations. Symbols representing the same consonant combined with different vowels are for the most part different in form.", parents = {"Scripts by type"}, }

for script_label, obj in pairs(script_labels) do raw_categories[mw.getContentLanguage:ucfirst(script_label) .. " by script"] = { description = "Categories with " .. script_label .. " of various specific scripts.", breadcrumb = obj.umbrella_breadcrumb or "by script", parents = obj.umbrella_parents, } end

- --                                                                        -- --                                RAW HANDLERS                             -- --                                                                        -- -

-- Intro text for "root" categories such as. Template substitutions are as described above. local root_intro = [=[

]=]

-- Short description for "root" categories such as. Template substitutions are as described above. local root_description = "This is the main category of the ."

-- Additional description text for "root" categories such as. Template substitutions are as described above. local root_additional = [=[Information about may be available at Appendix:.

In various places at Wiktionary, is represented by the code .]=]

-- Replace template notation { – } with variables. local function substitute_template_refs(text, sc) local categoryName = sc:getCategoryName local scname = sc:getCanonicalName local codes = {} for code, data in pairs(mw.loadData("Module:scripts/data")) do		if data.canonicalName == scname then table.insert(codes, "" .. code .. "") end end if codes[2] then table.sort(			codes,			-- Four-letter codes have length 10, because they are bolded: Latn.			function(code1, code2)				if #code1 == 10 then					if #code2 == 10 then						return code1 < code2					else						return true					end				else					if #code2 == 10 then						return false -- four-letter codes before other codes					else						return code1 < code2					end				end			end) end local content = { code = sc:getCode, codesplural = codes[2] and "s" or "", codes = table.concat(codes, ", "), scname = scname, sccat = categoryName, scprosename = categoryName:find("code") and categoryName or "the " .. categoryName, Wikipedia = sc:getWikipediaArticle, }	text = string.gsub(		text,		"}",		function (parameter)			return content[parameter] or error("No value for script category parameter '" .. parameter .. "'.")		end) return text end

local function get_root_additional(additional, sc) local ret = { additional } local systems = sc:getSystems for _, system in ipairs(systems) do		table.insert(ret, "\n\nThe script is ") if mw.ustring.sub(system:getCanonicalName, 1, 1) == "a" then table.insert(ret, "an ") else table.insert(ret, "a ") end local singular = system:getCategoryName singular = mw.getContentLanguage:lcfirst(singular) singular = mw.ustring.gsub(singular, "ies$", "y") singular = mw.ustring.gsub(singular, "s$", "") table.insert(ret, singular .. ".") end local blocks = require(blocks_submodule) .print_blocks_by_canonical_name(sc:getCanonicalName) if blocks then table.insert(ret, "\n") table.insert(ret, blocks) end

return substitute_template_refs(table.concat(ret), sc) end

local function get_script_obj(script) local scriptname = script:gsub(" script$", "") return require("Module:scripts").getByCanonicalName(scriptname) or -- vs. name of script = "undetermined" require("Module:scripts").getByCanonicalName(mw.ustring.lower(scriptname)) end

local scripts_without_script_in_category = { -- FIXME, consider checking all scripts for names without 'script' in them. ["Morse code"] = true, ["Flag semaphore"] = true, }

-- Handler for 'SCRIPT script' e.g. as well as  and -- . table.insert(raw_handlers, function(data)	if not data.category:match("^(.+ script)$") and not scripts_without_script_in_category[data.category] then		return nil	end	local sc = get_script_obj(data.category)	if not sc then		return nil	end	-- Compute parents.	local parents = {}	local systems = sc:getSystems	for _, system in ipairs(systems) do		table.insert(parents, system:getCategoryName)	end	table.insert(parents, "All scripts")

-- Compute (extra) children. local children = {} for script_label, _ in pairs(script_labels) do table.insert(children, data.category .. " " .. script_label) end

return { intro = substitute_template_refs(root_intro, sc), description = substitute_template_refs(root_description, sc), additional = get_root_additional(root_additional, sc), parents = parents, breadcrumb = sc:getCategoryName, extra_children = children, can_be_empty = true, } end)

-- Handler for 'SCRIPT script LABELS' e.g. as well as  and -- . table.insert(raw_handlers, function(data)	local script, label	for lab, _ in pairs(script_labels) do		-- FIXME, if we add script labels with a hyphen in them we'll have to escape the hyphen		-- in the following patterns.		script, label = data.category:match("^(.+ script) (" .. lab .. ")$")		if script then			break		end		-- Check for e.g. 'Morse code characters' or 'Flag semaphore templates'.		script, label = data.category:match("^(.+) (" .. lab .. ")$")		if script then			if scripts_without_script_in_category[script] then				break			else				script = nil			end		end	end	if not script then		return nil	end

local sc = get_script_obj(script) if not sc then return nil end local label_obj = script_labels[label] -- Compute description. local desc = substitute_template_refs(label_obj.description, sc)

-- Compute parents. local parents = { {name = script, sort = label}, -- umbrella category mw.getContentLanguage:ucfirst(label) .. " by script", }

return { description = substitute_template_refs(label_obj.description, sc), parents = parents, breadcrumb = label, catfix = label_obj.catfix, catfix_sc = label_obj.catfix and sc:getCode, } end)

return {RAW_CATEGORIES = raw_categories, RAW_HANDLERS = raw_handlers}


text:
Module:User:Benwing2/category tree/poscatboiler/data/scripts/blocks

local export = {}

local fun = require "Module:fun" local Array = require "Module:array"

local function compare_script_codes(code1, code2) -- Sort four-letter codes and non-four-letter codes alphabetically. if (#code1 == 4) == (#code2 == 4) then return code1 < code2 -- Put four-letter codes before non-four-letter codes. else return #code1 == 4 end end

local function sort_scripts(script_codes) table.sort(script_codes, compare_script_codes) return script_codes end

local block_data = require "Module:Unicode data/blocks"

-- Add position of range in the array of blocks to the range tables. for i, range in ipairs(block_data) do	range[4] = i end

-- Binary search, to avoid iterating over entire table in order to look up the -- higher codepoints. local floor = math.floor local function binary_lookup_block(codepoint) local iStart, iEnd = 1, block_data.length or #block_data while iStart <= iEnd do		local iMid = floor((iStart + iEnd) / 2) local range = block_data[iMid] if codepoint < range[1] then iEnd = iMid - 1 elseif codepoint <= range[2] then return range else iStart = iMid + 1 end end error(string.format("No block found for codepoint U+%04X.", codepoint)) end

function export.lookup_block(char) local codepoint = mw.ustring.codepoint(char) local range = binary_lookup_block(codepoint) if range then return range else error(string.format("No block found for U+%04X (%s).", codepoint, mw.ustring.char(codepoint))) end end

function export.get_singles_and_ranges(pattern) local ranges, singles = {}, {} pattern = mw.ustring.gsub(		pattern,		"(.)%-(.)",		function(lower, higher)			table.insert(ranges, { lower, higher })			return ""		end) for character in mw.ustring.gmatch(pattern, ".") do		table.insert(singles, character) end return singles, ranges end

function export.get_block_arrays(pattern) local singles, ranges = export.get_singles_and_ranges(pattern) local blocks = {} for _, character in ipairs(singles) do		blocks[export.lookup_block(character)] = true end for _, range in ipairs(ranges) do		local block_array1, block_array2 = export.lookup_block(range[1]), export.lookup_block(range[2]) for i = block_array1[4], block_array2[4] do			blocks[block_data[i]] = true end end return Array.keysToList(blocks, function (block1, block2) return block1[4] < block2[4] end) end

local function format_block_info(block_array) return ("%s (U+%04X–U+%04X)"):format(block_array[3], block_array[3], block_array[1], block_array[2]) end

function export.print_blocks(block_arrays, prefix) table.sort(		block_arrays,		function (block_array1, block_array2)			return block_array1[1] < block_array2[1]		end) local block_names = fun.map(		function (block_array)			return "* " .. format_block_info(block_array)		end,		block_arrays) if prefix then table.insert(block_names, 1, prefix) end return table.concat(block_names, "\n") end

function export.print_blocks_by_canonical_name(script_name) if type(script_name) ~= "string" then error("script_name should be a string, not " .. type(script_name) .. ".") end local scripts_by_pattern = {} setmetatable(		scripts_by_pattern,		{			__index = function(self, key)				if key == nil then					return				end				local val = Array				self[key] = val				return val			end		}) local count = 0 for code, data in pairs(mw.loadData("Module:scripts/data")) do		if data.canonicalName == script_name and data.characters then count = count + 1 scripts_by_pattern[data.characters]:insert(code) end end if not next(scripts_by_pattern) then return nil end local block_arrays_by_scripts = {} local block_count = 0 -- Construct arrays of blocks and count the blocks. for pattern, scripts in pairs(scripts_by_pattern) do		local array = export.get_block_arrays(pattern) block_arrays_by_scripts[sort_scripts(scripts)] = array block_count = block_count + #array end require("Module:debug").track{ "scriptcatboiler/blocks/" .. count, "scriptcatboiler/blocks/" .. block_count }	if count == 1 and block_count == 1 then local scripts, block_arrays = next(block_arrays_by_scripts) if scripts[2] or block_arrays[2] then error("More than one script or more than one block. Something is wrong.") end return ("The characters of  are found in the Unicode block %s") :format(scripts[1], format_block_info(block_arrays[1])) else local collapsible1 = '{|\n' local collapsible3 = ' ' return '{| class="mw-collapsible mw-collapsed wikitable" style="width: 30em;"\n|+ style="font-weight: normal;" | ' .. "'''Unicode block" .. (block_count > 1 and "s" or "") .. " for characters in " .. (count > 1 and "these scripts" or "this script") .. "'''\n|\n" .. table.concat(				fun.mapIter( function(block_arrays, scripts) return export.print_blocks(							block_arrays,							"; Block" .. (block_arrays[2] and "s" or "") .. " in "								.. table.concat( fun.map(										function (script_code)											return " "										end,										scripts), ", "))					end, require("Module:table").sortedPairs(						block_arrays_by_scripts,						function(script_array1, script_array2)							return compare_script_codes(script_array1[1], script_array2[1])						end)),				"\n") .. '\n|}' end end

-- For testing. function export.print_blocks_by_canonical_name_template(frame) return export.print_blocks_by_canonical_name(frame.args[1]) end

return export


text:
さきっちょ

Noun

 * 1) tip; ending

title: さきっちょ


text: 先っちょ

title: 先っちょ


text:
អូតូរុត

Etymology
Borrowed from.

Noun

 * 1) freeway; highway

title: អូតូរុត


text:
கயமை

Etymology
From.

Noun

 * 1) inferiority, baseness, despicableness

title: கயமை


text:
کلاه‌خود

Etymology
From.

Noun

 * 1) a Devil mask
 * 2) any war helmet in general

title: کلاه‌خود


text:
Module:category tree/poscatboiler/data/scripts

local raw_categories = {} local raw_handlers = {}

-- A list of Unicode blocks to which the characters of the script or scripts belong is created by this module -- and displayed in script category pages. local blocks_submodule = "Module:category tree/poscatboiler/data/scripts/blocks"

- --                                                                        -- --                               SCRIPT LABELS                             -- --                                                                        -- -

--[=[ The following values are recognized for each script label:

'description' A plain English description for the label. Special template substitutions are recognized; see below. 'umbrella_parents' A table listing one or more parent categories of the umbrella category 'LABELS by script' for this label. The format is as for regular raw categories (see Module:category tree/poscatboiler/data/documentation). 'umbrella_breadcrumb' The breadcrumb to use in the umbrella category 'LABELS by script'. Defaults to "by script". 'catfix' Same as the 'catfix' parameter for regular raw categories (see Module:category tree/poscatboiler/data/documentation). This specifies a language code to use to ensure that pages in the category are displayed in the right font and linked appropriately. If this is set, the 'catfix_sc' parameter will effectively be set with the script code in question.

Special template-like parameters can be used inside the 'description' field (as well as in the 'root_description', 'root_topright' and 'root_additional' variable values initialized below). These are replaced by the equivalent text.

multiple aliases (e.g. 'tt-Arab', 'ur-Arab', 'ku-Arab', etc.). ]=]
 * Script code.
 * A comma-separated list of all the alias codes for this script. This applies especially to Arabic, which has
 * The value "s" if lists more than one code, otherwise an empty string.
 * The name of the script that the category belongs to.
 * The name of the script's main category, which adds "script" to the capitalized regular name.
 * The display form of the script, which adds "script" to the regular name.
 * Same as for Morse code and flag semaphore, otherwise adds "the" before.
 * The Wikipedia article for the script (if it is present in the language's data file), or else.

local script_labels = {}

script_labels["characters"] = { description = "All characters from, and their possible variations, such as versions with diacritics and combinations recognized as single characters in any language.", umbrella_parents = {"Fundamental"}, umbrella_breadcrumb = "Characters by script", catfix = "mul", }

script_labels["appendices"] = { description = "Appendices about .", umbrella_parents = {"Category:Appendices"}, }

script_labels["languages"] = { description = "Languages that use .", umbrella_parents = {"All languages"}, }

script_labels["templates"] = { description = "Templates with predefined contents for .", umbrella_parents = {"Templates"}, }

script_labels["modules"] = { description = "Modules that implement functionality for .", umbrella_parents = {"Modules"}, }

script_labels["data modules"] = { description = "Modules that contain data related to .", umbrella_parents = {"Data modules"}, }

- --                                                                        -- --                              RAW CATEGORIES                             -- --                                                                        -- -

raw_categories["All scripts"] = { description = "This category contains the categories for every script (writing system) on Wiktionary.", additional = "See List of scripts for a full list.", parents = {"Fundamental"}, }

-- Types of writing systems listed in Module:writing systems/data. raw_categories["Scripts by type"] = { description = "Scripts classified by how they represent words.", parents = , breadcrumb = "by type", }

raw_categories["Alphabetic writing systems"] = { description = "Scripts whose symbols represent individual speech sounds.", parents = {"Scripts by type"}, }

raw_categories["Abjads"] = { description = "Scripts whose basic symbols represent consonants. Some of these are impure abjads, which have letters for some vowels.", parents = {"Scripts by type"}, }

raw_categories["Abugidas"] = { description = "Scripts whose symbols represent consonant and vowel combinations. Symbols representing the same consonant combined with different vowels are for the most part similar in form.", parents = {"Scripts by type"}, }

raw_categories["Logographic writing systems"] = { description = "Scripts whose symbols represent individual words.", parents = {"Scripts by type"}, }

raw_categories["Pictographic writing systems"] = { description = "Scripts whose symbols represent individual words by using symbols that resemble the physical objects to which those words refer.", parents = {"Scripts by type"}, }

raw_categories["Semisyllabaries"] = { description = "Scripts which are a combination of an alphabet and a syllbary.", parents = {"Scripts by type"}, }

raw_categories["Syllabaries"] = { description = "Scripts whose symbols represent consonant and vowel combinations. Symbols representing the same consonant combined with different vowels are for the most part different in form.", parents = {"Scripts by type"}, }

for script_label, obj in pairs(script_labels) do raw_categories[mw.getContentLanguage:ucfirst(script_label) .. " by script"] = { description = "Categories with " .. script_label .. " of various specific scripts.", breadcrumb = obj.umbrella_breadcrumb or "by script", parents = obj.umbrella_parents, } end

- --                                                                        -- --                                RAW HANDLERS                             -- --                                                                        -- -

-- Intro text for "root" categories such as. Template substitutions are as described above. local root_topright = [=[

]=]

-- Short description for "root" categories such as. Template substitutions are as described above. local root_description = "This is the main category of ."

-- Additional description text for "root" categories such as. Template substitutions are as described above. local root_additional = [=[Information about may be available at Appendix:.

In various places at Wiktionary, is represented by the code .]=]

-- Replace template notation { – } with variables. local function substitute_template_refs(text, sc) local displayForm = sc:getDisplayForm local scname = sc:getCanonicalName local codes = {} for code, data in pairs(mw.loadData("Module:scripts/data")) do		if data[1] == scname then table.insert(codes, "" .. code .. "") end end if codes[2] then table.sort(			codes,			-- Four-letter codes have length 10, because they are bolded: Latn.			function(code1, code2)				if #code1 == 10 then					if #code2 == 10 then						return code1 < code2					else						return true					end				else					if #code2 == 10 then						return false -- four-letter codes before other codes					else						return code1 < code2					end				end			end) end local content = { code = sc:getCode, codesplural = codes[2] and "s" or "", codes = table.concat(codes, ", "), scname = scname, sccat = sc:getCategoryName, scdisp = displayForm, scprosename = (displayForm:find("code") or displayForm:find("semaphore")) and displayForm or "the " .. displayForm, Wikipedia = sc:getWikipediaArticle, }	text = string.gsub(		text,		"}",		function (parameter)			return content[parameter] or error("No value for script category parameter '" .. parameter .. "'.")		end) return text end

local function get_root_additional(additional, sc) local ret = { additional } local systems = sc:getSystems for _, system in ipairs(systems) do		table.insert(ret, "\n\nThe script is ") if mw.ustring.sub(system:getCanonicalName, 1, 1) == "a" then table.insert(ret, "an ") else table.insert(ret, "a ") end local singular = system:getCategoryName singular = mw.getContentLanguage:lcfirst(singular) singular = mw.ustring.gsub(singular, "ies$", "y") singular = mw.ustring.gsub(singular, "s$", "") table.insert(ret, singular .. ".") end local blocks = require(blocks_submodule) .print_blocks_by_canonical_name(sc:getCanonicalName) if blocks then table.insert(ret, "\n") table.insert(ret, blocks) end

return substitute_template_refs(table.concat(ret), sc) end

local function get_script_obj(script) local scriptname = script:gsub(" script$", "") return require("Module:scripts").getByCanonicalName(scriptname) or -- vs. name of script = "undetermined" require("Module:scripts").getByCanonicalName(mw.ustring.lower(scriptname)) end

local scripts_without_script_in_category = { -- FIXME, consider checking all scripts for names without 'script' in them. ["Clear Script"] = true, ["Morse code"] = true, ["Flag semaphore"] = true, }

-- Handler for 'SCRIPT script' e.g. as well as  and -- . table.insert(raw_handlers, function(data)	if not data.category:match("^(.+ script)$") and not scripts_without_script_in_category[data.category] then		return nil	end	local sc = get_script_obj(data.category)	if not sc then		return nil	end	-- Compute parents.	local parents = {}	local systems = sc:getSystems	for _, system in ipairs(systems) do		table.insert(parents, system:getCategoryName)	end	table.insert(parents, "All scripts")

-- Compute (extra) children. local children = {} for script_label, _ in pairs(script_labels) do table.insert(children, data.category .. " " .. script_label) end

return { topright = substitute_template_refs(root_topright, sc), description = substitute_template_refs(root_description, sc), additional = get_root_additional(root_additional, sc), parents = parents, breadcrumb = sc:getCanonicalName, extra_children = children, can_be_empty = true, } end)

-- Handler for 'SCRIPT script LABELS' e.g. as well as  and -- . table.insert(raw_handlers, function(data)	local script, label	for lab, _ in pairs(script_labels) do		-- FIXME, if we add script labels with a hyphen in them we'll have to escape the hyphen		-- in the following patterns.		script, label = data.category:match("^(.+ script) (" .. lab .. ")$")		if script then			break		end		-- Check for e.g. 'Morse code characters' or 'Flag semaphore templates'.		script, label = data.category:match("^(.+) (" .. lab .. ")$")		if script then			if scripts_without_script_in_category[script] then				break			else				script = nil			end		end	end	if not script then		return nil	end

local sc = get_script_obj(script) if not sc then return nil end local label_obj = script_labels[label] -- Compute description. local desc = substitute_template_refs(label_obj.description, sc)

-- Compute parents. local parents = { {name = script, sort = label}, -- umbrella category mw.getContentLanguage:ucfirst(label) .. " by script", }

return { description = substitute_template_refs(label_obj.description, sc), parents = parents, breadcrumb = label, catfix = label_obj.catfix, catfix_sc = label_obj.catfix and sc:getCode, } end)

return {RAW_CATEGORIES = raw_categories, RAW_HANDLERS = raw_handlers}


text: Wúhú

title: Wúhú


text:
samāsa

Etymology
.

Noun

 * 1) compound, combination

title: samāsa


text:
کلاه‌برداری

Etymology
From.

Noun

 * 1) fraud

Related terms
,

title: کلاه‌برداری


text:
Reconstruction:Proto-Tsezian/mɔq’ʰu

Etymology
Cognate with 🇨🇬.

Noun

 * 1)  tear

Descendants

 * East Tsezian:
 * Bezhta:
 * Bezhta Bezhta:
 * Khoshar-Khota Bezhta:
 * Tlyadal Bezhta:
 * West Tsezian:
 * Khvarshi-Tsez:
 * Khvarshi:
 * Inkhokwari Khvarshi:
 * Khwarshi Khvarshi:
 * Kwantlada Khvarshi:
 * Tsez:
 * Kidero Tsez:
 * Asakh Tsez:
 * Kidero Tsez:
 * Asakh Tsez:

title: Reconstruction:Proto-Tsezian/mɔq’ʰu


text:
𑀲𑀫𑀸𑀲

Etymology
. Cognate with 🇨🇬.

Noun

 * 1) abridgement, conciseness
 * 2)  compound

title: 𑀲𑀫𑀸𑀲


text: সমাস

title: সমাস


text:
അവിയൽ

Noun

 * 1) A green vegetable curry that mixes vegetables (including, but not limited to drumsticks, elephant yam, carrot, and beans) with coconut, coconut oil, and curry leaves.

title: അവിയൽ


text:
말나식

Etymology
, ultimately from.

Noun

 * 1)  : the seventh of the, characterized by incessant mental activity in the mind, creating the illusion of the ego

title: 말나식


text:
ավտոմայրուղի

Noun

 * 1) freeway

title: ավտոմայրուղի


text:
Talk:അവിയൽ

What do you like to put in your aviyal? Consider adding images to showcase different styles of aviyal.

title: Talk:അവിയൽ


text:
podsłuch

Etymology
.

Noun

 * 1) bug, wiretap
 * 2) bugging
 * 1) bugging

title: podsłuch


text:
afeld

Etymology
From, equivalent to.

Adverb

 * 1) In the fields, out of doors, abroad

title: afeld


text:
കളരിപ്പയറ്റ്

Noun

 * 1) A martial art indigenous to Kerala, which progresses from unarmed to armed combat. Weapons include short sticks, a sword and shield, and a curved flexible sword mastered at the end of training.

title: കളരിപ്പയറ്റ്


text:
Talk:കളരിപ്പയറ്റ്

If you can read it, consider reading http://www.keralaculture.org/malayalam/kalaripayattu/84 to learn about the art, and pick up extra vocabulary that may be worth entering. GoateeBoi (talk) 04:20, 29 December 2020 (UTC)

What's the second root in kalari+payattu?

title: Talk:കളരിപ്പയറ്റ്


text: Template:cau-tsz-noun

title: Template:cau-tsz-noun


text:
ഭാരം

Etymology
.

Noun

 * 1) weight
 * 2) burden
 * 1) burden

title: ഭാരം


text:
hit a lick

Etymology
In the basic meaning a reference to liquor store robbery.

Verb

 * 1)  To earn a large sum of money in a short amount of time, usually illegally.

title: hit a lick


text:
കഷ്ടം

Etymology
.

Noun

 * 1) suffering
 * 2) tough situation
 * 3) difficulty
 * 4) pity

title: കഷ്ടം


text: Category:Proto-Tsezian class 2 nouns

title: Category:Proto-Tsezian class 2 nouns


text: Category:Proto-Tsezian nouns by class

title: Category:Proto-Tsezian nouns by class


text:
아뢰야식

Etymology
, ultimately from.

Noun

 * 1)  storehouse consciousness or , the last of the, the ultimate source of mind and existence

title: 아뢰야식


text: Category:Requests for gender in Proto-Tsezian entries


text:
പ്രക്രത

Noun

 * 1) human nature

title: പ്രക്രത


text: Category:English terms suffixed with -dronic


text: Category:Guajajára adverbs

title: Category:Guajajára adverbs


text: Category:Aari terms derived from Proto-Aroid


text: Category:Aari terms inherited from Proto-Aroid


text: Category:Eskayan cardinal numbers

title: Category:Eskayan cardinal numbers


text: Category:Hindi terms derived from the Proto-Indo-Aryan root *kar-


text: Category:Hindi terms derived from the Proto-Indo-Iranian root *kar-


text: Category:Hindi terms derived from the Sanskrit root अलंकृ


text: Category:Korean terms derived from Late Old Korean


text: Category:Korean terms inherited from Late Old Korean


text: 末那識

title: 末那識


text: Category:Sanskrit terms derived from the Proto-Indo-European root *nem-


text: Category:Sanskrit terms derived from the Proto-Indo-European root *reg-


text: Category:zh:Arthurian mythology

title: Category:zh:Arthurian mythology


text: Category:Dutch deverbals

title: Category:Dutch deverbals


text: Category:Eskayan palindromes

title: Category:Eskayan palindromes


text: Category:Foreign words of the day in Northern Kurdish


text: Category:Guajajára verbs

title: Category:Guajajára verbs


text: Category:Hindi terms derived from the Proto-Indo-European root *reg-


text: Category:Hindi terms derived from the Sanskrit root रञ्ज्


text: Category:South Slavey compound terms

title: Category:South Slavey compound terms


text: Category:Ainu copulative verbs

title: Category:Ainu copulative verbs


text: Category:Central Atlas Tamazight terms prefixed with ⴰⵏ-


text: Category:Central Atlas Tamazight terms suffixed with -ⴰⵏ


text: Category:English terms prefixed with coccido-


text: Category:English terms prefixed with detrito-


text: Category:English terms prefixed with helmintho-


text: Category:English terms prefixed with herbi-


text: Category:English terms prefixed with licheno-


text:
സഹോദരൻ

Etymology
.

Noun

 * 1)  brother

title: സഹോദരൻ


text: Category:Guajajára multiword terms

title: Category:Guajajára multiword terms


text: Category:Guajajára particles

title: Category:Guajajára particles


text: Category:Hindi terms derived from the Proto-Indo-European root *ǵem-


text: Category:Hindi terms derived from the Sanskrit root उन्नम्


text: Category:Hindi terms derived from the Sanskrit root क्रम्


text: Category:Indonesian humorous terms

title: Category:Indonesian humorous terms


text: Category:Proto-Tsezian class 3 nouns

title: Category:Proto-Tsezian class 3 nouns


text:
കളരി

Noun

 * 1) A place, like a dojo, where the martial art  is taught, traditionally with an earthen floor, hung weapons, and a shrine.
 * 2) kalarippayattu; the traditional martial art of Kerala
 * 3) gymnasium
 * 4) training or practicing center
 * 5)  school

title: കളരി


text: Category:Massachusett compound terms

title: Category:Massachusett compound terms


text: Category:Romanian terms borrowed from Old East Slavic


text: Category:Romanian terms derived from Proto-Indo-Iranian


text: Category:Sanskrit terms derived from Middle Persian


text: Category:Sanskrit terms derived from the Proto-Indo-Aryan root *kar-


text: Category:Sanskrit terms derived from the Proto-Indo-Iranian root *kar-


text: Category:South Slavey terms derived from Southwestern Iranian languages


text: Category:Terms derived from the Proto-Indo-Iranian root *man-


text:
通常運転

Noun

 * 1)  normal operation
 * 2)  business as usual; same old same old
 * 1)  business as usual; same old same old

title: 通常運転


text:
ലോഹം

Etymology
From.

Noun

 * 1) metal

title: ലോഹം


text: Category:sh:Bars

title: Category:sh:Bars


text: Category:tft:Face

title: Category:tft:Face


text: Category:vi:Political subdivisions of France


text: Category:zh:Batangas, Philippines

title: Category:zh:Batangas, Philippines


text: Category:Armenian terms coined by Vachagan Sargsyan


text: Category:Bashkir terms suffixed with -ла


text: Category:Breton female given names from Celtic languages


text: Category:Breton given names from Welsh

title: Category:Breton given names from Welsh


text: Category:Burmese semantic loans

title: Category:Burmese semantic loans


text: Category:Chamorro terms derived from Malayo-Chamic languages


text: Category:Classical Syriac nonstandard forms


text: Category:Coptic diacritical marks

title: Category:Coptic diacritical marks


text: Category:Dutch terms derived from Mandinka


text: Category:Proto-Tsezian class 4 nouns

title: Category:Proto-Tsezian class 4 nouns


text: Category:English terms derived from the Proto-Indo-European root *-lós


text: Category:English terms derived from the Proto-Indo-European root *temh₁-


text: Category:English terms derived from the Proto-Indo-European root *ḱwes-


text: Category:English terms derived from the Proto-Indo-European word *kʷetwóres


text: Category:English terms interfixed with -pris-


text:
നാളെ

Etymology
Cognate with 🇨🇬, 🇨🇬. Related to 🇨🇬.

Noun

 * 1) tomorrow

Adverb

 * 1) tomorrow

title: നാളെ


text: Category:English terms prefixed with acari-


text: Category:English terms prefixed with ona-


text: Category:English terms prefixed with ral-


text: Category:English terms prefixed with uli-


text: Category:English terms suffixed with -coely


text: Category:English terms suffixed with -phloic


text: Category:Eskayan interjections

title: Category:Eskayan interjections


text: Category:Eskayan multiword terms

title: Category:Eskayan multiword terms


text: Category:French surnames from Afroasiatic languages


text: Category:Garo terms derived from Proto-Bodo-Garo


text: Category:Garo terms inherited from Proto-Bodo-Garo


text: Category:Guajajára numerals

title: Category:Guajajára numerals


text: Category:Guajajára terms derived from Old Tupi


text: Category:Hawaiian Creole terms derived from Eastern Malayo-Polynesian languages


text: Category:Hebrew terms belonging to the root א־ח־ס־ן


text: Category:Hebrew terms belonging to the root נ־ו־ט


text: Category:Hindi terms derived from the BMAC substrate


text: Category:Hindi terms derived from the Proto-Indo-European root *ḱwes-


text: Category:Hindi terms derived from the Sanskrit root आहृ


text: Category:Hindi terms derived from the Sanskrit root उपस्था


text: Category:Hindi terms derived from the Sanskrit root खाद्


text: Category:Hindi terms derived from the Sanskrit root चल्


text: Category:Hindi terms derived from the Sanskrit root पद्


text: Category:Hindi terms derived from the Sanskrit root भज्


text: Category:Hindi terms derived from the Sanskrit root श्वस्


text:
ഇന്നലെ

Etymology
.

Noun

 * 1) yesterday

Adverb

 * 1) yesterday

title: ഇന്നലെ


text: Category:Hindi terms derived from the Sanskrit root सम्पद्


text: Category:Hindi terms derived from the Sanskrit root स्था


text:
やわはだ

Noun

 * 1) soft skin

title: やわはだ


text: Category:Hindi terms derived from the Sanskrit root हृ


text: Category:Hunzib terms derived from East Slavic languages


text: Category:Icelandic class 7 strong verbs

title: Category:Icelandic class 7 strong verbs


text: Category:Indonesian semantic loans from Hebrew


text: Category:Indonesian semantic loans from Minangkabau


text: Category:Indonesian terms calqued from Swedish


text: やわ肌

title: やわ肌


text: Category:Japanese kanji read as めばえる

title: Category:Japanese kanji read as めばえる


text: 柔肌

title: 柔肌


text: Category:Japanese kanji with historical on reading つ


text: Category:Japanese kanji with historical reading はつ


text: Category:Japanese kanji with historical reading ばち


text: Category:Japanese kanji with historical reading ばつ


text: Category:Japanese kanji with historical reading ぼち


text: Category:Japanese terms derived from Borneo-Philippines languages


text:
おねむ

Noun

 * 1)  sleepiness
 * 2)  sleep

title: おねむ


text: Category:Japanese terms suffixed with なさい


text: Category:Japanese terms suffixed with ぬ

title: Category:Japanese terms suffixed with ぬ


text: Category:Jeju verbs by inflection type

title: Category:Jeju verbs by inflection type


text:
ചിങ്ങം

Etymology
.

Noun

 * 1) a traditional month roughly corresponding to August-September
 * 2)  lion, leo

title: ചിങ്ങം


text: Category:Ladin clippings

title: Category:Ladin clippings


text: Category:Latin terms derived from the Proto-Indo-European root *bʰel-


text:
കന്നി

Etymology
.

Noun

 * 1) A traditional month roughly corresponding to September-October
 * 2) virgin

title: കന്നി


text: Category:Malayalam terms with obsolete senses


text: Category:Male given names from Albanian languages by language


text:
守秘

Noun

 * 1) protection of a secret

Verb

 * 1) to protect a secret

title: 守秘


text: Category:Maltese offensive terms

title: Category:Maltese offensive terms


text: Category:Maltese terms belonging to the root ġ-r-ħ


text:
sayop

Adjective

 * 1) wrong

Noun

 * 1) error; fault; mistake

Verb

 * 1) to make a mistake; to err

title: sayop


text: Category:Massachusett proper nouns

title: Category:Massachusett proper nouns