Modul:etîmolojî/şablon

Ji Wîkîferhengê

Documentation for this module may be created at Modul:etîmolojî/şablon/belge

local export = {}

local m_languages = require("Modul:ziman")
local b = require("Modul:bingeh")

local rsplit = mw.text.split
local rsubn = mw.ustring.gsub

-- version of rsubn() that discards all but the first return value
local function rsub(term, foo, bar)
	local retval = rsubn(term, foo, bar)
	return retval
end

local function fetch_lang(lang, parameter)
	return m_languages.getByCode(lang) or m_languages.err(lang, parameter)
end


local function fetch_source(code, disallow_family)
	local source =
		m_languages.getByCode(code)
		or require("Modul:etymology languages").getByCode(code)
		or not disallow_family and require("Modul:families").getByCode(code)
	
	if source then
		return source
	else
		error("Kodaz zimanê" .. (not disallow_family and ", malbata" or "") .. " yan zimanê etîmolojiyê \"" .. code .. "\" nayê zanîn.")
	end
end


local function fetch_script(sc)
	if sc then
		return require("Modul:scripts").getByCode(sc) or error("Koda skrîptê \"" .. sc .. "\" nayê zanîn.")
	else
		return nil
	end
end

function export.hevreh(frame)
	local args = frame:getParent().args

	local params = {
		[1] = {required = true, default = "und"},
		[2] = {},
		[3] = {alias_of = "cuda"},
		[4] = {alias_of = "w"},
		
		["cuda"] = {},
		["w"] = {},
		["wate"] = {alias_of = "w"},
		["tr"] = {},
		["ts"] = {},
		["R"] = {alias_of = "ts"},
		["sc"] = {},
		
		["sort"] = {},
	}
	
	args = require("Modul:parameters").process(args, params)
	
	local source = fetch_source(args[1])
	local sc = fetch_script(args["sc"])

	return require("Modul:etîmolojî").format_cognate(
		{
			lang = source,
			sc = sc,
			term = args[2],
			alt = args["cuda"],
			tr = args["tr"],
			ts = args["ts"],
			gloss = args["w"],
		},
		args["sort"])
end


function export.nehevreh(frame)
	return export.hevreh(frame)
end

local function parse_2_lang_args(frame, has_text, no_family)
	local params = {
		[1] = {required = true, default = "und"},
		[2] = {default = "ku"},
		[3] = {},
		[4] = {alias_of = "cuda"},
		[5] = {alias_of = "w"},
		
		["cuda"] = {},
		["wate"] = {alias_of = "w"},
		["w"] = {},
		["tr"] = {},
		["ts"] = {},
		["R"] = {alias_of = "ts"},
		["sc"] = {},
		
		["sort"] = {},
	}

	if has_text then
		params["notext"] = {type = "boolean"}
		params["nocap"] = {type = "boolean"}
	end

	local args = require("Modul:parameters").process(frame:getParent().args, params)
	
	local lang = fetch_lang(args[2], 1)
	local source = fetch_source(args[1], no_family)
	local sc = fetch_script(args["sc"])

	return args, lang, {
		lang = source,
		sc = sc,
		term = args[3],
		alt = args["cuda"],
		tr = args["tr"],
		ts = args["ts"],
		gloss = args["w"]
	}
end
	

function export.ji(frame)
	local args, lang, term = parse_2_lang_args(frame)
	return require("Modul:etîmolojî").format_derived(lang, term, args["sort"])
end

function export.mirasmayi(frame)
	local args, lang, term = parse_2_lang_args(frame, nil, "no family")
	return require("Modul:etîmolojî").format_inherited(lang, term, args["sort"])
end

function export.deynkiri(frame)
	local args, lang, term = parse_2_lang_args(frame)
	return require("Modul:etîmolojî").format_borrowed(lang, term, args["sort"],
		false, true, "plain")
end

local function qualifier(content)
	if content then
		return table.concat{
			'<i>(',
			content,
			')</i>'
		}
	end
end

