Module:he-noun

Hello, you have come here looking for the meaning of the word Module:he-noun. In DICTIOUS you will not only get to know all the dictionary meanings for the word Module:he-noun, but we will also tell you about its etymology, its characteristics and you will know how to say Module:he-noun in singular and plural. Everything you need to know about the word Module:he-noun you have here. The definition of the word Module:he-noun will help you to be more precise and correct when speaking or writing your texts. Knowing the definition ofModule:he-noun, as well as those of other words, enriches your vocabulary and provides you with more and better linguistic resources.

This module generates inflection tables for Hebrew nouns, used by {{he-decl}}, see its documentation to learn more.


local m_links = require("Module:links")
local m_strutils = require("Module:string utilities")
local com = require("Module:he-common")

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

local export = {}

local function process_arg(arg)
    arg = com.fix_nikud(arg)
    local i = mw.ustring.find(arg, "")
    if i then
        arg = {mw.text.trim(mw.ustring.sub(arg, 1, i - 1)), mw.text.trim(mw.ustring.sub(arg, i + 1))}
    end
    return arg
end

local function getv(x)
    if type(x) == "table" then
        return x
    else
        return x
    end
end

local function getnv(x)
    if type(x) == "table" then
        return x
    else
        return mw.ustring.gsub(x, "*+%-?]+", function(c1) return (lang:makeEntryName(c1)) end)
    end
end

local function getnvrx(x)
    return mw.ustring.gsub(getnv(x), "%?", "")
end

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

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

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

local function gsub_form(form, regex, repl, const_repl)
    if type(form) == "table" or type(regex) == "table" or (not const_repl and type(repl) == "table") then
        local replv = repl
        local replnv = repl
        if not const_repl then
            replv = getv(repl)
            replnv = getnv(repl)
        end
        local retv = mw.ustring.gsub(getv(form), getv(regex), replv)
        local retnv = mw.ustring.gsub(getnv(form), getnvrx(regex), replnv)
        return {retnv, retv}
    else
        return mw.ustring.gsub(form, regex, repl)
    end
end

local function match_form(form, regex)
    if type(form) == "table" or type(regex) == "table" then
        local retv = mw.ustring.match(getv(form), getv(regex))
        local retnv = mw.ustring.match(getnv(form), getnvrx(regex))
        if retv and retnv then
            return {retnv, retv}
        else
            return nil
        end
    else
        return mw.ustring.match(form, regex)
    end
end

local final_to_unfinal = {
     = "כ",
     = "מ",
     = "נ",
     = "פ",
     = "צ",
}

local function unfinalize(form)
    if match_form(form, "ַ$") or match_form(form, "הּ?$") then
        return gsub_form(form, "()??$", "%1")
    elseif match_form(form, "$") or match_form(form, "ךְ$") then
        return gsub_form(form, "()?$", final_to_unfinal, true)
    else
        return form
    end
end

local function make_link(x, is_construct)
    local dolink = true
    if SUPPRESS_LINKS then
        dolink = nil
    end
    local maqaf = is_construct and "־" or ""
    if type(x) == "table" then
        local pg = (lang:makeEntryName(x))
        return m_links.full_link({lang = lang, allow_self_link = false, term = dolink and pg, alt = (pg ~= (lang:makeEntryName(x)) and pg .. maqaf .. " / " or "") .. x .. maqaf, tr = "-"})
    else
        if x == "-" then
            return "—" -- m-dash
        else
            return m_links.full_link({lang = lang, term = dolink and x, alt = x .. maqaf, tr = "-", allow_self_link = false})
        end
    end
end

local numbers = {
     = "singular",
     = "dual",
     = "plural",
     = "masculine singular",
     = "masculine dual",
     = "masculine plural",
     = "feminine singular",
     = "feminine dual",
     = "feminine plural",
}

local singulars = {
     = true,
     = true,
     = true,
}

local function split_defv(form)
    local ret = mw.ustring.gsub(form, "^הַ(?)ּ", "%1")
    if ret ~= form then return ret end
    ret = mw.ustring.gsub(form, "^הַ()", "%1")
    if ret ~= form then return ret end
    ret = mw.ustring.gsub(form, "^הָ(ר)", "%1")
    if ret ~= form then return ret end
    ret = mw.ustring.gsub(form, "^ה()", "%1")
    if ret ~= form then return ret end
    return nil
end

