Module:User:kc kennylau/ancestor chain
Jump to navigation
Jump to search
- The following documentation is located at Module:User:kc kennylau/ancestor chain/documentation. [edit] Categories were auto-generated by Module:documentation. [edit]
- Useful links: root page • root page’s subpages • links • transclusions • testcases • user page • user talk page • userspace
Lua error at line 147: bad argument #1 to 'ipairs' (table expected, got string)
local p = {}
local lang = mw.loadData("Module:languages/data/all")
local fam = mw.loadData("Module:families/data")
local etyl = mw.loadData("Module:etymology languages/data")
local function get_data(code)
return lang[code] or etyl[code] or error("language code " .. code .. " not recognized")
end
local function get_sort_value(val)
data = get_data(val)
return data[1] or data.canonicalName
end
local function format(code)
if lang[code] then
return "<code>[[:Category:" .. lang[code][1] .. " language|" .. lang[code][1] .. " <span style=\"color:green;\">(" .. code .. ")</span>]]</code>"
elseif etyl[code] then
return "<code>[[:Category:" .. etyl[code].canonicalName .. "|" .. etyl[code].canonicalName .. " <span style=\"color:green;\">(" .. code .. ")</span>]] (etym-only)</code>"
end
end
local function dump(data, prefix)
if type(data) == "string" then
return format(data)
else
local result = {}
local branch = "├───"
local next_level = prefix .. "│ "
local length = #data
for i, val in ipairs(data) do
if i == length then
branch = "└───"
next_level = prefix .. " "
end
if not val[1] then
table.insert(result, prefix .. branch .. dump(val.name) .. "<br/>")
else
table.insert(result, "\n{| class=mw-collapsible style=border-collapse:collapse\n|")
table.insert(result, prefix .. branch .. dump(val.name))
table.insert(result, "\n|-\n|")
table.insert(result, dump(val, next_level))
table.insert(result, "\n|}\n")
end
end
return table.concat(result)
end
end
local function deep_sort(current)
local result = {}
local is_table = {}
for key, val in pairs(current) do
if type(key) == "number" then
table.insert(result, val)
else
is_table[key] = true
table.insert(result, key)
end
end
table.sort(result, function(a, b)
return get_sort_value(a) < get_sort_value(b)
end)
local i = 2
while i < #result do
while get_data(result[i - 1]) == get_data(result[i]) do
table.remove(result, i)
end
i = i + 1
end
for i = 1, #result do
if is_table[result[i]] then
local name = result[i]
result[i] = deep_sort(current[result[i]])
result[i].name = name
else
result[i] = { name = result[i] }
end
end
return result
end
local function find_code(t, code)
for _, val in ipairs(t) do
if val.name == code then -- "name" is really code
return { val }
else
local result = find_code(val, code)
if result then
return result
end
end
end
end
local function find_ancestors(origin, key, val)
if val.ancestors then
return val.ancestors
elseif etyl[key] and val.parent and val.parent:match("%-pro$") then
return { val.parent }
elseif val[3] or val.family then
while true do
key = val[3] or val.family
val = fam[key]
if not key or key == "qfa-not" or key == "qfa-und" then
return nil
elseif val.protoLanguage and origin ~= val.protoLanguage then
return { val.protoLanguage }
elseif origin ~= key .. "-pro" and lang[key .. "-pro"] then
return { key .. "-pro" }
end
end
end
end
local function make_nested(data, children)
local make_nil = {}
for key, val in pairs(data) do
if type(key) == "number" then
if children[val] then
data[val] = make_nested(children[val], children)
table.insert(make_nil, key)
children[val] = nil
end
else
data[key] = make_nested(val, children)
end
end
for _, key in ipairs(make_nil) do
data[key] = nil
end
return data
end
local function get_children()
local children = {}
for _, data in ipairs { lang, etyl } do
for key, val in pairs(data) do
local ancestors = find_ancestors(key, key, val)
if ancestors then
for _, ancestor in ipairs(ancestors) do
if ancestor ~= key then
if children[ancestor] then
table.insert(children[ancestor], key)
else
children[ancestor] = { key }
end
end
end
end
end
end
return children
end
function p.show(frame)
local children = get_children()
local nested = make_nested(children, children)
nested = deep_sort(nested)
local descendants_of = frame.args[1]
if descendants_of then
if not lang[descendants_of] then
error("The language code " .. descendants_of .. " is not a valid non-etymology language.")
end
nested = find_code(nested, descendants_of)
end
local result = {}
for i = 1, #nested do
table.insert(result, "\n\n\n{| class=mw-collapsible style=border-collapse:collapse\n|" .. format(nested[i].name) .. "\n|-\n|")
table.insert(result, dump(nested[i], " "))
table.insert(result, "\n|}")
end
return table.concat(result)
end
return p