Module:descendants
Jump to navigation
Jump to search
Underlies {{descendant}}
and {{descendant tree}}
.
local export = {}
local getArgs = require("Module:Arguments").getArgs
local m_links = require("Module:links")
local m_languages = require("Module:languages")
local m_inline = require("Module:inline")
function export.descendant(frame)
local args = getArgs(frame)
local out = ""
local lang = args[1]
if mw.ustring.find(lang, "[%>%_]") then
lang = mw.ustring.match(lang, "[%>%_]([^%>%_]+)$")
end
if mw.ustring.find(lang, "[0-9]+$") then
lang = mw.ustring.gsub(lang, "[0-9]+$", "")
end
lang = m_languages.get_by_code(lang)
local borrowed = args["borrowed"] or args["bor"] or args["b"]
local see_desc = args["see"]
local noname = args["noname"]
local lostcap = args["lost"] or "lost"
if borrowed then out = "<span class=\"desc-arrow\" title=\"borrowed\">→</span>" .. out end
if not noname then out = out .. lang.name .. ": " end
if args[2] then
local terms = {}
local i = 2
while args[i] do
local term, term_args = m_inline.parse(args[i])
table.insert(terms, m_links.full_link({
language = lang,
term = term,
alt = term_args.alt,
anchor = term_args.anchor or term_args.a,
gloss = term_args.t,
pos = term_args.pos,
nobold = true,
})
)
i = i + 1
end
out = out .. table.concat(terms, ", ")
if see_desc then out = out .. " " .. frame:expandTemplate{ title = 'see descendants' } end
else
out = out .. "— (''" .. lostcap .. "'')"
end
return out
end
function export.langtree(list)
-- build in-set ancestry
local ancestors = {}
for _, lang in ipairs(list) do
ancestors[lang] = {}
if mw.ustring.find(lang, "[%>%_]") then
local ancestor_temp = ""
for piece in mw.ustring.gmatch(lang, "([^%>%_]+[%>%_])") do
ancestor_temp = ancestor_temp .. piece
ancestor_add = mw.ustring.gsub(ancestor_temp, "[%>%_]$", "")
table.insert(ancestors[lang], ancestor_add)
end
elseif mw.ustring.find(lang, "[0-9]+$") then
local lang_temp, index = mw.ustring.match(lang, "^([^0-9]+)([0-9]+)$")
for _, test in ipairs(list) do
if mw.ustring.find(test, index .. "$") then
local test_temp = mw.ustring.gsub(test, index .. "$", "")
if m_languages.get_by_code(lang_temp).lineage[test_temp] then
table.insert(ancestors[lang], test)
end
elseif m_languages.get_by_code(lang_temp).lineage[test] then
local nope = false
for _, contain_test in ipairs(list) do
if contain_test == test .. index then nope = true end
end
if not nope then table.insert(ancestors[lang], test) end
end
end
else
for _, test in ipairs(list) do
if m_languages.get_by_code(lang).lineage[test] then
table.insert(ancestors[lang], test)
end
end
end
end
local structure = {}
for lang, _ in pairs(ancestors) do
if #ancestors[lang] == 0 then
structure[lang] = {}
ancestors[lang] = nil
end
end
local swept = {}
local function search_and_sort(superordinate)
for mother, it in pairs(superordinate) do
for lang, lang_ancestors in pairs(ancestors) do
for i, lang_ancestor in ipairs(ancestors[lang]) do
if swept[lang_ancestor] then table.remove(ancestors[lang], i) end
end
end
for lang, lang_ancestors in pairs(ancestors) do
if #lang_ancestors == 1 and lang_ancestors[1] == mother then
superordinate[mother][lang] = {}
swept[mother] = true
ancestors[lang] = nil
end
end
search_and_sort(it)
end
end
search_and_sort(structure)
return structure
end
function export.desctree(frame)
local args = getArgs(frame)
local out = ""
local current_lang, code
local terms = {}
local langs = {}
local indenter = args["indent"] or args["in"] or ""
for i, term in ipairs(args) do --ryn:term1|term2|term3|rad:term1|term2 ...
local lang_change = mw.ustring.match(term, "^([^%:%<]+)%:")
local lang_change_arged = mw.ustring.match(term, "^(.+%>)%:")
local from_lang, index
if i == 1 and not (lang_change or lang_change_arged) then error("Language code needs to be specified in the first parameter as xyz(<bor>):term₁") end
if lang_change or lang_change_arged then
if lang_change then
current_lang = lang_change
term = mw.ustring.gsub(term, "^[^%:]+%:%s*", "")
elseif lang_change_arged then
current_lang = mw.ustring.match(lang_change_arged, "^[^%<]+")
term = mw.ustring.gsub(term, "^.+%>%:%s*", "")
end
if mw.ustring.find(current_lang, "[%>%_][^%:]") then
from_lang, current_lang = mw.ustring.match(current_lang, "^(.*[%>%_])([^%>%_%:]+)$")
if mw.ustring.match(from_lang, "%>$") then
if lang_change_arged then
lang_change_arged = lang_change_arged .. "<bor>"
else
lang_change_arged = "<bor>"
end
end
end
if mw.ustring.find(current_lang, "[0-9]+$") then
current_lang, index = mw.ustring.match(current_lang, "^(.*)([0-9]+)$")
end
current_lang = m_languages.get_by_code(current_lang)
code = current_lang.code
if from_lang then code = from_lang .. code end
if index then code = code .. index end
if terms[code] == nil then
terms[code] = {}
table.insert(langs, code)
end
end
if lang_change_arged then
for lang_arg in mw.ustring.gmatch(lang_change_arged, "%<([^%>]+)%>") do
terms[code][lang_arg] = true
end
end
if from_lang then terms[code]["from"] = from_lang end
table.insert(terms[code], term)
end
local items = {}
for lang, lang_args in pairs(terms) do
table.insert(lang_args, 1, lang)
items[lang] = export.descendant(lang_args)
end
-- BEGIN TRIAGE --
local structure = export.langtree(langs)
local outs = {}
local it = 0
function process_structure(tab)
it = it + 1
local sorter = {}
local sorter_proto = {}
local sorter_bor = {}
local sorter_bor_proto = {}
for key, _ in pairs(tab) do
if mw.ustring.find(key, "%-pro[0-9]*$") then
if mw.ustring.find(key, "%>[^%>%_%:]+$") then
table.insert(sorter_bor_proto, key)
else
table.insert(sorter_proto, key)
end
else
if mw.ustring.find(key, "%>[^%>%_%:]+$") then
table.insert(sorter_bor, key)
else
table.insert(sorter, key)
end
end
end
table.sort(sorter)
table.sort(sorter_proto)
table.sort(sorter_bor)
table.sort(sorter_bor_proto)
for _, key in ipairs(sorter_bor) do table.insert(sorter, key) end
for _, key in ipairs(sorter_proto) do table.insert(sorter, key) end
for _, key in ipairs(sorter_bor_proto) do table.insert(sorter, key) end
for _, key in ipairs(sorter) do
local out = " " .. items[key]
for i = 1, it do
out = "*" .. out
end
out = indenter .. out
table.insert(outs, out)
process_structure(tab[key])
end
it = it - 1
end
process_structure(structure)
return table.concat(outs, "\n")
end
return export
--[[
Debug console test string:
=p.descendant(mw.getCurrentFrame():newChild{title="whatever",args={"rad"}})
=p.desctree(mw.getCurrentFrame():newChild{title="whatever",args={"ryn>rad-o:1", "aeg:2", "3", "ryn:4", "ryn>rad-o_rad:5", ">rad-pro:6", "hrd-pro:7", "ryn-o:8", "lfv-pro:9", "lfv-o:10", "lfv:11", "rad-pro:12"}})
]]--