Mòdul:compost

De Viccionari
Icona de documentació de mòdul Documentació del mòdul[mostra] [modifica] [refresca]

A continuació es mostra la documentació transclosa de la subpàgina /ús. [salta a la caixa de codi]


Mòdul de suport per {{etim-comp}}.

local p = {}

local m_links = require("Module:enllaç")
local m_utilities = require("Module:utilitats")
local m_languages = require("Module:llengua")
local m_general = require("Module:ca-general")

local rsub = mw.ustring.gsub
local usub = mw.ustring.sub
local ulen = mw.ustring.len
local rfind = mw.ustring.find
local rmatch = mw.ustring.match

-- FIXME: should be script-based
-- But we can't do that unless we do script detection before linking.
local hyphens = {
	["ar"] = "ـ",
	["fa"] = "ـ",
	["he"] = "־",
	["yi"] = "־",
}

local no_displayed_hyphens = {
	["ja"] = true,
	["ko"] = true,
	["lo"] = true,
	["th"] = true,
	["zh"] = true,
}

local function linkTerm(terminfo, display_term, lang, sc, sort_key)
	local terminfo_new = require("Module:TableTools").shallowClone(terminfo)
	
	terminfo_new.term = display_term
	terminfo_new.lang = terminfo_new.lang or lang
	terminfo_new.sc = terminfo_new.sc or sc
	
	return m_links.full_link(terminfo_new, "terme", false)
end

-- ABOUT TEMPLATE AND DISPLAY HYPHENS:
--
-- The "template hyphen" is the hyphen character (always a single Unicode char)
-- that is used in template calls to indicate that a term is an affix.
-- Normally this is just the regular hyphen character "-", but for some
-- non-Latin-script languages (currently only right-to-left languages), it
-- is different.
--
-- The "display hyphen" is the string (which might be an empty string) that
-- is added onto a term as displayed (and linked), to indicate that a term
-- is an affix. It is different for East Asian languages, which use a regular
-- hyphen in calls to {{affix}} and such to indicate an affix, but which
-- don't include any visible hyphen in the displayed and linked terms.
-- Currently this is the only situation where template and display hyphens
-- are different, but the code below is written generally enough to handle
-- arbitrary display hyphens.

-- Get the single character that signals an affix in template params.
local function getTemplateHyphen(lang, sc)
	--The script will be "Latn" for transliterations.
	if (sc or lang.sc) == "Latn" then
		return "-"
	else
		return hyphens[lang.code] or "-"
	end
end

-- Get the string (possibly empty) that signals an affix in displayed
-- and linked terms. This differs from getTemplateHyphen() in various
-- East Asian languages, where the parameters to {{affix}} will still
-- contain a hyphen to signal an affix, but the affix will be displayed
-- and linked without such a hyphen.
local function getDisplayHyphen(lang, sc)
	--The script will be "Latn" for transliterations.
	if (sc or lang.sc) == "Latn" then
		return "-"
	end
	if no_displayed_hyphens[lang.code] then
		return ""
	else
		return hyphens[lang.code] or "-"
	end
end

-- Find the type of affix ("prefix", "infix", "suffix", "circumfix" or nil
-- for non-affix). Return the affix type and the displayed/linked equivalent
-- of the part (normally the same as the part but will be different for some
-- East Asian languages that use a regular hyphen as an affix-signaling
-- hyphen but have no displayed hyphen).
local function getAffixType(lang, sc, part)
	if not part then
		return nil, nil
	end
	
	local thyph = getTemplateHyphen(lang, sc)
	local dhyph = getDisplayHyphen(lang, sc)
	
	if part:find("^%^") then
		-- If part begins with ^, it's not an affix no matter what.
		-- Strip off the ^ and return "no affix".
		return nil, usub(part, 2)
	end
	
	-- Remove an asterisk if the morpheme is reconstructed and add it in the end.
	local reconstructed = ""
	if part:find("^%*") then
		reconstructed = "*"
		part = part:gsub("^%*", "")
	end
	
	local affix_type = nil
	
	local begins_with_hyphen = usub(part, 1, 1) == thyph
	local ends_with_hyphen = usub(part, -1) == thyph
	if begins_with_hyphen and ends_with_hyphen then
		affix_type = "infix"
		-- Don't do anything if the part is a single hyphen.
		-- This is probably correct.
		if thyph ~= dhyph and ulen(part) > 1 then
			part = dhyph .. rsub(part, "^.(.-).$", "%1") .. dhyph
		end
	elseif ends_with_hyphen then
		affix_type = "prefix"
		if thyph ~= dhyph then
			part = rsub(part, "^(.-).$", "%1") .. dhyph
		end
	elseif begins_with_hyphen then
		affix_type = "sufix"
		if thyph ~= dhyph then
			part = dhyph .. usub(part, 2)
		end
	elseif usub(part, 1, 1) == "+" then
		affix_type = "desinència"
		if rfind(part, "[Ø0∅⌀ø]") then
			part = "Ø"
		else
			part = dhyph .. usub(part, 2)
		end
	elseif usub(part, 1, 1) == "√" then
		affix_type = "arrel"
	end
	
	part = reconstructed .. part
	return affix_type, part
