Մոդուլ:links

Վիքիբառարան-ից

Documentation for this module may be created at Մոդուլ:links/doc

local export = {}

--TODO: move to [[Module:languages]]
local override_translit = {
	["ab"] = true,
	["abq"] = true,
	["ady"] = true,
	["av"] = true,
	["axm"] = true,
	["ba"] = true,
	["bo"] = true,
	["bua"] = true,
	["ce"] = true,
	["chm"] = true,
	["cv"] = true,	
	["dar"] = true,
	["dv"] = true,
	["dz"] = true,
	["el"] = true,
	["gmy"] = true,
	["grc"] = true,
	["hy"] = true,
	["inh"] = true,
	["iu"] = true,
	["ka"] = true,
	["kk"] = true,
	--["ko"] = true,
	["kbd"] = true,
	["kca"] = true,
	["kjh"] = true,
	["kn"] = true,
	["koi"] = true,
	["kpv"] = true,
	["ky"] = true,
	["kv"] = true,
	["lo"] = true,
	["lbe"] = true,
	["lez"] = true,
	["lzz"] = true,
	["mdf"] = true,
	["ml"] = true,
	["mn"] = true,
	["my"] = true,
	["myv"] = true,
	["nog"] = true,	
	["oge"] = true,
	["os"] = true,
	["sah"] = true,
	["si"] = true,
	["sva"] = true,
	["ta"] = true,
	["tab"] = true,
	["te"] = true,
	["tg"] = true,
	["tt"] = true,
	["tyv"] = true,
	["ug"] = true,
	["udi"] = true,
	["udm"] = true,
	["xal"] = true,
	["xcl"] = true,
	["xmf"] = true,
}

local ignore_cap = {
	["ko"] = true,
}

local pos_tags = {
	["a"] = "ածական",
	["adv"] = "մակբայ",
	["int"] = "բացականչություն",
	["n"]  = "գոյական",
	["գ"] = "գոյական",
	["ած"] = "ածական",
	["բ"] = "բայ",
	["մկբ"] = "մակբայ",
	["թվ"] = "թվական",
	["դ"] = "դերանուն",
	["կ"] = "կապ",
	["շղկ"] = "շաղկապ",
	["եղբ"] = "եղանակավորող բառ",
	["ձ"] = "ձայնարկություն",
	["վ"] = "վերաբերական",
	["pron"] = "դերանուն",
	["v"] = "բայ",
	["vi"] = "անանցողական բայ",
	["vt"] = "անցողական բայ",
	["vti"] = "անանցողական և անցողական բայ",
	["a"] = "ածական",
	["a"] = "ածական",
}