local function split_def(form)
    if type(form) == "table" then
        local wv = split_defv(form)
        local nv = mw.ustring.gsub(form, "^ה", "")
        if wv and (nv ~= form) then
            return {nv, wv}
        else
            return nil
        end
    else
        return split_defv(form)
    end
end

local function attach_def(form)
    if match_form(form, "^") then
        return append_parts("הַ", form)
    elseif match_form(form, "^") then
        return append_parts("הָ", form)
    elseif match_form(form, "^ו") then
        return gsub_form(form, "^ו", {"הוו", "הַוּ"})
    elseif match_form(form, "^") or match_form(form, "^ש") then
        return gsub_form(form, "^(?)", "הַ%1ּ")
    else
        error("Unrecognized initial consonant in indefinite form.")
    end
end

local function remove_maqaf(x)
    if type(x) == "table" then
        return {mw.ustring.gsub(x, "־$", ""), mw.ustring.gsub(x, "־$", "")}
    else
        return mw.ustring.gsub(x, "־$", "")
    end
end

local function process_args(args)
    for key, val in pairs(args) do
        val = mw.text.trim(val)
        if val == "" then val = nil end
        args = val
    end

    local forms = {}

    if not args then return forms end

    local i = 1
    local num = "s"
    while num do
        local section = { = num}
        local touched = false
        local likely_def = nil
        local initial_hes = nil
        while args and not numbers] do
            local form = process_arg(args)
            local wv = getv(form)
            if likely_def then
                local cur_initial_hes = mw.ustring.len(mw.ustring.match(getnv(form), "^ה*"))
                if cur_initial_hes < initial_hes then
                    section = likely_def
                elseif cur_initial_hes > initial_hes and split_defv(wv) then
                    section = likely_def
                else
                    error("Definite form must either be first or second.")
                end
                likely_def = nil
            end
            if (not section) and split_defv(wv) then
                if touched then
                    section = form
                else
                    likely_def = form
                    initial_hes = mw.ustring.len(mw.ustring.match(getnv(form), "^ה*"))
                end
            elseif not touched then
                section = form
            elseif (not section) and mw.ustring.match(wv, "ךָ$") then
                section = form
            elseif (not section) and mw.ustring.match(wv, "כֶם$") then
                section = form
            elseif (not section) and (mw.ustring.match(wv, "וֹ$") or mw.ustring.match(wv, "ו$") or mw.ustring.match(wv, "הוּ$")) then
                section = form
            elseif (not section) and (mw.ustring.match(wv, "־$") or mw.ustring.match(getnv(form), "־$")) then
                section = remove_maqaf(form)
            else
                error("Unrecognized or duplicate form: " .. wv)
            end
            touched = true
            i = i + 1
        end
        if likely_def then
            if section then error("Unrecognized or duplicate form: " .. getv(section)) end
            section = likely_def
        end
        if touched then
            table.insert(forms, section)
        end
        num = args
        i = i + 1
    end

    return forms
end

local endings_c = {
     = false,
     = "ִי",
     = "ְךָ",
     = "ֵךְ",
     = "וֹ",
     = "ָהּ",
     = "ֵנוּ",
     = "ְכֶם",
     = "ְכֶן",
     = "ָם",
     = "ָן",
}

-- most have alternative forms that are not yet supported
local endings_e = {
     = true,
     = "ִי",
     = "ֶךָ",
     = "ֵךְ",
     = "ֵהוּ",
     = "ֶהָ",
     = "ֵנוּ",
     = "ֵכֶם",
     = "ֵכֶן",
     = "ֵהֶם",
     = "ֵהֶן",
}

local endings_i = {
     = true,
     = "",
     = "ךָ",
     = "ךְ",
     = "ו", -- and "הוּ", for when I allow multiple forms
     = "הָ",
     = "נוּ",
     = "כֶם",
     = "כֶן",
     = "הֶם",
     = "הֶן",
}

-- endings for ים ending

local endings_pm = {
     = true,
     = {"יי", "ַי"},
     = "ֶיךָ",
     = {"ייך", "ַיִךְ"},
     = "ָיו",
     = "ֶיהָ",
     = "ֵינוּ",
     = "ֵיכֶם",
     = "ֵיכֶן",
     = "ֵיהֶם",
     = "ֵיהֶן",
}

-- endings for ות ending

local endings_pf = {
     = true,
     = {"יי", "ַי"},
     = "ֶיךָ",
     = {"ייך", "ַיִךְ"},
     = "ָיו",
     = "ֶיהָ",
     = "ֵינוּ",
     = "ֵיכֶם",
     = "ֵיכֶן",
     = "ָם",--add extra יהם ending
     = "ָן",--add extra יהן ending
}