end

local function getPart(args, i)
	local term = args[i + 1]; if term == "" then term = nil end
	local alt = args["alt" .. i]; if alt == "" then alt = nil end
	local id = args["id" .. i]; if id == "" then id = nil end
	local langcode = args["lang" .. i]; if langcode == "" then langcode = nil end
	local sc = args["sc" .. i]; if sc == "" then sc = nil end
	local ordre = args["sort" .. i]; if ordre == "" then ordre = nil end
	
	local tr = args["tr" .. i]; if tr == "" then tr = nil end
	local gloss = args["t" .. i] or args["gloss" .. i]; if gloss == "" then gloss = nil end
	local pos = args["pos" .. i]; if pos == "" then pos = nil end
	local lit = args["lit" .. i]; if lit == "" then lit = nil end

	if langcode and not m_languages.existeix(langcode) then
		error("El codi de llengua \"" .. langcode .. "\" no és vàlid.")
	end
	
	if term or alt then
		local lang
		if langcode then
			lang = m_languages.getByCode(langcode, true)
		end
		return {term = term, alt = alt, id = id, lang = lang, sc = sc, sort = ordre, tr = tr, gloss = gloss, pos = pos, lit = lit}
	end
	
	return nil
end

local function getParts(args)
	local parts = {}
	i = 1
	
	while true do
		local part = getPart(args, i)
		
		if not part then
			break
		end
		
		table.insert(parts, part)
		
		i = i + 1
	end
	
	return parts
end

-- Iterate an array up to the greatest integer index found.
local function ipairsWithGaps(t)
	local max_index = math.max(unpack(require("Module:TableTools").numKeys(t)))
	local i = 0
	return function()
		while i < max_index do
			i = i + 1
			return i, t[i]
		end
	end
end

