Module:User:DTLHS/etymtree

require "math"

local p = {}

function getLevel(line) local result = 1 while string.sub(line, result, result) == "*" do       result = result + 1 end return result - 1 end

function getLangname(line, level) local result = string.sub(line, level + 2) return string.sub(result, 1, (result:find(':')) - 1) end

function getWord(line, level, langname) return string.sub(line, level + 4 + string.len(langname)) end

function getTree(sourcepage) -- load entire tree local result = {} local i = 1 local treeName = "Template:etymtree/" .. sourcepage local tree = "\n" .. mw.title.new( treeName ):getContent .. "\n"

for line in tree:gmatch("[^\n]+") do       if string.sub(line, 1, 1) == "*" then local level = getLevel(line) local langname = getLangname(line, level) local word = getWord(line, level, langname) result[i] = {level, langname, word, line} i = i + 1 end end

return result end

function lineMatch(tree, i, target_langcode, target_word) local t = "{{l|" .. target_langcode .. "|" .. target_word local line = tree[i][3] if string.find(line, t) ~= nil then return true end return false end

function getIndex(tree, target_langcode, target_word) for i, v in ipairs(tree) do       local l = lineMatch(tree, i, target_langcode, target_word) if l == true then return i       end end return nil end

function getParent(tree, i)   local data = tree[i] local level = data[1] local j = i - 1 while true do		if tree[j] == nil then return tree[j] end

if tree[j][1] == (level - 1) then return j       end j = j - 1

end end

function getParents(tree, i)	local result = {} local parent = getParent(tree, i)	while parent ~= nil do		table.insert(result, parent) parent = getParent(tree, parent) end return result end

function getChildren(tree, i)	local result = {} local j = i + 1 local level = tree[i][1]

while (tree[j] ~= nil) and (tree[j][1] > level) do		table.insert(result, j)		j = j + 1 end return result end

function getSisters(tree, i)	local result = {} local level = tree[i][1] local langname = tree[i][2] local parent = getParent(tree, i)   local children = getChildren(tree, parent) for i, v in ipairs(children) do       if (tree[v][1] == level) then table.insert(result, v)       end end return result end

function getDerivedTerms(tree, i)	local result = {} local children = getChildren(tree, i)	local parent_langname = tree[i][2] for i, v in ipairs(children) do		if (tree[v][2] == parent_langname) then table.insert(result, v)		end end return result end

function getRelatedTerms(tree, i)	local result = {} local sisters = getSisters(tree, i)	local langname = tree[i][2] for j, v in ipairs(sisters) do		if (v ~= i) and (tree[v][2] == langname) then table.insert(result, v)		end end return result end

function getCognates(tree, i)	local result = {} local sisters = getSisters(tree, i)	local langname = tree[i][2] for j, v in ipairs(sisters) do		if (v ~= i) and (tree[v][2] ~= langname) then table.insert(result, v)		end end return result end

function makeWikiTable(t, title, columns) local l = tablelength(t) local n = math.ceil(l / columns) local width = 96 / columns

local result = ' \n' result = result .. ' ' .. title .. ' '	result = result .. '\n ' result = result .. ' \n{| border=0 width=100%\n|-\n| bgcolor="#F8F8FF" valign=top align=left|'

for i, v in ipairs(t) do

result = result .. "\n" .. v		-- if (math.mod(i, n) == 0) and (i ~= (n + 1)) and (n ~= 1) then --	result = result .. '\n| width=1% |\n| bgcolor="#F8F8FF" valign=top align=left width=' .. tostring(width) .. '%|'		-- end

end return result .. "\n" .. "|}  " end

function formattedEtymology(tree, i)	local result = "" local parents = getParents(tree, i)	for j, v in ipairs(parents) do		langname = tree[v][2] word = tree[v][3] if word ~= (nil or "" or " ") then result = result .. " from " .. langname .. " " .. word .. ","       end if word == (nil or "" or " ") then result = result .. " from " .. langname .. ","       end end result = string.sub(result, 2, -2) return string.upper(string.sub(result, 1, 1)) .. string.sub(result, 2) .. '.' end

function formattedDescendants(tree, i)	local result = {} local base_level = tree[i][1] local children = getChildren(tree, i)	for i, v in ipairs(children) do       if tree[v][3] ~= (nil or "" or " ") then child = tree[v][4] child = string.sub(child, base_level + 1) table.insert(result, child) end end return makeWikiTable(result, "Descendants", 1) end

function formattedDerivedTerms(tree, i)	local result = {} local base_level = tree[i][1] local derived_terms = getDerivedTerms(tree, i)	for i, v in ipairs(derived_terms) do       if tree[v][3] ~= (nil or "" or " ") then derived = tree[v][4] derived = string.sub(derived, base_level + 1) table.insert(result, derived) end end return makeWikiTable(result, "Derived terms", 1) end

function formattedRelatedTerms(tree, i)	local result = {} local base_level = tree[i][1] local related_terms = getRelatedTerms(tree, i)	for i, v in ipairs(related_terms) do       if tree[v][3] ~= (nil or "" or " ") then related = tree[v][4] related = string.sub(related, base_level) table.insert(result, related) end end return makeWikiTable(result, "Related terms", 1) end

function formattedCognates(tree, i)	local result = {} local base_level = tree[i][1] local cognates = getCognates(tree, i)	for i, v in ipairs(cognates) do       if tree[v][3] ~= (nil or "" or " ") then cognate = tree[v][4] cognate = string.sub(cognate, base_level) table.insert(result, cognate) end end return makeWikiTable(result, "Cognates", 1) end

function tablelength(T) local count = 0 for _ in pairs(T) do count = count + 1 end return count end

function p.main(frame) local args = frame:getParent.args local sourcepage = args[1] local langcode = args[2] local term = args[3] local tree = getTree(sourcepage) local i = getIndex(tree, langcode, term) local etymology = formattedEtymology(tree, i)   local descendants = formattedDescendants(tree, i)    local derived_terms = formattedDerivedTerms(tree, i)    local related_terms = formattedRelatedTerms(tree, i)    local cognates = formattedCognates(tree, i)    return frame:preprocess(etymology .. "\n" .. descendants .. "\n" .. derived_terms .. "\n" .. related_terms .. "\n" .. cognates) end

return p