Mòdul:enllaç/proves

De Viccionari

La documentació d'ús d'aquest mòdul es pot crear a Mòdul:enllaç/proves/ús

local p = {}

function p.getLinkPage(target, lang)
	-- backwards compatibility TODO: track
	if not type(lang) == "table" then
		lang = require("Module:llengua").getByCode(lang)
	elseif lang.name == nil then
		lang.name = require("Module:llengua").nom(lang.code)
	end
	
	if lang.code == "und" then
		return nil
	end
	
	-- If the link contains unexpanded template parameters, then don't create a link.
	if target:find("{{{") then
		return nil
	end
	
	if target:sub(1, 1) == ":" or target:sub(1, 2) == "w:" or target:sub(1, 10) == "wikipedia:" then
		return target
	end
	
	-- Remove diacritics from the page name
	target = p.sense_diacritics(lang.code, target)
	
	-- Link to appendix for terms in appendix-only languages
	lang.name = mw.language.new('ca'):ucfirst(lang.name)
	if lang.type == "annex" then
		target = "Viccionari:" .. lang.name .. "/" .. target
	elseif mw.ustring.sub(target, 1, 1) == "√" then
		target = "Viccionari:" .. lang.name .. "/arrel/" .. mw.ustring.sub(target, 2)
	elseif (target:sub(1, 1) == "*" and #target > 1) then
		return nil
	end
	
	return target
end
	
-- 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

	-- Process the target
	link.target = p.getLinkPage(link.target, lang)
	
	if not link.target then
		return link.display
	end
	
	-- If the target is the same as the current page, then return a "self-link" like the software does
	if not allowSelfLink and not id 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.
	if not (link.target:find("^w:") or link.target:find("^wikipedia:")) then
		if not link.fragment and lang.code ~= "xx" then
			if id then
				link.fragment = lang.code .. "-" .. id
			else
				link.fragment = lang.code
			end
		end
	end
	
	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

-- Format the annotations (things following the linked term)
function p.format_link_annotations(data, face)
	-- backwards compatibility TODO: track
	if not data.lang then
		data.lang = {}
		data.lang.code = data.langcode
		data.lang.sc = data.sc
	end
	
	local ret = ""
	
	-- Interwiki link
	if data.interwiki then
		ret = ret .. data.interwiki
	end
	
	-- Genders
	if data.genders and #data.genders > 0 then
		local gen = require("Module:categoria gramatical")
		ret = ret .. "&nbsp;" .. gen.format_list(data.genders, data.lang.code)
	end
	
	local glosses = {}
	
	-- Transliteration
	if data.tr then
		table.insert(glosses, "<span lang=\"\" style=\"font-style: italic\">" .. data.tr .. "</span>")
	end
	
	-- Gloss/translation
	if data.gloss then
		table.insert(glosses, "<span class=\"mention-gloss-double-quote\">«</span><span class=\"mention-gloss\">" .. data.gloss .. "</span><span class=\"mention-gloss-double-quote\">»</span>")
	end
	
	-- Part of speech
	if data.pos then
		table.insert(glosses, data.pos)
	end
	
	-- Literal/sum-of-parts meaning
	if data.lit then
		table.insert(glosses, "literalment <span class=\"mention-gloss-double-quote\">«</span><span class=\"mention-gloss\">" .. data.lit .. "</span><span class=\"mention-gloss-double-quote\">»</span>")
	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 p.full_link(data, face, allowSelfLink, dontLinkRecons)
	-- backwards compatibility TODO: track
	if not data.lang then
		data.lang = {}
		data.lang.code = data.langcode
		data.lang.sc = data.sc
	end
	
	-- Create the link
	local link = ""
	
	-- Is there any text to show?
	if (data.term or data.alt) then
		-- Try to detect the script if it was not provided
		if not data.lang.sc then
			data.lang.sc = require("Module:llengua").script(data.lang.code)
		end
		
		-- Only make a link if the term has been given, otherwise just show the alt text without a link
		link = p.tag_text(data.term and p.language_link(data, allowSelfLink, dontLinkRecons) or data.alt, data.lang.code, data.lang.sc, face, data.genders)
	else
		-- No term to show.
		if not data.tr or data.tr == "-" then
			-- No link to show, and no transliteration either. Show a term request.
			link = "<small>[Terme?]</small>"
		end
	end
	
	local mantrFix, redtrFix
	local manual_tr = ""
	
	if data.tr == "" or data.tr == "-" then
		data.tr = nil
	elseif data.tr == nil and (data.term or data.alt) and not data.lang.sc:find("Latn", nil, true) then
		-- Try to generate a transliteration if necessary
		data.tr = require("Module:llengua").trans(data.lang.code, p.remove_links(data.term or data.alt))
	end
	
	return link .. p.format_link_annotations(data, face)
end

-- Creates a basic wikilink to the given term. If the text already contains
-- links, these are replaced with links to the correct section.
function p.language_link(text_compat, alt, langcode, id, allowSelfLink, dontLinkRecons)
	-- TODO: function p.language_link(data, allowSelfLink)
	local data = {}
	if type(text_compat) == "table" then
		data = text_compat
		allowSelfLink = alt
		dontLinkRecons = langcode
	else -- TODO: track
		data.term = text_compat
		data.alt = alt
		data.lang = {}
		data.lang.code = langcode
	end
	
	local text = data.term
	
	-- 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
		text = mw.ustring.gsub(text, "%[%[([^%]]+)%]%]",
			function(linktext)
				local link = parseLink(linktext)
				
				if allReconstructed then
					link.target = "*" .. link.target
				end
				
				return makeLangLink(link, data.lang, data.id, allowSelfLink, dontLinkRecons)
			end
			)
		
		-- 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 = data.alt}, data.lang, data.id, allowSelfLink, dontLinkRecons)
	end
	
	return text
