Module:Etymology/templates

local export = {}

local m_languages = require("Module:languages")

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("Module:etymology languages").getByCode(code) or not disallow_family and require("Module:families").getByCode(code) if source then return source else error("The language" .. (not disallow_family and ", family" or "") .. " or etymology language code \"" .. code .. "\" is not valid.") end end

local function fetch_script(sc) if sc then return require("Module:scripts").getByCode(sc) or error("The script code \"" .. sc .. "\" is not valid.") else return nil end end

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 = 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 = 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 require("Module:etymology").format_etyl(lang, source, sort_key) end

function export.cognate(frame) local args = frame:getParent.args if args.gloss then require("Module:debug").track("cognate/gloss param") end local params = { [1] = {required = true, default = "und"}, [2] = {},		[3] = {alias_of = "alt"}, [4] = {alias_of = "t"}, ["alt"] = {}, ["g"] = {list = true}, ["id"] = {}, ["lit"] = {}, ["pos"] = {}, ["t"] = {}, ["gloss"] = {alias_of = "t"}, ["tr"] = {}, ["ts"] = {}, ["sc"] = {}, ["sort"] = {}, }	args = require("Module:parameters").process(args, params) local source = fetch_source(args[1]) local sc = fetch_script(args["sc"])

return require("Module:etymology").format_cognate(		{			lang = source,			sc = sc,			term = args[2],			alt = args["alt"],			id = args["id"],			genders = args["g"],			tr = args["tr"],			ts = args["ts"],			gloss = args["t"],			pos = args["pos"],			lit = args["lit"]		},		args["sort"]) end

function export.noncognate(frame) return export.cognate(frame) end

function export.derived(frame) local params = { [1] = {required = true, default = "und"}, [2] = {required = true, default = "und"}, [3] = {},		[4] = {alias_of = "alt"}, [5] = {alias_of = "t"}, ["alt"] = {}, ["g"] = {list = true}, ["gloss"] = {alias_of = "t"}, ["id"] = {}, ["lit"] = {}, ["pos"] = {}, ["t"] = {}, ["tr"] = {}, ["ts"] = {}, ["sc"] = {}, ["sort"] = {}, }	local args = require("Module:parameters").process(frame:getParent.args, params) local lang = fetch_lang(args[1], 1) local source = fetch_source(args[2]) local sc = fetch_script(args["sc"]) return require("Module:etymology").format_derived(		lang, 		{			lang = source,			sc = sc,			term = args[3],			alt = args["alt"],			id = args["id"],			genders = args["g"],			tr = args["tr"],			ts = args["ts"],			gloss = args["t"],			pos = args["pos"],			lit = args["lit"]		},		args["sort"]) end

function export.inherited(frame) local params = { [1] = {required = true, default = "und"}, [2] = {required = true, default = "und"}, [3] = {},		[4] = {alias_of = "alt"}, [5] = {alias_of = "t"}, ["alt"] = {}, ["g"] = {list = true}, ["gloss"] = {alias_of = "t"}, ["id"] = {}, ["lit"] = {}, ["pos"] = {}, ["t"] = {}, ["tr"] = {}, ["ts"] = {}, ["sc"] = {}, ["sort"] = {}, }	local args = require("Module:parameters").process(frame:getParent.args, params) local lang = fetch_lang(args[1], 1) local source = fetch_source(args[2], "no family") local sc = fetch_script(args["sc"])

return require("Module:etymology").format_inherited(		lang,		{			lang = source,			sc = sc,			term = args[3],			alt = args["alt"],			id = args["id"],			genders = args["g"],			tr = args["tr"],			ts = args["ts"],			gloss = args["t"],			pos = args["pos"],			lit = args["lit"]		},		args["sort"]) end

function export.borrowed(frame) local params = { [1] = {required = true, default = "und"}, [2] = {required = true, default = "und"}, [3] = {},		[4] = {alias_of = "alt"}, [5] = {alias_of = "t"}, ["alt"] = {}, ["g"] = {list = true}, ["gloss"] = {alias_of = "t"}, ["id"] = {}, ["lit"] = {}, ["pos"] = {}, ["t"] = {}, ["tr"] = {}, ["ts"] = {}, ["sc"] = {}, ["sort"] = {}, }	local args = require("Module:parameters").process(frame:getParent.args, params) local lang = fetch_lang(args[1], 1) local source = fetch_source(args[2]) local sc = fetch_script(args["sc"]) return require("Module:etymology").format_borrowed(		lang,		{			lang = source,			sc = sc,			term = args[3],			alt = args["alt"],			id = args["id"],			genders = args["g"],			tr = args["tr"],			ts = args["ts"],			gloss = args["t"],			pos = args["pos"],			lit = args["lit"],		},		args["sort"], false, true, "plain") end

