Module:etymtree

Definition from Wiktionary, the free dictionary
Jump to: navigation, search
Text-x-generic with pencil.svg This module needs documentation.
Please document this module by describing its purpose and usage on the documentation page.

local export = {}

-- Please add comments to explain what the code does/is for! (August 2013)

-- Search in {{etymtree/root_lang/root_term}} for the list item containing a
-- linking template containing "|branch_lang|branch_term".
-- Return all of the list items below this node; that is, the group of items
-- that are below this list item and have a larger number of list markers (#, *, :).
function export.getTree(branch_lang, branch_term, root_lang, root_term)
	if not branch_term then
		branch_term = mw.title.getCurrentTitle().subpageText
	
		if branch_lang:getType() == "reconstructed" or (branch_lang:getType() ~= "appendix-constructed" and (mw.title.getCurrentTitle().nsText == "Appendix" or mw.title.getCurrentTitle().nsText == "Reconstruction")) then
			branch_term = "*" .. branch_term
		end
	end
	
	root_lang = root_lang or branch_lang
	root_term = root_term or branch_term
	
	-- Grab content from subtemplate of {{etymtree}}, for example
	-- {{etymtree/la/populus}}.
	local tree_page = "Template:etymtree/" .. root_lang:getCode() .. "/" .. root_term
	local tree = mw.title.new(tree_page):getContent()
	
	local function template_link()
		return "{{[[" .. tree_page .. "|" .. tree_page:gsub("^Template:", "") ..
				"]]}}"
	end
	
	if not tree then
		error("No subtemplate of {{[[Template:etymtree|etymtree]]}} for language " ..
				root_lang:getCode() " and term " .. root_term .. "; it would be located at " ..
				template_link() .. ".")
	end
	
	-- Match language code and term parameter: for instance,
	-- "|la|populus" in "{{desc|la|populus}}".
	-- This means that fancy stuff like "{{desc|1=la|2=populus}}" won't work.
	local search_for = "|" .. branch_lang:getCode():gsub("-", "%%-") .. "|([^|}]+)"
	
	local found = false
	
	local indent_level, skip_level
	
	local result = {}
	
	for line in tree:gmatch("[^\n]+") do
		if not found then
			for term_match in line:gmatch(search_for) do
				if term_match == branch_term or branch_lang:makeEntryName(term_match) == branch_term then
					indent_level = #line:match("^[%*:#]+")
					found = true
					break
				end
			end
		else
			local current_level = #line:match("^[%*:#]+")
			if current_level <= indent_level then
				break
			end
			
			if not skip_level or current_level <= skip_level then
				skip_level = false
				
				local lang, term = line:match("|([^|=}]+)|(%*[^|=}]+)")
				
				if not lang then
					lang, term = line:match("|(la)|(%*?[^|=}]+)")
				end
				
				if lang and lang == "itc-pro" then
					lang = nil
				end
				
				if lang then
					lang = require("Module:languages").getByCode(lang)
					term = lang:makeEntryName(term)
					lang = lang:getCanonicalName()
					local page_name
					if term:match("^%*") then
						page_name = 'Reconstruction:'..lang..'/'..mw.ustring.sub(term,2)
					else
						page_name = term
					end
					
					if mw.title.new(page_name).exists then
						table.insert(result, mw.ustring.sub(line, indent_level + 1) .. " {{see desc}}")
						skip_level = current_level
					else
						table.insert(result, mw.ustring.sub(line, indent_level + 1))
					end
				else
					table.insert(result, mw.ustring.sub(line, indent_level + 1))
				end
			end
		end
	end
	
	if not found then
		error("Branch for language code " .. branch_lang:getCode() .. " and term " .. branch_term ..
			" not found in " .. template_link() .. ".")
	end
	
	if result[16] and branch_lang:getType() ~= "reconstructed" and not (branch_lang:getType() ~= "appendix-constructed" and mw.title.getCurrentTitle().nsText == "Appendix") then
		local index = math.floor((#result+1)/2) + 1
		local left, right = index, index
		
		while left > 0 and right <= #result do
			if result[left]:match("^[%*:#][^%*:#]") then
				index = left
				break
			elseif result[right]:match("^[%*:#][^%*:#]") then
				index = right
				break
			end
			right = right + 1
			left = left - 1
		end
			
		table.insert(result, 1, "{{top2}}")
		table.insert(result, index+1, "{{mid2}}")
		table.insert(result, "{{bottom}}")
	end
	
	return "<div style=\"float: right;\">{{edit|" .. tree_page .. "}}</div>\n" .. table.concat(result,"\n")
end

function export.etym(branch_lang, branch_term, root_lang, root_term)
	if not branch_term then
		branch_term = mw.title.getCurrentTitle().subpageText
	
		if branch_lang:getType() == "reconstructed" or (branch_lang:getType() ~= "appendix-constructed" and mw.title.getCurrentTitle().nsText == "Appendix") then
			branch_term = "*" .. branch_term
		end
	end

	root_lang = root_lang or branch_lang
	root_term = root_term or branch_term
	
	local tree_page = "Template:etymtree/" .. root_lang:getCode() .. "/" .. root_term
	local tree = "\n" .. mw.title.new(tree_page):getContent() .. "\n"
	
	local point = tree:find("|" .. branch_lang:getCode() .. "|" .. branch_term, 1, true) or error("Etymology chain not found.")
	point = tree:find("\n", point, true)
	local branch = tree:sub(1, point)
	
	local function a()
		branch = branch:gsub( "(\n%*+)%**[^\n%*][^\n]+%1([^%*])", "%1%2")
		return branch
	end
	
	while a() ~= a() do
		-- nothing
	end
	
	branch = branch:gsub("\n[^\n]+\n?$","") -- don't display the word itself in the etym
	local chain = mw.text.gsplit(branch, "\n%*+%s*")
	local returnvalue = "."
	
	for b in chain do
		if b:find( ":" ) then
			local c = b:gsub("^[^:]+%:%s*%{%{", "")
				:gsub("^l%|([^%|]+)%|%*", "%1|" .. branch_lang:getCode() .. "}} {{m|%1|*")
				:gsub("^l%|([^%|]+)%|", "%1|" .. branch_lang:getCode() .. "}} {{m|%1|")
			returnvalue = ", from {{etyl|" .. c .. returnvalue
		end
	end
	
	return returnvalue:gsub("^, f", "F") .. "{{edit|" .. tree_page .. "}}"
end

function export.main(frame)
	local args = frame:getParent().args
	
	local branch_lang = args[1] or nil
	local root_lang = args[2] or nil
	local root_term = args[3] or nil
	local branch_term = args["branch_term"] or nil
	
	if mw.title.getCurrentTitle().nsText == "Template" then
		root_lang = "ine-pro"
		root_term = "*wódr̥"
		branch_lang = "ang"
		branch_term = "wæter"
	end
	
	branch_lang = require("Module:languages").getByCode(branch_lang) or require("Module:languages").err(branch_lang, 1, "branch language code")
	root_lang = root_lang and (require("Module:languages").getByCode(root_lang) or require("Module:languages").err(root_lang, 2) ) or nil
	
	local ret = export.getTree(branch_lang, branch_term, root_lang, root_term)
	return frame:preprocess(ret)
end

function export.etymmain(frame)
	local args = frame:getParent().args
	
	local branch_lang = args[1] or nil
	local root_lang = args[2] or nil
	local root_term = args[3] or nil
	local branch_term = args["branch_term"] or nil
	
	if mw.title.getCurrentTitle().nsText == "Template" then
		root_lang = "ine-pro"
		root_term = "*wódr̥"
		branch_lang = "en"
		branch_term = "water"
	end
	
	branch_lang = require("Module:languages").getByCode(branch_lang) or require("Module:languages").err(branch_lang, 1, "branch language code")
	root_lang = root_lang and (require("Module:languages").getByCode(root_lang) or require("Module:languages").err(root_lang, 2)) or nil
	
	local ret = export.etym(branch_lang, branch_term, root_lang, root_term)
	return frame:preprocess(ret)
end

return export