function p.show(frame)
	local args = frame:getParent().args
	
	local langcode = args[1]; if langcode == "" then langcode = nil end
	local sc = args["sc"] or ""; if sc == "" then sc = nil end
	local pos = args["pos"]; if pos == "" then pos = nil end
	local intro = frame.args["intro"] ~= "false"
	local sort_key = args["sort"]; if sort_key == "" then sort_key = nil end
	local nocat = args["nocat"]; if not nocat or nocat == "" then nocat = false else nocat = true end
	
	if not langcode and mw.title.getCurrentTitle().nsText == "Plantilla" then
		langcode = "mul"
	end

	if langcode and not m_languages.existeix(langcode) then
		error("El codi de llengua \"" .. langcode .. "\" no és vàlid.")
	end
	local lang = m_languages.getByCode(langcode, true)
	
	local parts = getParts(args)
	
	-- There must be at least one part to display.
	if #parts < 1 then
		if mw.title.getCurrentTitle().nsText == "Plantilla" then
			parts = { {term = "primer"}, {term = "segon"} }
		else
			error("Cal proporcionar almenys una part del compost.")
		end
	end
	
	pos = pos or "words"
	local parts_formatted = {}
	local categories_formatted = {}
	
	-- Make links out of all the parts
	local whole_words, whole_affixes = 0, 0
	for i, part in ipairsWithGaps(parts) do
		part = part or {}
		part.sc = part.sc or sc or (part.lang and part.lang.sc)
		
		-- Is it an affix, and if so, what type of affix?
		local affix_type, display_term = getAffixType(part.lang or lang, part.sc, part.term)
		
		-- Make a link for the part
		local part_formatted = ""
		if display_term ~= "" then
			-- If a bare ^ was specified, then insert a blank string. A + will still
			-- appear next to it. This lets us directly convert things such as
			-- {{suffix|mul||idae}} to {{affix|mul|^|-idae}}.
			part_formatted = linkTerm(part, display_term, lang, sc, sort_key)
		end
		
		if not part.sort and affix_type == "prefix" then
			local word = mw.title.getCurrentTitle().subpageText
			for i = mw.ustring.len(part.term) - 1, 1, -1 do
				if mw.ustring.find(word, "^" .. mw.ustring.sub(part.term, 1, i)) then
					part.sort = mw.ustring.gsub(word, mw.ustring.sub(part.term, 1, i), "", 1)
					break
				end
			end
		end
		
		if i == 1 then
			if intro then
				if part.lang then
					local particle_name
					if part.lang.type == "grup" then
						particle_name = "D'un " .. part.lang.name
					else
						particle_name = m_general.addParticle("Del", part.lang.name)
					end
					part_formatted = particle_name .. " " .. part_formatted
				elseif affix_type then
					part_formatted = m_general.addParticle("Del", affix_type) .. " " .. part_formatted
				else
					part_formatted = "De " .. part_formatted
				end
			else
				if part.lang then
					part_formatted = part.lang.name .. " " .. part_formatted
				elseif affix_type then
					part_formatted = affix_type .. " " .. part_formatted
				end
			end
		elseif part.lang then
			part_formatted = m_general.addParticle("el", part.lang.name) .. " " .. part_formatted
		elseif affix_type then
			if affix_type == "desinència" then
				part_formatted = "la desinència " .. part_formatted
			else
				part_formatted = m_general.addParticle("el", affix_type) .. " " .. part_formatted
			end
		end
		
		table.insert(parts_formatted, part_formatted)
		
		-- categories
		if affix_type then
			whole_affixes = whole_affixes + 1
			if affix_type == "arrel" then
				display_term = usub(display_term, 2)
			end
			if affix_type ~= "desinència" then
				table.insert(categories_formatted, m_utilities.format_categories(
					{"Mots en " .. lang.name
						.. " amb " .. affix_type .. " "
						.. m_links.sense_diacritics(lang.code, display_term)
						.. (part.id and " (" .. part.id .. ")" or "")
					}, lang, sort_key, part.sort
					)
					)
			end
		else
			whole_words = whole_words + 1
			if whole_words == 2 then
				table.insert(categories_formatted, m_utilities.format_categories({"Mots compostos en " .. lang.name}, lang, sort_key))
			end
		end
		if part.lang then
			local particle_name
			if part.lang.type == "grup" then
				particle_name = "d'un " .. part.lang.name
			else
				particle_name = m_general.addParticle("del", part.lang.name)
			end
			table.insert(categories_formatted, m_utilities.format_categories({"Derivats " .. particle_name .. " " .. m_general.addParticle("al", lang.name)}, lang, sort_key))
		end
	end
	
	if whole_words < 2 and whole_affixes == 0 then
		error("Els paràmetres no inclouen afixos o compostos.")
	end
	
	local num_parts = #parts_formatted
	if num_parts > 2 then
		ret = table.concat(parts_formatted, ", ", 1, num_parts - 1) .. " i " .. parts_formatted[num_parts]
	else
		ret = table.concat(parts_formatted, " i ")
	end
	
	return ret .. (nocat and "" or table.concat(categories_formatted))
end

-- suport per la plantilla vegeu-der-afix
function p.derivsee(frame)
	local args = frame:getParent().args
	
	--local derivtype = frame.args["tipus"]
	--local mode = frame.args["mode"]; if mode == "" then mode = nil end
	local langcode = args[1] or (mw.title.getCurrentTitle().nsText == "Plantilla" and "und")
	local lang = m_languages.getByCode(langcode)
	local term = args[2] or args["lema"]; if term == "" then term = nil end
	
	--local id = args["id"]; if id == "" then id = nil end
	local sc = args["sc"]; if sc == "" then sc = nil end
	--local pos = args["pos"]; if pos == "" then pos = nil end
	
	--pos = pos or "Mots"
	term = term or mw.title.getCurrentTitle().subpageText
	
	local category = nil
	
	local affix_type = getAffixType(lang, sc, term)
	if affix_type then
		category = "Mots en " .. lang.name .. " amb " .. affix_type .. " " .. term
	else
		return
	end
	
	return frame:callParserFunction{
		name = "#categorytree",
		args = {
			category,
			depth = 0,
			class = "\"derivedterms" .. (sc and " " .. sc or "") .. "\"",
			namespaces = "-",
			}
		}
end

return p