-- Make a language-specific link from given link's parts
local function makeLangLink(link, lang, id, allowSelfLink)
	-- If there is no display form, then create a default one
	if not link.display then
		link.display = link.target
		
		-- Strip the prefix from the displayed form
		-- TODO: other interwiki links?
		if link.display:find("^:") then
			link.display = link.display:gsub("^:", "")
		elseif link.display:find("^w:") then
			link.display = link.display:gsub("^w:", "")
		elseif link.display:find("^wikipedia:") then
			link.display = link.display:gsub("^wikipedia:", "")
		end
	end
	
	-- If dontLinkRecons is given, or the link contains unexpanded
	-- template parameters, then don't create a link.
	if link.target:find("{{{", nil, true) then
		return link.display
	end
	
	-- Process the target
	if not (link.target:find("^:") or link.target:find("^w:") or link.target:find("^wikipedia:")) then
		-- Remove diacritics from the page name
		link.target = lang:makeEntryName(link.target)
		
		-- Link to appendix for reconstructed terms and terms in appendix-only languages
		if link.target:find("^*.") then
			if dontLinkRecons or lang:getCode() == "und" then
				return link.display
			else
				link.target = "Հավելված:" .. lang:getCanonicalName() .. "/" .. mw.ustring.sub(link.target, 2)
			end
		elseif lang:getType() == "reconstructed" then
			error("Տվյալ լեզուն՝ " .. lang:getCanonicalName() .. ", ոչ հավաստի է, քանի որ տրված բառը նշված չէ «*»-ով՝ լեզվի վերակառուցված լինելը ցույց տալու համար:")
		elseif lang:getType() == "appendix-constructed" then
			link.target = "Հավելված:" .. lang:getCanonicalName() .. "/" .. link.target
		end
	end
	
	-- If the target is the same as the current page, then return a "self-link" like the software does
	if not allowSelfLink and (link.target == mw.title.getCurrentTitle().prefixedText or link.target == ":" .. mw.title.getCurrentTitle().prefixedText) then
		return "<strong class=\"selflink\">" .. link.display .. "</strong>"
	end
	
	-- Add fragment
	-- Do not add a section link to "Undetermined", as such sections do not exist and are invalid.
	-- TabbedLanguages handles links without a section by linking to the "last visited" section,
	-- but adding "Undetermined" would break that feature.
	if not (link.target:find("^w:") or link.target:find("^wikipedia:")) then
		if link.fragment or mw.ustring.find(link.target, "#$") then
			require("Module:debug").track("links/fragment")
			require("Module:debug").track("links/fragment/" .. lang:getCode())
		end
		
		if not link.fragment and lang:getCode() ~= "und" then
			if id then
				link.fragment = lang:getCanonicalName() .. "-" .. id
			elseif not link.target:find("^Appendix:") then
				link.fragment = lang:getCanonicalName()
			end
		end
	end
	
	-- This allows linking to pages like [[sms:a]] without it being treated weirdly.
	link.target = mw.ustring.gsub(link.target, ":", "&#x3a;")
	
	return "[[" .. link.target .. (link.fragment and "#" .. link.fragment or "") .. "|" .. link.display .. "]]"
end


-- Split a link into its parts
local function parseLink(linktext)
	local link = {target = linktext}
	local found, _, first, second
	
	found, _, first, second = mw.ustring.find(link.target, "^([^|]+)|(.+)$")
	
	if found then
		link.target = first
		link.display = second
	else
		link.display = link.target
	end
	
	found, _, first, second = mw.ustring.find(link.target, "^(.+)#(.+)$")
	
	if found then
		link.target = first
		link.fragment = second
	end
	
	return link
end


-- Creates a basic wikilink to the given term. If the text already contains
-- links, these are replaced with links to the correct section.
local function language_link2(text, alt, lang, id, allowSelfLink, dontLinkRecons)
	if ignore_cap[lang:getCode()] and text then
		text = mw.ustring.gsub(text, "%^", "")
	end
	
	-- If the text begins with * and another character,
	-- then act as if each link begins with *
	local allReconstructed = false
	
	if text:find("^*.") then
		allReconstructed = true
	end
	
	-- Do we have embedded wikilinks?
	if text:find("[[", nil, true) then
		if id then
			require("Module:debug").track("language link/bad id")
		end
		
		local function repl(linktext)
			local link = parseLink(linktext)
			
			if allReconstructed then
				link.target = "*" .. link.target
			end
			
			return makeLangLink(link, lang, id, allowSelfLink, dontLinkRecons)
		end
		
		text = mw.ustring.gsub(text, "%[%[([^%]]+)%]%]", repl)
		
		-- Remove the extra * at the beginning if it's immediately followed
		-- by a link whose display begins with * too
		if allReconstructed then
			text = mw.ustring.gsub(text, "^%*%[%[([^|%]]+)|%*", "[[%1|*")
		end
	else
		-- There is no embedded wikilink, make a link using the parameters.
		text = makeLangLink({target = text, display = alt}, lang, id, allowSelfLink, dontLinkRecons)
	end
	
	return text
end


