يمكن إنشاء صفحة توثيق الوحدة في وحدة:affix/templates/شرح

local m_compound = require("Module:affix")
local m_languages = require("Module:languages")
local m_debug = require("Module:debug")

local export = {}


local function if_not_empty(val)
	if val == "" then
		return nil
	else
		return val
	end
end


local function to_boolean(val)
	if not val or val == "" then
		return false
	else
		return true
	end
end


local function get_part(template, args, offset, i)
	offset = offset or 0
	
	local term = if_not_empty(args[i + offset])
	local alt = if_not_empty(args["alt" .. i])
	local id = if_not_empty(args["id" .. i])
	local lang = if_not_empty(args["lang" .. i])
	local sc = if_not_empty(args["sc" .. i])
	
	local tr = if_not_empty(args["tr" .. i])
	local gloss = if_not_empty(args["t" .. i] or args["gloss" .. i])
	local pos = if_not_empty(args["pos" .. i])
	local lit = if_not_empty(args["lit" .. i])
	
	if lang then
		lang =
			m_languages.getByCode(lang) or
			require("Module:etymology languages").getByCode(lang) or
			m_languages.err(lang, "lang" .. i)
	end
	
	if sc then
		sc = require("Module:scripts").getByCode(sc) or error("The script code \"" .. sc .. "\" is not valid.")
	end
	
	if not (term or alt or tr) then
		require("Module:debug").track(template .. "/no term or alt or tr")
		return nil
	else
		return { term = term, alt = alt, id = id, lang = lang, sc = sc, tr = tr, gloss = gloss, pos = pos, lit = lit }
	end
end


local function get_parts(template, args, offset, i)
	local parts = {}
	i = i or 1

	-- Temporary tracking code for bare arguments of which numeric variants
	-- are recognized, but where the bare argument shouldn't occur.
	-- Eventually, this should be converted to use [[Module:parameters]] and
	-- the unrecognized arguments removed.
	local no_bare_args = {"tr", "alt", "id", "gloss", "t", "lit"}
	for _, bare_arg in ipairs(no_bare_args) do
		if args[bare_arg] then
			m_debug.track{
				template .. "/bare-" .. bare_arg,
				template .. "/bare-arg"
			}
			mw.log("bare arg in {{" .. template .. "}} was ignored: |" .. bare_arg .. "=" .. tostring(args[bare_arg]))
		end
	end
	
	while true do
		local part = get_part(template, args, offset, i)
		
		if not part then
			break
		end
		
		table.insert(parts, part)
		
		i = i + 1
	end
	
	return parts
end


function export.affix(frame)
	local args = frame:getParent().args
	
	local lang = if_not_empty(args[1])
	local sc = if_not_empty(args["sc"] or "")
	local pos = if_not_empty(args["pos"])
	local sort_key = if_not_empty(args["sort"])
	local nocat = to_boolean(args["nocat"])
	
	if args.lang then
		error('The |lang= parameter is not used by the affix template. Place the language code in parameter 1 instead.')
	end
	
	if not lang then
		if mw.title.getCurrentTitle().nsText == "Template" then
			lang = "und"
		else
			error("Place the language code in parameter 1 of the affix template.")
		end
	end
	
	lang = m_languages.getByCode(lang) or m_languages.err(lang, 1)
	if sc then
		sc = require("Module:scripts").getByCode(sc) or error("The script code \"" .. sc .. "\" is not valid.")
	end
	
	local parts = get_parts("affix", args, 1)
	
	-- There must be at least one part to display.
	if #parts < 1 then
		if mw.title.getCurrentTitle().nsText == "Template" then
			parts = { {term = "prefix-"}, {term = "base"}, {term = "-suffix"} }
		else
			error("You must provide at least one part.")
		end
	end
	
	return m_compound.show_affixes(lang, sc, parts, pos, sort_key, nocat)
end