function export.learned_borrowed(frame) local args = frame:getParent.args if args.gloss then require("Module:debug").track("learned_borrowed/gloss param") end local params = { [1] = {required = true, default = "und"}, [2] = {required = true, default = "und"}, [3] = {},		[4] = {alias_of = "alt"}, [5] = {alias_of = "t"}, ["alt"] = {}, ["g"] = {list = true}, ["gloss"] = {alias_of = "t"}, ["id"] = {}, ["lit"] = {}, ["pos"] = {}, ["t"] = {}, ["tr"] = {}, ["ts"] = {}, ["sc"] = {}, ["notext"] = {type = "boolean"}, ["nocap"] = {type = "boolean"}, ["sort"] = {}, }	args = require("Module:parameters").process(args, params) local lang = fetch_lang(args[1], 1) local source = fetch_source(args[2]) local sc = fetch_script(args["sc"]) return require("Module:etymology").format_borrowed(		lang,		{			lang = source,			sc = sc,			term = args[3],			alt = args["alt"],			id = args["id"],			genders = args["g"],			tr = args["tr"],			ts = args["ts"],			gloss = args["t"],			pos = args["pos"],			lit = args["lit"],		},		args["sort"], args["nocap"], args["notext"], "learned") end

function export.orthographic_borrowed(frame) local args = frame:getParent.args if args.gloss then require("Module:debug").track("orthographic_borrowed/gloss param") end local params = { [1] = {required = true, default = "und"}, [2] = {required = true, default = "und"}, [3] = {},		[4] = {alias_of = "alt"}, [5] = {alias_of = "t"}, ["alt"] = {}, ["g"] = {list = true}, ["gloss"] = {alias_of = "t"}, ["id"] = {}, ["lit"] = {}, ["pos"] = {}, ["t"] = {}, ["tr"] = {}, ["ts"] = {}, ["sc"] = {}, ["notext"] = {type = "boolean"}, ["nocap"] = {type = "boolean"}, ["sort"] = {}, }	args = require("Module:parameters").process(args, params) local lang = fetch_lang(args[1], 1) local source = fetch_source(args[2]) local sc = fetch_script(args["sc"]) return require("Module:etymology").format_borrowed(		lang,		{			lang = source,			sc = sc,			term = args[3],			alt = args["alt"],			id = args["id"],			genders = args["g"],			tr = args["tr"],			ts = args["ts"],			gloss = args["t"],			pos = args["pos"],			lit = args["lit"],		},		args["sort"], args["nocap"], args["notext"], "orthographic") end

function export.unadapted_borrowed(frame) local args = frame:getParent.args if args.gloss then require("Module:debug").track("unadapted_borrowed/gloss param") end local params = { [1] = {required = true, default = "und"}, [2] = {required = true, default = "und"}, [3] = {},		[4] = {alias_of = "alt"}, [5] = {alias_of = "t"}, ["alt"] = {}, ["g"] = {list = true}, ["gloss"] = {alias_of = "t"}, ["id"] = {}, ["lit"] = {}, ["pos"] = {}, ["t"] = {}, ["tr"] = {}, ["ts"] = {}, ["sc"] = {}, ["notext"] = {type = "boolean"}, ["nocap"] = {type = "boolean"}, ["sort"] = {}, }	args = require("Module:parameters").process(args, params) local lang = fetch_lang(args[1], 1) local source = fetch_source(args[2]) local sc = fetch_script(args["sc"]) return require("Module:etymology").format_borrowed(		lang,		{			lang = source,			sc = sc,			term = args[3],			alt = args["alt"],			id = args["id"],			genders = args["g"],			tr = args["tr"],			ts = args["ts"],			gloss = args["t"],			pos = args["pos"],			lit = args["lit"],		},		args["sort"], args["nocap"], args["notext"], "unadapted") end