local function get_parsed_part(template, lang, args, terms, i)
	local term = terms[i]
	local alt = args["alt"][i]
	local id = args["id"][i]
	local sc = fetch_script(args["sc"][i])

	local tr = args["tr"][i]
	local ts = args["ts"][i]
	local gloss = args["t"][i]
	local pos = args["pos"][i]
	local lit = args["lit"][i]
	local g = args["g"][i]

	if not (term or alt or tr or ts) then
		require("Module:debug").track(template .. "/no term or alt or tr")
		return nil
	else
		return require("Module:links").full_link(
			{ term = term, alt = alt, id = id, lang = lang, sc = sc, tr = tr,
			ts = ts, gloss = gloss, pos = pos, lit = lit,
			genders = g and rsplit(g, ",") or {}
		}, "term", true)
	end
end

local function get_parsed_parts(template, lang, args, terms)
	local parts = {}

	-- Find the maximum index among any of the list parameters.
	local maxmaxindex = 0
	for k, v in pairs(args) do
		if type(v) == "table" and v.maxindex and v.maxindex > maxmaxindex then
			maxmaxindex = v.maxindex
		end
	end

	for index = 1, maxmaxindex do
		table.insert(parts, get_parsed_part(template, lang, args, terms, index))
	end
	
	return parts
end

function export.misc_variant_multiple_terms(frame)
	local params = {
		[1] = {required = true, default = "und"},
		[2] = {list = true, allow_holes = true},

		["t"] = {list = true, allow_holes = true, require_index = true},
		["gloss"] = {list = true, allow_holes = true, require_index = true, alias_of = "t"},
		["w"] = {list = true, allow_holes = true, require_index = true, alias_of = "t"},
		["wate"] = {list = true, allow_holes = true, require_index = true, alias_of = "t"},
		["tr"] = {list = true, allow_holes = true, require_index = true},
		["ts"] = {list = true, allow_holes = true, require_index = true},
		["g"] = {list = true, allow_holes = true, require_index = true},
		["z"] = {list = true, allow_holes = true, require_index = true, alias_of = "g"},
		["id"] = {list = true, allow_holes = true, require_index = true},
		["alt"] = {list = true, allow_holes = true, require_index = true},
		["cuda"] = {list = true, allow_holes = true, require_index = true, alias_of = "g"},
		["lit"] = {list = true, allow_holes = true, require_index = true},
		["pos"] = {list = true, allow_holes = true, require_index = true},
		["cure"] = {list = true, allow_holes = true, require_index = true, alias_of = "pos"},
		["sc"] = {list = true, allow_holes = true, require_index = true},

		["nocap"] = {type = "boolean"}, -- should be processed in the template itself
		["hûr"] = {alias_of = "nocap"},
		["notext"] = {type = "boolean"},
		["nivîs"] = {alias_of = "notext"},
		["nocat"] = {type = "boolean"},
		["nekat"] = {alias_of = "nocat"},
		["sort"] = {},
	}

	local args = require("Module:parameters").process(frame:getParent().args, params)
	
	local lang = fetch_lang(args[1], 1)

	local parts = {}
	if not args["notext"] then
		table.insert(parts, frame.args["text"])
	end
	if #args[2] > 0 or #args["alt"] > 0 then
		if not args["notext"] then
			table.insert(parts, " ")
			table.insert(parts, " ")
		end
		local formatted_terms = get_parsed_parts(mw.ustring.lower(
			-- Remove link and convert uppercase to lowercase to get an
			-- approximation of the original template name.
			rsub(rsub(frame.args["text"], "^%[%[.*|", ""), "%]%]$", "")),
			lang, args, args[2])
		table.insert(parts, require("Module:table").serialCommaJoin(formatted_terms))
	end
	if not args["nocat"] and frame.args["cat"] then
		local categories = {}
		table.insert(categories, frame.args["cat"] .. " bi " .. lang:getCanonicalName())
		table.insert(parts, require("Module:utilities").format_categories(categories, lang, args["sort"]))
	end

	return table.concat(parts)
end


