Modul:etimologi/templat

local export = {}

local m_languages = require("Module:languages")
local m_etymology = require("Module:etymology")
local m_internal = require("Module:etymology/templates/internal")


function export.etyl(frame)
	local params = {
		[1] = {required = true, default = "und"},
		[2] = {},
		["sort"] = {},
	}
	
	local args = require("Module:parameters").process(frame:getParent().args, params)
	
	local source = m_internal.fetch_source(args[1])
	local lang = args[2]
	local sort_key = args["sort"]
	
	-- Empty language means English, but "-" means no language. Yes, confusing...
	if not lang then
		lang = "en"
	elseif lang == "-" then
		lang = nil
	end
	if lang then
		lang = m_internal.fetch_lang(lang, 2)
	end
	if lang and (lang:getCode() == "la" or lang:getCode() == "nl") then
		require("Module:debug").track("etyl/" .. lang:getCode())
		require("Module:debug").track("etyl/" .. lang:getCode() .. "/" .. source:getCode())
	end
	
	return m_etymology.format_etyl(lang, source, sort_key)
end

function export.learned_borrowing(frame)
	if frame:getParent().args.gloss then
		require("Module:debug").track("learned_borrowing/gloss param")
	end

	local args, lang, term = m_internal.parse_2_lang_args(frame, "has text")
	return m_etymology.format_borrowed(lang, term, args["sort"],
		args["nocap"], args["notext"], args["nocat"], "learned")
end

function export.semi_learned_borrowing(frame)
	if frame:getParent().args.gloss then
		require("Module:debug").track("semi_learned_borrowing/gloss param")
	end

	local args, lang, term = m_internal.parse_2_lang_args(frame, "has text")
	return m_etymology.format_borrowed(lang, term, args["sort"],
		args["nocap"], args["notext"], args["nocat"], "semi-learned")
end

function export.orthographic_borrowing(frame)
	if frame:getParent().args.gloss then
		require("Module:debug").track("orthographic_borrowing/gloss param")
	end

	local args, lang, term = m_internal.parse_2_lang_args(frame, "has text")
	return m_etymology.format_borrowed(lang, term, args["sort"],
		args["nocap"], args["notext"], args["nocat"], "orthographic")
end

function export.unadapted_borrowing(frame)
	if frame:getParent().args.gloss then
		require("Module:debug").track("unadapted_borrowing/gloss param")
	end

	local args, lang, term = m_internal.parse_2_lang_args(frame, "has text")
	return m_etymology.format_borrowed(lang, term, args["sort"],
		args["nocap"], args["notext"], args["nocat"], "unadapted")
end

function export.calque(frame)
	local args = frame:getParent().args
	
	-- More informative error message.
	if args["etyl lang"] or args["etyl term"] or args["etyl t"] or args["etyl tr"] then
		error("{{[[Template:calque|calque]]}} no longer supports parameters beginning with etyl. " ..
			"The parameters supported are similar to those used by " ..
			"{{[[Template:der|der]]}}, {{[[Template:inh|inh]]}}, " ..
			"{{[[Template:bor|bor]]}}. See [[Template:calque/documentation]] for more.")
	end
	
	local args, lang, term = m_internal.parse_2_lang_args(frame, "has text")
	return m_etymology.calque(lang, term, args["sort"],
		args["nocap"], args["notext"], args["nocat"])
end

function export.partial_calque(frame)
	if frame:getParent().args.gloss then
		require("Module:debug").track("partial_calque/gloss param")
	end

	local args, lang, term = m_internal.parse_2_lang_args(frame, "has text")
	return m_etymology.partial_calque(lang, term, args["sort"],
		args["nocap"], args["notext"], args["nocat"])
end

function export.semantic_loan(frame)
	local args, lang, term = m_internal.parse_2_lang_args(frame, "has text")
	return m_etymology.semantic_loan(lang, term, args["sort"],
		args["nocap"], args["notext"], args["nocat"])
end

function export.psm(frame)
	local args, lang, term = m_internal.parse_2_lang_args(frame, "has text")
	return m_etymology.phono_semantic_matching(lang, term, args["sort"],
		args["nocap"], args["notext"], args["nocat"])
end