local light_endings = {
    "1s",
    "2ms",
    "2fs",
    "3ms",
    "3fs",
    "1p",
}

local heavy_endings = {
    "2mp",
    "2fp",
}

local maybe_endings = {
    "3mp",
    "3fp",
}

local function attach_ending(stem, ending)
    if match_form(ending, "^ְ") and match_form(stem, "$") then
        ending = gsub_form(ending, "^ְ", "ֲ")
    elseif match_form(ending, "^ָ") and match_form(stem, "ַח$") then
        stem = gsub_form(stem, "ַח$", "ֶח")
    elseif type(ending) == "table" and mw.ustring.match(getnv(stem), "י$") and mw.ustring.len(mw.ustring.match(getnv(ending), "^י*")) > mw.ustring.len(mw.ustring.match(getnv(getv(ending)), "^י*")) then
        ending = gsub_form(ending, {"^י", "^"}, "")
    end
    return append_parts(stem, ending)
end

local function infer_forms(forms)
    for _, section in pairs(forms) do
        local light_stem = nil
        local heavy_stem = nil
        local endings = nil
        if section then
            section = section or split_def(section)
        elseif section then
            section = section or attach_def(section)
        else
            error("Must have either definite or indefinite form.")
        end
        if singulars] then
            local is_fem = match_form(section, "ָה$")
            local is_e = match_form(section, "ֶה$")
            if not section then
                if is_fem then
                    section = gsub_form(section, "ָה$", "ַת")
                elseif is_e then
                    section = gsub_form(section, "ֶה$", "ֵה")
                elseif match_form(section, "ָ?$") then
                    section = gsub_form(section, "ָ(?)$", "ַ%1")
                else
                    section = section
                end
            end
            if section then
                if match_form(section, "וֹ$") then
                    light_stem = gsub_form(section, "וֹ$", "")
                    endings = endings_c
                elseif match_form(section, "ֵהוּ$") then
                    light_stem = gsub_form(section, "ֵהוּ$", "")
                    endings = endings_c
                elseif match_form(section, "ִיהוּ$") then
                    light_stem = gsub_form(section, "הוּ$", "")
                    endings = endings_i
                elseif match_form(section, "ִיו$") then
                    light_stem = gsub_form(section, "ו$", "")
                    endings = endings_i
                else
                    error("Unrecognized 3ms suffix pattern.")
                end
            elseif match_form(section, "ֵה$") then
                if is_e then
                    light_stem = gsub_form(section, "ֶה$", "")
                else
                    light_stem = gsub_form(section, "ֵה$", "")
                end
                endings = endings_e
            elseif match_form(unfinalize(section), "ַ?$") then
                light_stem = gsub_form(unfinalize(section), "ַ(?)$", "ָ%1")
                endings = endings_c
            else
                light_stem = unfinalize(section)
                if match_form(section, "ִי$") then
                    endings = endings_i
                else
                    endings = endings_c
                end
            end
            if section then
                if endings == endings_c then
                    if not match_form(section, "ְכֶם$") and not match_form(section, "ֲכֶם$") then
                        error("Unrecognized 2mp suffix pattern.")
                    end
                    heavy_stem = gsub_form(section, "כֶם$", "")
                else
                    if not match_form(section, "כֶם$") then
                        error("Unrecognized 2mp suffix pattern.")
                    end
                    heavy_stem = gsub_form(section, "כֶם$", "")
                end
            elseif section and endings == endings_c and match_form(section, "ְךָ$") then
                heavy_stem = gsub_form(section, "ְךָ$", "")
            elseif match_form(light_stem, "ּ$") or match_form(light_stem, "ְ?$") then
                heavy_stem = light_stem
            elseif match_form(section, "ֵה$") then
                if endings == endings_e then
                    heavy_stem = gsub_form(section, "ה$", "")
                else
                    heavy_stem = light_stem
                end
            else
                heavy_stem = unfinalize(section)
            end
        else
            endings = endings_pm
            if not section then
                if match_form(section, "וֹת$") then
    				endings = endings_pf
                    section = section
                elseif match_form(section, "ִים$") then
                    section = gsub_form(section, "ִים$", "ֵי")
                elseif match_form(section, {"יי?ם$", "ַיִם$"}) then
                    section = gsub_form(section, {"יי?ם$", "ַיִם$"}, "ֵי")
                else
                    error("Unrecognized plural pattern.")
                end
            end
            if match_form(section, "ֵי$") then
                heavy_stem = gsub_form(section, "ֵי$", "")
                if match_form(section, "ִים$") then
                    light_stem = gsub_form(section, "ִים$", "")
                elseif match_form(section, {"יי?ם$", "ַיִם$"}) then
                    light_stem = gsub_form(section, {"יי?ם$", "ַיִם$"}, "")
                else
                    light_stem = heavy_stem
                end
            elseif match_form(section, "וֹת$") then
    			endings = endings_pf
                heavy_stem = section
                light_stem = heavy_stem
            else
                error("Unrecognized plural construct pattern.")
            end
        end
        local maybe_stem = endings and heavy_stem or light_stem
        for _, p in pairs(light_endings) do
            section = section or attach_ending(light_stem, endings)
        end
        for _, p in pairs(heavy_endings) do
            section = section or attach_ending(heavy_stem, endings)
        end
        for _, p in pairs(maybe_endings) do
            section = section or attach_ending(maybe_stem, endings)
        end
    end