local function desc_or_desc_tree(frame, desc_tree)
	local params
	if desc_tree then
		params = {
			[1] = {required = true, default = "gem-pro"},
			[2] = {required = true, default = "*fuhsaz"},
			["notext"] = { type = "boolean" },
			["noalts"] = { type = "boolean" },
			["noparent"] = { type = "boolean" },
			["nivîs"] = { alias_of = "notext" },

		}
	else
		params = {
			[1] = { required = true },
			[2] = {},
			["alts"] = { type = "boolean" }
		}
	end

	for k, v in pairs({
		[3] = {},
		[4] = { alias_of = "gloss" },
		["z"] = {list = true}, --zayend
		["wate"] = {},
		["cuda"] = {},
		["w"] = { alias_of = "wate" },
		["tr"] = {},
		["ts"] = {},
		["sc"] = {},
		["deyn"] = { type = "boolean" },
		["hdeyn"] = { type = "boolean" },
		["nhd"] = { type = "boolean" },
		["ji"] = { type = "boolean" },
		["yekser"] = { type = "boolean" },
		["yks"] = { alias_of = "yekser" },
		["yksr"] = { alias_of = "yekser" },
		["yeksr"] = { alias_of = "yekser" },
		["qyekser"] = { type = "boolean" },
		["wergirtin"] = { type = "boolean" },
		["unc"] = { type = "boolean" },
		["sclb"] = { type = "boolean" },
		["nolb"] = { type = "boolean" },
		["q"] = {},
		["ceribandin"] = { type = "boolean" },
	}) do
		params[k] = v
	end

	local namespace = mw.title.getCurrentTitle().nsText

	local args
	if frame.args[1] then
		args = require("Modul:parameters").process(frame.args, params)
	else
		args = require("Modul:parameters").process(frame:getParent().args, params)
	end

	if args.sandbox then
		if namespace == "" or namespace == "Jinûvesazî" then
			error('The sandbox module, Modul:descendants tree/sandbox, should not be used in entries.')
		end
	end
	
	local lang = args[1]
	local term = args[2]
	local alt = args[3] or args["cuda"]
	local gloss = args["wate"]
	local tr = args["tr"]
	local ts = args["ts"]
	local sc = args["sc"]

	if namespace == "Şablon" then
		if not ( sc or lang ) then
			sc = "Latn"
		end
		if not lang then
			lang = "ku"
		end
		if not term then
			term = "peyv"
		end
	end
	
	lang = m_languages.getByCode(lang)
		or require("Modul:etymology languages").getByCode(lang)
		or m_languages.err(lang, 1)
		
	local entryLang = require("Modul:ziman").getNonEtymological(lang)
	
	if not desc_tree and entryLang:getType() == "family" then
		error("Zimanê malbatî bi [[Şablon:dû]] nayê bikaranîn.")
	end
	
	if lang:getCode() ~= entryLang:getCode() then
		-- [[Special:WhatLinksHere/Template:tracking/descendant/etymological]]
		require("Modul:debug").track("descendant/etymological")
		require("Modul:debug").track("descendant/etymological/" .. lang:getCode())
	end
	
	if sc then
		sc = require("Modul:scripts").getByCode(sc) or error("Koda skrîptê \"" .. sc .. "\" ne guncav e.")
	end

	local languageName = b.ucfirst(lang:getCanonicalName())

	local link = ""
	
	if term ~= "-" then
		link = require("Modul:links").full_link(
			{
				lang = entryLang,
				sc = sc,
				term = term,
				alt = alt,
				tr = tr,
				ts = ts,
				genders = args["z"],
				gloss = gloss,
			},
			nil,
			true)
	elseif ts or gloss or #args["z"] > 0 then
		-- [[Special:WhatLinksHere/Template:tracking/descendant/no term]]
		require "Modul:debug".track("descendant/no term")
		link = require("Modul:links").full_link(
			{
				lang = entryLang,
				sc = sc,
				ts = ts,
				gloss = gloss,
				genders = args["z"],
			},
			nil,
			true)
		link = link
			:gsub("<small>%[Peyv%?%]</small> ", "")
			:gsub("<small>%[Peyv%?%]</small>&nbsp;", "")
			:gsub("%[%[Kategorî:Peyvên ku skrîpt hewce ye ([^%[%]]+)%]%]", "")
	else -- display no link at all
		-- [[Special:WhatLinksHere/Template:tracking/descendant/no term or annotations]]
		require "Modul:debug".track("descendant/no term or annotations")
	end
	
	local function add_tooltip(text, tooltip)
		return '<span class="desc-arr" title="' .. tooltip .. '">' .. text .. '</span>'
	end
	
	local label, arrow, descendants, alts, semi_learned, calque, partial_calque, semantic_loan, qual
	
	if args["sclb"] then
		if sc then
			label = b.ucfirst(sc:getCanonicalName())
		else
			label = b.ucfirst(require("Modul:scripts").findBestScript(term, lang):getCanonicalName())
		end
	else
		label = languageName
	end
	
	if args["deyn"] then
		arrow = add_tooltip("→", "deynkirî")
	elseif args["hdeyn"] then
		arrow = add_tooltip("→", "deynkirina hînbûyî")
	elseif args["qhd"] then
		arrow = add_tooltip("→", "deynkirina hînbûyî ya qismî")
	elseif args["yekser"] then
		arrow = add_tooltip("→", "wergerandina yekser")
	elseif args["qyekser"] then
		arrow = add_tooltip("→", "wergerandina yekser a qismî")
	elseif args["wergirtin"] then
		arrow = add_tooltip("→", "wergirtina wateyê")
	elseif args["unc"] and not args["der"] then
		arrow = add_tooltip(">", "mîrasmayî")
	else
		arrow = ""
	end
	-- allow der=1 in conjunction with bor=1 to indicate e.g. English "pars recta"
	-- derived and borrowed from Latin "pars".
	if args["der"] then
		arrow = arrow .. add_tooltip("⇒", "wergirtî û bi peyvsaziyê dariştî")
	end
	
	if args["unc"]then
		arrow = arrow .. add_tooltip("?", "nayê zanîn")
	end

	local m_desctree
	if desc_tree or args["alts"] then
		if args.sandbox or require("Modul:yesno")(frame.args.sandbox, false) then
			m_desctree = require("Modul:dara dûnde/ceribandin")
		else
			m_desctree = require("Modul:dara dûnde")
		end
	end

	if desc_tree then
		descendants = m_desctree.getDescendants(entryLang, term, id)
	end
	
	if desc_tree and not args["noalts"] or not desc_tree and args["alts"] then
		-- [[Special:WhatLinksHere/Template:tracking/desc/alts]]
		require("Modul:debug").track("desc/alts")
		alts = m_desctree.getAlternativeForms(entryLang, term)
	end
	
	if args["hdeyn"] then
		learned = " " .. qualifier("hînbûyî")
	else
		learned = ""
	end
	
	if args["qhd"] then
		semi_learned = " " .. qualifier("qismî hinbûyî")
	else
		semi_learned = ""
	end
	
	if args["yekser"] then
		calque = " " .. qualifier("[[Nimînok:Ferhengok#yekser|yekser]]")
	else
		calque = ""
	end
	
	if args["pclq"] then
		partial_calque = " " .. qualifier("[[Nimînok:Ferhengok#yekser|qismî yekser]]")
	else
		partial_calque = ""
	end

	if args["sml"] then
		semantic_loan = " " .. qualifier("[[Nimînok:Ferhengok#wergirtin|wergirtina wateyê]]")
	else
		semantic_loan = ""
	end
	
	if args["q"] then
		qual = " " .. require("Modul:qualifier").format_qualifier(args["q"])
	else
		qual = ""
	end

	if args["noparent"] then
		return descendants
	end
	
	if arrow and arrow ~= "" then
		arrow = arrow .. " "
	end
	
	local linktext = table.concat{link, alts or "", learned, semi_learned, calque,
		partial_calque, semantic_loan, qual, descendants or ""}
	if args["notext"] then
		return linktext
	elseif args["nolb"] then
		return arrow .. linktext
	else
		return table.concat{arrow, label, ":", linktext ~= "" and " " or "", linktext}
	end
end
	
function export.descendant(frame)
	return desc_or_desc_tree(frame, false) .. require("Modul:TemplateStyles")("Modul:etîmolojî/stîl.css")
end

function export.descendants_tree(frame)
	return desc_or_desc_tree(frame, true)
end

return export