function export.compound(frame)
	local args = frame:getParent().args
	local compat = true
	
	local lang = if_not_empty(args["lang"])
	local sc = if_not_empty(args["sc"] or "")
	local pos = if_not_empty(args["pos"])
	local sort_key = if_not_empty(args["sort"])
	local nocat = to_boolean(args["nocat"])
	
	if not lang then
		compat = false
		lang = if_not_empty(args[1])
	end
	
	if not lang and mw.title.getCurrentTitle().nsText == "Template" then
		lang = "und"
	end
	
	lang = m_languages.getByCode(lang) or m_languages.err(lang, compat and "lang" or 1)
	if sc then
		sc = require("Module:scripts").getByCode(sc) or error("The script code \"" .. sc .. "\" is not valid.")
	end
	
	local parts = get_parts("compound", args, compat and 0 or 1)
	
	-- There must be at least one part to display.
	if #parts < 1 then
		if mw.title.getCurrentTitle().nsText == "Template" then
			parts = { {term = "first"}, {term = "second"} }
		else
			error("You must provide at least one part of a compound.")
		end
	end
	
	return m_compound.show_compound(lang, sc, parts, pos, sort_key, nocat)
end


function export.interfix_compound(frame)
	local args = frame:getParent().args
	
	local lang = if_not_empty(args[1])
	local sc = if_not_empty(args["sc"] or "")
	local sort_key = if_not_empty(args["sort"])
	local nocat = to_boolean(args["nocat"])
	local pos = if_not_empty(args["pos"])
	
	if not lang then
		if mw.title.getCurrentTitle().nsText == "Template" then
			lang = "und"
		else
			error("Language code has not been specified. Please pass parameter 1 to the template.")
		end
	end
	
	lang = m_languages.getByCode(lang) or m_languages.err(lang, 1)
	if sc then
		sc = require("Module:scripts").getByCode(sc) or error("The script code \"" .. sc .. "\" is not valid.")
	end
	
	local parts = get_parts("interfix-compound", args, 1)
	local base1 = parts[1]
	local interfix = parts[2]
	local base2 = parts[3]
	
	-- Just to make sure someone didn't use the template in a silly way
	if not (base1 and interfix and base2) then
		if mw.title.getCurrentTitle().nsText == "Template" then
			base1 = {term = "base1"}
			interfix = {term = "interfix"}
			base2 = {term = "base2"}
		else
			error("You must provide a base term, an interfix and a second base term.")
		end
	end
	
	return m_compound.show_interfix_compound(lang, sc, base1, interfix, base2, pos, sort_key, nocat)
end


function export.circumfix(frame)
	local args = frame:getParent().args
	local compat = true
	
	local lang = if_not_empty(args["lang"])
	local sc = if_not_empty(args["sc"] or "")
	local sort_key = if_not_empty(args["sort"])
	local nocat = to_boolean(args["nocat"])
	local pos = if_not_empty(args["pos"])
	
	if not lang then
		compat = false
		lang = if_not_empty(args[1])
	end
	
	if not lang and mw.title.getCurrentTitle().nsText == "Template" then
		lang = "und"
	end
	
	lang = m_languages.getByCode(lang) or m_languages.err(lang, compat and "lang" or 1)
	if sc then
		sc = require("Module:scripts").getByCode(sc) or error("The script code \"" .. sc .. "\" is not valid.")
	end
	
	local parts = get_parts("circumfix", args, compat and 0 or 1)
	local prefix = parts[1]
	local base = parts[2]
	local suffix = parts[3]
	
	-- Just to make sure someone didn't use the template in a silly way
	if not (prefix and base and suffix) then
		if mw.title.getCurrentTitle().nsText == "Template" then
			prefix = {term = "circumfix", alt = "prefix"}
			base = {term = "base"}
			suffix = {term = "circumfix", alt = "suffix"}
		else
			error("You must specify a prefix part, a base term and a suffix part.")
		end
	end
	
	return m_compound.show_circumfix(lang, sc, prefix, base, suffix, pos, sort_key, nocat)
end


