Module:family tree
Documentation for this module may be created at Module:family tree/doc
local m_families = mw.loadData('Module:families/data')
local m_languages_old = mw.loadData('Module:languages/alldata')
local export = {}
local function build_tree()
local tree = {}
for code, data in pairs(m_families) do
if not tree[data.family] then
tree[data.family] = {}
end
if code ~= data.family then
table.insert(tree[data.family], code)
end
end
for code, data in pairs(m_languages_old) do
if not tree[data.family] then
tree[data.family] = {}
end
if code ~= data.family then
table.insert(tree[data.family], code)
end
end
return tree
end
local type_map = {
["reconstructed" ] = 0,
["family" ] = 1,
["regular" ] = 2,
["appendix-constructed"] = 2
}
local function make_list(code, tree, with_parents)
local result = {}
local stars = '*'
local function format_family(code)
local catname = m_families[code].names[1]
if not catname:find("[Ll]anguages$") then
catname = catname .. ' languages'
end
return ("[[:Category:%s|%s]] (<code>%s</code>)"):format(catname, catname, code)
end
local function format_lang(code)
local catname = m_languages_old[code].names[1]
if not catname:find("[Ll]anguage$") then
catname = catname .. ' language'
end
return ("%s[[:Category:%s|%s]]%s (<code>%s</code>)"):format(
(m_languages_old[code].type == "reconstructed") and "*" or
((m_languages_old[code].type == "appendix-constructed") and "''" or ""),
catname, m_languages_old[code].names[1],
(m_languages_old[code].type == "appendix-constructed") and "''" or "",
code
)
end
local function add_item(code)
if m_families[code] then
table.insert(result, stars .. ' ' .. format_family(code))
elseif m_languages_old[code] then
table.insert(result, stars .. ' ' .. format_lang(code))
end
if tree[code] then
stars = stars .. '*'
table.sort(tree[code], function (apple, orange)
local appl_lang = m_languages_old[apple]
local orng_lang = m_languages_old[orange]
local appl_name = appl_lang and appl_lang.names[1] or m_families[apple].names[1]
local orng_name = orng_lang and orng_lang.names[1] or m_families[orange].names[1]
local appl_type = appl_lang and appl_lang.type or "family"
local orng_type = orng_lang and orng_lang.type or "family"
if type_map[appl_type] < type_map[orng_type] then
return true
elseif type_map[appl_type] > type_map[orng_type] then
return false
else
return appl_name < orng_name
end
end)
for i, item in ipairs(tree[code]) do
add_item(item)
end
stars = stars:sub(1, #stars - 1)
end
end
if with_parents then
local fcode = (m_families[code] and m_families[code].family) or (m_languages_old[code] and m_languages_old[code].family) or error("Not a valid language or family code")
local dcode, depth, itnum = fcode, 0, 0
while (dcode ~= "qfa-und") and (dcode ~= "qfa-not") do
dcode = m_families[dcode].family
depth = depth + 1
stars = stars .. "*"
end
while itnum < depth do
table.insert(result, 1, stars:sub(1, depth - itnum) .. ' ' .. format_family(fcode))
fcode = m_families[fcode].family
itnum = itnum + 1
end
end
add_item(code)
return table.concat(result, "\n")
end
function export.show(frame)
local tree = build_tree()
local root = frame.args[1] or "qfa-not"
return make_list(root, tree, frame.args.with_parents)
end
return export