function export.calque(frame) local args = frame:getParent.args local params = { [1] = {required = true, default = "und"}, [2] = {required = true, default = "und"}, [3] = {},		[4] = {alias_of = "alt"}, [5] = {alias_of = "t"}, ["alt"] = {}, ["g"] = {list = true}, ["id"] = {}, ["lit"] = {}, ["pos"] = {}, ["t"] = {}, ["tr"] = {}, ["ts"] = {}, ["sc"] = {}, ["sort"] = {}, ["nocap"] = {type = "boolean"}, ["notext"] = {type = "boolean"}, }	-- More informative error message. if args["etyl lang"] or args["etyl term"] or args["etyl t"] or args["etyl tr"] then error(" no longer supports parameters beginning with etyl. " ..			"The parameters supported are similar to those used by " ..			",, " ..			". See Template:calque/documentation for more.") end args = require("Module:parameters").process(args, params) local lang = fetch_lang(args[1], 1) local source = fetch_source(args[2]) local sc	if args.sc then sc = require("Module:scripts").getByCode(args.sc) or error("The script code " .. tostring(args.sc) .. " is not valid.") end return require("Module:etymology").calque(		lang,		{			lang = source,			sc = sc,			term = args[3],			alt = args["alt"],			genders = args["g"],			tr = args["tr"],			ts = args["ts"],			gloss = args["t"],			pos = args["pos"],			lit = args["lit"],		},		args["sort"],		args["nocap"],		args["notext"]) end

function export.semantic_loan(frame) local params = { [1] = {required = true, default = "und"}, [2] = {required = true, default = "und"}, [3] = {},		[4] = {alias_of = "alt"}, [5] = {alias_of = "t"}, ["alt"] = {}, ["g"] = {list = true}, ["id"] = {}, ["lit"] = {}, ["pos"] = {}, ["t"] = {}, ["tr"] = {}, ["ts"] = {}, ["sc"] = {}, ["nocap"] = {type = "boolean"}, ["notext"] = {type = "boolean"}, ["sort"] = {}, ["ger"] = {type = "boolean"}, }	local args = require("Module:parameters").process(frame:getParent.args, params) local lang = fetch_lang(args[1], 1) local source = fetch_source(args[2]) local sc = fetch_script(args["sc"])

return require("Module:etymology").format_semantic_loan(		lang,		{			lang = source,			sc = sc,			term = args[3],			alt = args["alt"],			id = args["id"],			genders = args["g"],			tr = args["tr"],			ts = args["ts"],			gloss = args["t"],			pos = args["pos"],			lit = args["lit"],		},		args["sort"], args["nocap"], args["notext"]) end

function export.psm(frame) local params = { [1] = {required = true, default = "und"}, [2] = {required = true, default = "und"}, [3] = {},		[4] = {alias_of = "alt"}, [5] = {alias_of = "t"}, ["alt"] = {}, ["g"] = {list = true}, ["id"] = {}, ["lit"] = {}, ["pos"] = {}, ["t"] = {}, ["tr"] = {}, ["ts"] = {}, ["sc"] = {}, ["nocap"] = {type = "boolean"}, ["notext"] = {type = "boolean"}, ["sort"] = {}, }	local args = require("Module:parameters").process(frame:getParent.args, params) local lang = fetch_lang(args[1], 1) local source = fetch_source(args[2]) local sc = fetch_script(args["sc"])

return require("Module:etymology").psm(		lang,		{			lang = source,			sc = sc,			term = args[3],			alt = args["alt"],			id = args["id"],			genders = args["g"],			tr = args["tr"],			ts = args["ts"],			gloss = args["t"],			pos = args["pos"],			lit = args["lit"],		},		args["sort"], args["nocap"], args["notext"]) end

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

