Actions

Module

Module:etymology

From SUALEX

Documentation for this module may be created at Module:etymology/doc

-- Module:etymology

local utilities = require("Module:utilities")
local lexicon   = require("Module:lexicon")
local format    = require("Module:format")

local etymology = {}

local function get_ancestor_relations(lang, item, homonym, options)
    local rels = {}
    for _, et in ipairs(lexicon.get_sources(lang, item, homonym, options) or {}) do
        local rel_type = et.descendant_type or ""
        local rel_unc  = et.uncertainty == true or false
        for _, it in ipairs(et.items or {}) do
            table.insert(rels, {
                type = rel_type,
                uncertainty = rel_unc,
                source_etym = et,
                from = { lang = lang, item = item, homonym = homonym },
                to   = { lang = it.lang_code, item = it.etymon_item, homonym = it.homonym, display = it.display_form }
            })
        end
    end
    return rels
end

local function get_descendant_relations(lang, item, homonym, options)
    local rels = {}
    for _, d in ipairs(lexicon.get_descendants(lang, item, homonym, options) or {}) do
        local et = d.matching_etym
        if et then
            local rel_type = et.descendant_type or ""
            local rel_unc  = et.uncertainty == true or false
            local term = d.entry and d.entry.term and d.entry.term[1] or nil
            if term then
                table.insert(rels, {
                    type = rel_type,
                    uncertainty = rel_unc,
                    source_etym = et,
                    from = { lang = lang, item = item, homonym = homonym },
                    to   = { lang = d.lang, item = term.term_item, homonym = term.homonym, display = term.display_form }
                })
            end
        end
    end
    return rels
end

local function walk(relations_fn, origin, options, level, out)
    out = out or {}
    for _, rel in ipairs(relations_fn(origin.lang, origin.item, origin.homonym, options)) do
        local node = {
            indent = string.rep(":", level + 1),
            type = rel.type,
            uncertainty = rel.uncertainty,
            lang = rel.to.lang,
            term_item = rel.to.item,
            homonym = rel.to.homonym,
            display_form = rel.to.display,
            matching_etym = rel.source_etym
        }
        table.insert(out, node)
        walk(
            relations_fn,
            { lang = rel.to.lang, item = rel.to.item, homonym = rel.to.homonym },
            options,
            level + 1,
            out
        )
    end
    return out
end

function etymology.build_ancestor_tree(lang, item, homonym, options, level)
    return walk(get_ancestor_relations, { lang = lang, item = item, homonym = homonym }, options, level or 0, {})
end

function etymology.build_descendant_tree(lang, item, homonym, options, level)
    return walk(get_descendant_relations, { lang = lang, item = item, homonym = homonym }, options, level or 0, {})
end

function etymology.render_etymon(desc_type, items, global_uncertainty, gloss_pref)
    gloss_pref = gloss_pref or "en"

    local langs = {}
    for _, i in ipairs(items or {}) do langs[i.lang_code] = true end
    local all_same = (utilities.table_keys_count(langs) == 1)
    local rendered = {}

    for _, i in ipairs(items or {}) do
        local term = format.render_term(i.lang_code, i.etymon_item, i.homonym, i.display_form, nil, i.sup, gloss_pref)
        if all_same then
            table.insert(rendered, term)
        else
            table.insert(rendered, format.language_name(i.lang_code) .. " " .. term)
        end
    end

    local joined = utilities.join_strings(rendered, " + ")
    local global_sup = global_uncertainty and format.sup("?", true) or ""

    if all_same and #items > 0 then
        return format.language_name(items[1].lang_code) .. " " .. joined .. global_sup
    else
        return joined .. global_sup
    end
end

function etymology.render_node(node, mode)
    local rel_type = node.type
    local prefix = ""
    if rel_type == "bor" then
        prefix = (mode == "ancestor") and "< " or "> "
    end

    local lang_label = format.language_name(node.lang)
    local term_link = format.render_term(
        node.lang,
        node.term_item,
        node.homonym,
        node.display_form,
        nil,
        nil,
        "en"
    )

    if node.uncertainty then
        term_link = term_link .. format.sup("?", true)
    end

    return prefix .. lang_label .. " " .. term_link
end

return etymology