function export.confix(frame)
	local args = frame:getParent().args
	local compat = true
	
	local lang = if_not_empty(args["lang"])
	local sc = if_not_empty(args["sc"] or "")
	local sort_key = if_not_empty(args["sort"])
	local nocat = to_boolean(args["nocat"])
	local pos = if_not_empty(args["pos"])
	
	if not lang then
		compat = false
		lang = if_not_empty(args[1])
	end
	
	if not lang and mw.title.getCurrentTitle().nsText == "Template" then
		lang = "und"
	end
	
	lang = m_languages.getByCode(lang) or m_languages.err(lang, compat and "lang" or 1)
	if sc then
		sc = require("Module:scripts").getByCode(sc) or error("The script code \"" .. sc .. "\" is not valid.")
	end
	
	local parts = get_parts("confix", args, compat and 0 or 1)
	local prefix = parts[1]
	local base = #parts >= 3 and parts[2] or nil
	local suffix = #parts >= 3 and parts[3] or parts[2]
	
	-- Just to make sure someone didn't use the template in a silly way
	if not (prefix and suffix) then
		if mw.title.getCurrentTitle().nsText == "Template" then
			prefix = {term = "prefix"}
			suffix = {term = "suffix"}
		else
			error("You must specify a prefix part, an optional base term and a suffix part.")
		end
	end
	
	return m_compound.show_confix(lang, sc, prefix, base, suffix, pos, sort_key, nocat)
end


function export.infix(frame)
	local args = frame:getParent().args
	local compat = true
	
	local lang = if_not_empty(args["lang"])
	local sc = if_not_empty(args["sc"] or "")
	local sort_key = if_not_empty(args["sort"])
	local nocat = to_boolean(args["nocat"])
	local pos = if_not_empty(args["pos"])
	
	if not lang then
		compat = false
		lang = if_not_empty(args[1])
	end
	
	if not lang and mw.title.getCurrentTitle().nsText == "Template" then
		lang = "und"
	end
	
	lang = m_languages.getByCode(lang) or m_languages.err(lang, compat and "lang" or 1)
	if sc then
		sc = require("Module:scripts").getByCode(sc) or error("The script code \"" .. sc .. "\" is not valid.")
	end
	
	local parts = get_parts("infix", args, compat and 0 or 1)
	local base = parts[1]
	local infix = parts[2]
	
	-- Just to make sure someone didn't use the template in a silly way
	if not (base and infix) then
		if mw.title.getCurrentTitle().nsText == "Template" then
			base = {term = "base"}
			infix = {term = "infix"}
		else
			error("You must provide a base term and an infix.")
		end
	end
	
	return m_compound.show_infix(lang, sc, base, infix, pos, sort_key, nocat)
end