-- Format the annotations (things following the linked term)
local function format_link_annotations(lang, annotations, face)
	local ret = ""
	
	-- Interwiki link
	if annotations["interwiki"] then
		ret = ret .. annotations["interwiki"]
	end
	
	-- Genders
	if annotations["genders"] and #annotations["genders"] > 0 then
		local gen = require("Module:gender and number")
		ret = ret .. "&nbsp;" .. gen.format_list(annotations["genders"], lang)
	end
	
	local glosses = {}
	
	-- Transliteration
	if annotations["tr"] then
		if face == "term" then
			table.insert(glosses, "<span lang=\"\" class=\"tr mention-tr\">" .. annotations["tr"] .. "</span>")
		else
			table.insert(glosses, "<span lang=\"\" class=\"tr\">" .. annotations["tr"] .. "</span>")
		end
	end
	
	-- Gloss/translation
	if annotations["gloss"] then
		table.insert(glosses, "«" .. annotations["gloss"] .. "»")
	end
	
	-- Part of speech
	if annotations["pos"] then
		table.insert(glosses, pos_tags[annotations["pos"]] or annotations["pos"])
	end
	
	-- Literal/sum-of-parts meaning
	if annotations["lit"] then
		table.insert(glosses, "բառացիորեն՝ «" .. annotations["lit"] .. "»")
	end
	
	if #glosses > 0 then
		ret = ret .. " &lrm;(" .. table.concat(glosses, ", ") .. ")"
	end
	
	return ret
end


-- A version of {{l}} or {{m}} that can be called from other modules too
function export.full_link(term, alt, lang, sc, face, id, annotations, allowSelfLink, dontLinkRecons)
	annotations = annotations or {}
	
	-- Create the link
	local link = ""
	
	local m_utilities = require("Module:utilities")
	local m_scriptutils = require("Module:script utilities")
	
	-- Is there any text to show?
	if (term or alt) then
		-- Try to detect the script if it was not provided
		if not sc then
			sc = require("Module:scripts").findBestScript(alt or term, lang)
		end
		
		-- Only make a link if the term has been given, otherwise just show the alt text without a link
		link = m_scriptutils.tag_text(term and language_link2(term, alt, lang, id, allowSelfLink, dontLinkRecons) or alt, lang, sc, face)
	else
		-- No term to show.
		-- Is there at least a transliteration we can work from?
		link = m_scriptutils.request_script(lang, sc)
		
		if link == "" or not annotations["tr"] or annotations["tr"] == "-" then
			-- No link to show, and no transliteration either. Show a term request.
			local category = ""
			if mw.title.getCurrentTitle().nsText ~= "Template" then
				category = "[[Category:" .. lang:getCanonicalName() .. " term requests]]"
			end
			link = "<small>[Term?]</small>" .. category
		end
	end
	
	local mantrFix, redtrFix
	local manual_tr = ""
	
	if annotations["tr"] == "" or annotations["tr"] == "-" then
		annotations["tr"] = nil
	elseif (term or alt) and not ((sc:getCode():find("Latn", nil, true)) or sc:getCode() == "Latinx") and (not annotations["tr"] or override_translit[lang:getCode()]) then
		-- Try to generate a transliteration if necessary
		local automated_tr
		automated_tr = lang:transliterate(export.remove_links(alt or term), sc)
		if automated_tr then
			if annotations["tr"] ~= automated_tr then
				if annotations["tr"] then
					manual_tr = annotations["tr"]
					mantrFix = true
				end
				annotations["tr"] = automated_tr
			else
				redtrFix = true
			end
		end
	end
	
	return link .. format_link_annotations(lang, annotations, face)
				.. (mantrFix and "[[Category:Terms with manual transliterations different from the automated ones]][[Category:Terms with manual transliterations different from the automated ones/" .. lang:getCode() .. "]]" or "")
				.. (redtrFix and "[[Category:Terms with redundant transliterations]][[Category:Terms with redundant transliterations/" .. lang:getCode() .. "]]" or "")
end


function export.language_link(text, alt, lang, id, allowSelfLink)
	require("Module:debug").track("links/language_link")
	return language_link2(text, alt, lang, id, allowSelfLink)
end


-- Strips all square brackets out or replaces them.
function export.remove_links(text)
	if type(text) == "table" then text = text.args[1] end; if not text then text = "" end
	
	text = text:gsub("%[%[Category:[^|%]]-|?[^|%]]-%]%]", "")
	text = text:gsub("%[%[[^|%]]-|", "")
	text = text:gsub("%[%[", "")
	text = text:gsub("%]%]", "")

	return text
end

return export