-- Implementation of miscellaneous templates such as {{back-formation}}, {{clipping}},
-- {{ellipsis}}, {{rebracketing}}, and {{reduplication}} that have a single
-- associated term.
function export.misc_variant(frame)
	local params = {
		[1] = {required = true, default = "und"},
		[2] = {},
		[3] = {alias_of = "alt"},
		[4] = {alias_of = "t"},
		
		["alt"] = {},
		["gloss"] = {alias_of = "t"},
		["g"] = {list = true},
		["id"] = {},
		["lit"] = {},
		["pos"] = {},
		["t"] = {},
		["tr"] = {},
		["ts"] = {},
		["sc"] = {},
		
		["nocap"] = {type = "boolean"}, -- should be processed in the template itself
		["notext"] = {type = "boolean"},
		["nocat"] = {type = "boolean"},
		["sort"] = {},
	}
	
	-- |ignore-params= parameter to module invocation specifies
	-- additional parameter names to allow  in template invocation, separated by
	-- commas. They must consist of ASCII letters or numbers or hyphens.
	local ignore_params = frame.args["ignore-params"]
	if ignore_params then
		ignore_params = mw.text.trim(ignore_params)
		if not ignore_params:match "^[%w%-,]+$" then
			error("Invalid characters in |ignore-params=: " .. ignore_params:gsub("[%w%-,]+", ""))
		end
		for param in ignore_params:gmatch "[%w%-]+" do
			if params[param] then
				error("Duplicate param |" .. param
					.. " in |ignore-params=: already specified in params")
			end
			params[param] = {}
		end
	end
	
	local args = require("Module:parameters").process(frame:getParent().args, params)
	
	local lang = m_internal.fetch_lang(args[1], 1)
	local sc = m_internal.fetch_script(args["sc"])

	local parts = {}
	if not args["notext"] then
		table.insert(parts, frame.args["text"])
	end
	if args[2] or args["alt"] then
		if not args["notext"] then
			table.insert(parts, " ")
			table.insert(parts, frame.args["oftext"] or "of")
			table.insert(parts, " ")
		end
		table.insert(parts, require("Module:links").full_link(
			{
				lang = lang,
				sc = sc,
				term = args[2],
				alt = args["alt"],
				id = args["id"],
				tr = args["tr"],
				ts = args["ts"],
				genders = args["g"],
				gloss = args["t"],
				pos = args["pos"],
				lit = args["lit"],
			},
			"term",
			true))
	end
	-- Allow |cat=, |cat2=, |cat3=, etc. They must be sequential. If |cat=
	-- is not defined, |cat2= will not be checked. Empty categories are ignored.
	local categories = {}
	if not args["nocat"] and frame.args["cat"] then
		local cat_number
		while true do
			local cat = frame.args["cat" .. (cat_number or "")]
			if not cat then break end
			cat = mw.text.trim(cat)
			if cat ~= "" then
				table.insert(categories, lang:getCanonicalName() .. " " .. cat)
			end
			cat_number = (cat_number or 1) + 1
		end
	end
	if #categories > 0 then
		table.insert(
			parts,
			require("Module:utilities/format_categories")(categories, lang, args["sort"]))
	end

	return table.concat(parts)
end

-- Implementation of miscellaneous templates such as {{unknown}} that have no
-- associated terms.
function export.misc_variant_no_term(frame)
	local params = {
		[1] = {required = true, default = "und"},

		["title"] = {},
		["nocap"] = {type = "boolean"}, -- should be processed in the template itself
		["notext"] = {type = "boolean"},
		["nocat"] = {type = "boolean"},
		["sort"] = {},
	}

	if frame.args["title2_alias"] then
		params[2] = {alias_of = "title"}
	end
	
	local args = require("Module:parameters").process(frame:getParent().args, params)
	
	local lang = m_internal.fetch_lang(args[1], 1)

	local parts = {}
	if not args["notext"] then
		table.insert(parts, args["title"] or frame.args["text"])
	end
	if not args["nocat"] and frame.args["cat"] then
		local categories = {}
		table.insert(categories, lang:getCanonicalName() .. " " .. frame.args["cat"])
		table.insert(parts, require("Module:utilities/format_categories")(categories, lang, args["sort"]))
	end

	return table.concat(parts)
end

return export