end

local example_s = {
     = "s",
     = "בַּיִת",
     = "הַבַּיִת",
     = "בֵּית",
     = "בֵּיתִי",
     = "בֵּיתְךָ",
     = "בֵּיתֵךְ",
     = "בֵּיתוֹ",
     = "בֵּיתָהּ",
     = "בֵּיתֵנוּ",
     = "בֵּיתְכֶם",
     = "בֵּיתְכֶן",
     = "בֵּיתָם",
     = "בֵּיתָן",
}

local example_p = {
     = "p",
     = "בָּתִּים",
     = "הַבָּתִּים",
     = "בָּתֵּי",
     = {"בתיי", "בָּתַּי"},
     = "בָּתֶּיךָ",
     = {"בתייך", "בָּתַּיִךְ"},
     = "בָּתָּיו",
     = "בָּתֶּיהָ",
     = "בָּתֵּינוּ",
     = "בָּתֵּיכֶם",
     = "בָּתֵּיכֶן",
     = "בָּתֵּיהֶם",
     = "בָּתֵּיהֶן",
}

local example = {example_s, example_p}

local table_top = [===[<div><div class="NavFrame" style="display:inline-block;min-width:30em">
<div class="NavHead" align="left" style="min-width:30em">{title}</div>
<div class="NavContent" align="center" style="min-width:30em">
{\op}| class="wikitable inflection-table" style="text-align:center;margin:0"
! rowspan="3" | Number !! colspan="2" | Isolated forms !! colspan="5" | With possessive pronouns
|-
! rowspan="2" | State !! rowspan="2" | Form !! rowspan="2" | Person !! colspan="2" | singular !! colspan="2" | plural
|-
! m. !! f. !! m. !! f.
]===]

local table_section = [===[|-
! rowspan="3" | {number} !! indefinite
| {i}
! first
| colspan="2" | {1s} || colspan="2" | {1p}
|-
! definite
| {d}
! second
| {2ms} || {2fs} || {2mp} || {2fp}
|-
! construct
| {c}
! third
| {3ms} || {3fs} || {3mp} || {3fp}
]===]

local table_bottom = [===[|{\cl}
</div></div></div>]===]

local forms_names = {
    "i",
    "d",
    "c",
    "1s",
    "2ms",
    "2fs",
    "3ms",
    "3fs",
    "1p",
    "2mp",
    "2fp",
    "3mp",
    "3fp",
}

local function make_table(forms)
    local title = forms and forms and forms and ("Declension of " .. make_link(forms)) or "Declension"
    local output = {}
    table.insert(output, m_strutils.format(table_top, { = title}))
    for _, section in ipairs(forms) do
        section = numbers]
        for _, form_name in pairs(forms_names) do
            section = make_link(section or "-", section and form_name == "c")
        end
        table.insert(output, m_strutils.format(table_section, section))
    end
    table.insert(output, m_strutils.format(table_bottom, {}))
    return table.concat(output)
end

function export.show(frame)
    local args = frame:getParent().args
    PAGENAME = mw.title.getCurrentTitle().text
    NAMESPACE = mw.title.getCurrentTitle().nsText

    if args and args ~= "" then
        SUPPRESS_LINKS = true
    end

    local forms = nil
    if frame.args == "example" then
        forms = example
    else
        forms = process_args(args)
        infer_forms(forms)
    end

    return make_table(forms)
end

return export