function export.descendant(frame) local namespace = mw.title.getCurrentTitle.nsText local params = { [1] = { required = true }, [2] = {},		[3] = {},		[4] = { alias_of = "gloss" }, ["g"] = {list = true}, ["gloss"] = {}, ["id"] = {}, ["lit"] = {}, ["pos"] = {}, ["t"] = { alias_of = "gloss" }, ["tr"] = {}, ["ts"] = {}, ["sc"] = {}, ["bor"] = { type = "boolean" }, ["der"] = { type = "boolean" }, ["clq"] = { type = "boolean" }, ["cal"] = { alias_of = "clq" }, ["calq"] = { alias_of = "clq" }, ["calque"] = { alias_of = "clq" }, ["sl"] = { type = "boolean" }, ["semantic loan"] = { alias_of = "sl" }, ["alts"] = { type = "boolean" }, ["sclb"] = { type = "boolean" }, }	local args = require("Module:parameters").process(frame:getParent.args, params) local lang = args[1] local term = args[2] local alt = args[3] local gloss = args["gloss"] local tr = args["tr"] local ts = args["ts"] local sc = args["sc"] if namespace == "Template" then if not ( sc or lang ) then sc = "Latn" end if not lang then lang = "en" end if not term then term = "word" end end lang = m_languages.getByCode(lang) or require("Module:etymology languages").getByCode(lang) or m_languages.err(lang, 1) local entryLang = require("Module:etymology").getNonEtymological(lang) if entryLang:getType == "family" then error("Cannot use language family code in Template:desc.") end if lang:getCode ~= entryLang:getCode then -- Special:WhatLinksHere/Template:tracking/descendant/etymological require("Module:debug").track("descendant/etymological") require("Module:debug").track("descendant/etymological/" .. lang:getCode) end if sc then sc = require("Module:scripts").getByCode(sc) or error("The script code \"" .. sc .. "\" is not valid.") end local languageName = lang:getCanonicalName languageName = mw.ustring.gsub(languageName, "^Proto%-", "") local link = "" if term ~= "-" then link = require("Module:links").full_link(			{				lang = entryLang,				sc = sc,				term = term,				alt = alt,				id = args["id"],				tr = tr,				ts = ts,				genders = args["g"],				gloss = gloss,				pos = args["pos"],				lit = args["lit"],			},			nil,			true) elseif ts or gloss then -- Special:WhatLinksHere/Template:tracking/descendant/no term require "Module:debug".track("descendant/no term") link = require("Module:links").full_link(			{				lang = entryLang,				sc = sc,				ts = ts,				gloss = gloss,			},			nil,			true) link = link :gsub(" %[Term%?%] ", "") :gsub("%[%[Category:[^%[%]]+ term requests%]%]", "") else -- display no link at all -- Special:WhatLinksHere/Template:tracking/descendant/no term or annotations require "Module:debug".track("descendant/no term or annotations") end local function add_tooltip(text, tooltip) return ' ' .. text .. ' '	end local label, arrow, alts, calque, semantic_loan if args["sclb"] then if sc then label = sc:getCanonicalName else label = require("Module:scripts").findBestScript(term, lang):getCanonicalName end else label = languageName end if args["bor"] then arrow = add_tooltip("→ ", "borrowed") elseif args["clq"] then arrow = add_tooltip("→ ", "calque") elseif args["sl"] then arrow = add_tooltip("→ ", "semantic loan") elseif args["der"] then arrow = add_tooltip("⇒ ", "derived by addition of morphemes") else arrow = "" end if args["alts"] then -- Special:WhatLinksHere/Template:tracking/desc/alts require("Module:debug").track("desc/alts") alts = require("Module:descendants tree").getAlternativeForms(entryLang, term) end if args["clq"] then calque = " " .. qualifier("calque") else calque = "" end if args["sl"] then semantic_loan = " " .. qualifier("semantic loan") else semantic_loan = "" end return table.concat{arrow, label, ": ", link, alts or "", calque, semantic_loan} end

-- Implementation of miscellaneous templates such as, , --, , and 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"] = {}, }	local args = require("Module:parameters").process(frame:getParent.args, params) local lang = fetch_lang(args[1], 1) local sc = 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 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

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

-- Implementation of miscellaneous templates such as that can take -- multiple terms. Doesn't handle or, which display -- + signs between elements and use compound_like in Module:compound/templates. 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"}, ["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}, ["id"] = {list = true, allow_holes = true, require_index = true}, ["alt"] = {list = true, allow_holes = true, require_index = true}, ["lit"] = {list = true, allow_holes = true, require_index = true}, ["pos"] = {list = true, allow_holes = true, require_index = true}, ["sc"] = {list = true, allow_holes = true, require_index = true},

["nocap"] = {type = "boolean"}, -- should be processed in the template itself ["notext"] = {type = "boolean"}, ["nocat"] = {type = "boolean"}, ["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, frame.args["oftext"] or "of") 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, lang:getCanonicalName .. " " .. frame.args["cat"]) 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 = 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