function export.prefix(frame)
	local args = frame:getParent().args
	local compat = true
	
	local lang = if_not_empty(args["lang"])
	local sc = if_not_empty(args["sc"] or "")
	local sort_key = if_not_empty(args["sort"])
	local nocat = to_boolean(args["nocat"])
	local pos = if_not_empty(args["pos"])
	
	if not lang then
		compat = false
		lang = if_not_empty(args[1])
	end
	
	if not lang and mw.title.getCurrentTitle().nsText == "Template" then
		lang = "und"
	end
	
	lang = m_languages.getByCode(lang) or m_languages.err(lang, compat and "lang" or 1)
	if sc then
		sc = require("Module:scripts").getByCode(sc) or error("The script code \"" .. sc .. "\" is not valid.")
	end
	
	local prefixes = get_parts("prefix", args, compat and 0 or 1)
	local base = nil
	
	if #prefixes >= 2 then
		base = prefixes[#prefixes]
		prefixes[#prefixes] = nil
	end
	
	-- Just to make sure someone didn't use the template in a silly way
	if #prefixes == 0 then
		if mw.title.getCurrentTitle().nsText == "Template" then
			base = {term = "base"}
			prefixes = { {term = "prefix"} }
		else
			error("You must provide at least one prefix.")
		end
	end
	
	return m_compound.show_prefixes(lang, sc, prefixes, base, pos, sort_key, nocat)
end


function export.suffix(frame)
	local args = frame:getParent().args
	local compat = true
	
	local lang = if_not_empty(args["lang"])
	local sc = if_not_empty(args["sc"] or "")
	local sort_key = if_not_empty(args["sort"])
	local nocat = to_boolean(args["nocat"])
	local pos = if_not_empty(args["pos"])
	
	if not lang then
		compat = false
		lang = if_not_empty(args[1])
	end
	
	if not lang and mw.title.getCurrentTitle().nsText == "Template" then
		lang = "und"
	end
	
	lang = m_languages.getByCode(lang) or m_languages.err(lang, compat and "lang" or 1)
	if sc then
		sc = require("Module:scripts").getByCode(sc) or error("The script code \"" .. sc .. "\" is not valid.")
	end
	
	local base = get_part("suffix", args, compat and 0 or 1, 1)
	local suffixes = get_parts("suffix", args, compat and 0 or 1, 2)
	
	-- Just to make sure someone didn't use the template in a silly way
	if #suffixes == 0 then
		if mw.title.getCurrentTitle().nsText == "Template" then
			base = {term = "base"}
			suffixes = { {term = "suffix"} }
		else
			error("You must provide at least one suffix.")
		end
	end
	
	return m_compound.show_suffixes(lang, sc, base, suffixes, pos, sort_key, nocat)
end


function export.transfix(frame)
	local params = {
		[1] = {required = true, default = "und"},
		[2] = {required = true, default = "base"},
		[3] = {required = true, default = "transfix"},
		
		["nocat"] = {type = "boolean"},
		["pos"] = {},
		["sc"] = {},
		["sort"] = {},
	}
	
	local args = require("Module:parameters").process(frame:getParent().args, params)
	
	local lang = m_languages.getByCode(args[1]) or m_languages.err(lang, 1)
	local sc = args["sc"]
	if sc then
		sc = require("Module:scripts").getByCode(sc) or error("The script code \"" .. sc .. "\" is not valid.")
	end
	
	local base = {term = args[2]}
	local transfix = {term = args[3]}
	
	return m_compound.show_transfix(lang, sc, base, transfix, args["pos"], args["sort"], args["nocat"])
end


function export.derivsee(frame)
	local args = frame:getParent().args
	
	local derivtype = frame.args["derivtype"]
	local mode = if_not_empty(frame.args["mode"])
	local lang
	local term
	
	if derivtype == "PIE root" then
		lang = "ine-pro"
		term = if_not_empty(args[1] or args["head"])

		if term then
			term = "*" .. term .. "-"
		end
	else
		lang = args[1] or (mw.title.getCurrentTitle().nsText == "Template" and "und") or error("Language code has not been specified. Please pass parameter 1 to the template.")
		term = if_not_empty(args[2] or args["head"])
	end
	
	local id = if_not_empty(args["id"])
	local sc = if_not_empty(args["sc"])
	local pos = if_not_empty(args["pos"])
	
	lang = m_languages.getByCode(lang)
	if sc then
		sc = require("Module:scripts").getByCode(sc) or error("The script code \"" .. sc .. "\" is not valid.")
	end
	
	pos = pos or "word"
	
	-- Pluralize the part of speech name
	if pos:find("[sx]$") then
		pos = pos .. "es"
	else
		pos = pos .. "s"
	end
	
	if not term then
		if lang:getType() == "reconstructed" then
			term = "*" .. mw.title.getCurrentTitle().subpageText
		elseif lang:getType() == "appendix-constructed" then
			term = mw.title.getCurrentTitle().subpageText
		elseif mw.title.getCurrentTitle().nsText == "Reconstruction" then
			term = "*" .. mw.title.getCurrentTitle().subpageText
		else
			term = mw.title.getCurrentTitle().subpageText
		end
	end
	
	local category = nil
	
	if derivtype == "PIE root" then
		return frame:callParserFunction{
			name = "#categorytree",
			args = {
				"Terms derived from the PIE root " .. term .. (id and " (" .. id .. ")" or ""),
				depth = 0,
				class = "\"derivedterms\"",
				mode = mode,
				}
			}
	end
	
	if derivtype == "compound" then
		category = lang:getCanonicalName() .. " compounds with " .. term
	else
		category = lang:getCanonicalName() .. " " .. pos .. " " .. derivtype .. "ed with " .. term .. (id and " (" .. id .. ")" or "")
	end
	
	return frame:callParserFunction{
		name = "#categorytree",
		args = {
			category,
			depth = 0,
			class = "\"derivedterms" .. (sc and " " .. sc:getCode() or "") .. "\"",
			namespaces = "-" .. (mw.title.getCurrentTitle().nsText == "Reconstruction" and " Reconstruction" or ""),
			}
		}
end

return export