end

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

-- original de Module:script utilities
-- Wrap text in the appropriate HTML tags with language and script class.
function p.tag_text(text, langcode, sc, face, genders)
	if sc == nil then
		sc = ""
	end
	-- Add a script wrapper
	if face == "terme" or face == "cursiva" then
		return '<i class="' .. sc .. ' mention" lang="' .. langcode .. '">' .. text .. '</i>'
	elseif face == "lema" then
		return '<strong class="' .. sc .. ' headword" lang="' .. langcode .. '">' .. text .. '</strong>'
	elseif face == "negreta" then
		return '<b class="' .. sc .. '" lang="' .. langcode .. '">' .. text .. '</b>'
	elseif face == "trad" then
		local ret = '<span class="form-of trad-form-of lang-' .. langcode
		if genders and genders[1] then
			ret = ret .. ' gender-' .. genders[1]:gsub("%-", "")
		end
		return ret .. ' ' .. sc .. '" lang="' .. langcode .. '">' .. text .. '</span>'
	elseif face == nil then
		return '<span class="' .. sc .. '" lang="' .. langcode .. '">' .. text .. '</span>'
	else
		error("El tipus no és vàlid: \"" .. face .. "\".")
	end
end

-- Traiem màcrons i altres diacrítics opcionals en algunes llengues.
-- TODO: substituir per Module:languages#Language:makeEntryName
function p.sense_diacritics(langcode, text)
    -- Remove punctuation
    text = mw.ustring.gsub(text, "[؟?!]$", "")
	
    -- Caràcters descomposats http://www.gymel.com/charsets/ANSEL.html
    local strip = {
        ang = "[\204\132\204\135]", -- macron and above dot
        ar  = "[\217\139\217\140\217\141\217\142\217\143\217\144\217\145\217\146]",
        fa  = "[\217\142\217\143\217\144\217\145\217\146]",
        ur  = "[\217\139\217\140\217\141\217\142\217\143\217\144\217\145\217\146]",
        chl = "[\204\132]", -- acute accent
        he  = "[\214\176\214\177\214\178\214\179\214\180\214\181\214\182\214\183\214\184\214\185\214\186\214\187\214\188\214\189\214\191\215\129\215\130]",
        hr  = "[\204\143\204\128\204\145\204\129\204\132]",
        la  = "[\204\132\204\134]", -- màcron i breu
        lt  = "[\204\128\204\129\204\131]",
        nci = "[\204\132]", -- macron
        ru  = "[\204\128\204\129]",
        uk  = "[\204\128\204\129]",
        be  = "[\204\128\204\129]",
        bg  = "[\204\128\204\129]",
        mk  = "[\204\128\204\129]",
        sh  = "[\204\143\204\128\204\145\204\129\204\132]",
        sr  = "[\204\143\204\128\204\145\204\129\204\132]",
        sl  = "[\204\163\204\129\204\128\204\130\204\145\204\143]",
        tr  = "[\204\130]",
        zu  = "^-" -- initial hyphen
    }
	if strip[langcode] then
		text = mw.ustring.toNFD(text)
		text = mw.ustring.gsub(text, strip[langcode], "")
		text = mw.ustring.toNFC(text)
	elseif langcode == "grc" then
		local RSQUO = mw.ustring.char(0x2019)
		local PSILI = mw.ustring.char(0x1FBD)
		local CORONIS = mw.ustring.char(0x1FBF)
		local MACRON = mw.ustring.char(0x0304)
		local BREVE = mw.ustring.char(0x0306)
		local UNDERTIE = mw.ustring.char(0x035C) -- actually "combining double breve below"
		local from = {"[ᾸᾹ]", "[ᾰᾱ]", "[ῘῙ]", "[ῐῑ]", "[ῨῩ]", "[ῠῡ]", "µ", "["..RSQUO..PSILI..CORONIS.."]", "["..MACRON..BREVE..UNDERTIE.."]" }
		local to   = {"Α", "α", "Ι", "ι", "Υ", "υ", "μ", "'", ""}
		for i, fr_i in ipairs(from) do
			local to_i = to[i] or ""
			text = mw.ustring.gsub(text, fr_i, to_i)
		end
    end
	
    return text
end

return p