Jump to content

Module:Wikt-lang

Permanently protected module
From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Gonnym (talk | contribs) at 02:33, 26 October 2020. The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

require('Module:No globals')
local m_data = mw.loadData("Module:Language/data")
local langData = m_data.languages or m_data

local strings = {
	["RECONSTRUCTION"] = "Reconstruction:%s/%s",
	["APPENDIX"] = "Appendix:%s/%s",
	["LINK"] = "[[wikt:%s|%s]]",
	["PIPED_LINK"] = "[[wikt:%s#%s|%s]]",
	["HTML_ITALIC_LANG"] = "<i lang=\"%s\" xml:lang=\"%s\"%s>%s</i>",
	["HTML_SPAN_LANG"] = "<span lang=\"%s\" xml:lang=\"%s\"%s>%s</span>",
}

local error_messages = {
	["NO_LANGUAGE_CODE"] = "No language code.",
	["NO_WIKTIONARY_ENTRY"] = "No Wiktionary entry.",
	["LANGUAGE_NAME_FOR_CODE_NOT_FOUND"] = "The language name for the language code <code>%s</code> was not found.",
}

local tracking_categories = {
	["ERROR_CATEGORY"] = "[[Category:Language module errors]]",
	["RECONSTRUCTED_WITH_NO_ASTERISK"] = "[[Category:Language module reconstructed with no asterisk]]",
	["USING_REDIRECT_CODE"] = "[[Category:Language module using redirect code]]",
}

local activeTrackingCategories = {}

local p = {}

local function get_error_message(message)
	return string.format('<span style="font-size:100%%; font-style:normal;" class="error">Error: %s </span>', message) .. tracking_categories["ERROR_CATEGORY"]
end

local function getCodes(code, text)
	local redirect_code = m_data.redirects[code]
	if redirect_code then
		code = redirect_code
		table.insert(activeTrackingCategories, tracking_categories["USING_REDIRECT_CODE"])
	end

	local langModule = require('Module:Lang').get_ietf_parts
	local languageCode, script, region, variant, private, errorText = langModule(code)
	return languageCode, script, errorText
end	

local function cleanWiktionaryText(wiktionaryText, languageCode)
	local data = langData[languageCode]
	wiktionaryText = tostring(wiktionaryText)

	-- Remove bold and italics, so that words that contain bolding or emphasis can be linked without piping.
	wiktionaryText = wiktionaryText:gsub("\'\'\'", "")
	wiktionaryText = wiktionaryText:gsub("\'\'", "")
	
	-- If the language is not found, return wiktionaryText.
	if data == nil then
		return wiktionaryText
	end

	-- If the language does not have diacritics, return wiktionaryText.
	local replacements = data and data["replacements"]
	if replacements == nil then
		return wiktionaryText
	end

	-- Decompose so that the diacritics of characters such
	-- as á can be removed in one go.
	-- No need to compose at the end, because the MediaWiki software
	-- will handle that.
	local ugsub = mw.ustring.gsub
	if replacements.decompose then
		wiktionaryText = mw.ustring.toNFD(wiktionaryText)
		for i, from in ipairs(replacements.from) do
			wiktionaryText = ugsub(wiktionaryText, from, replacements.to and replacements.to[i] or "")
		end
	else
		for regex, replacement in pairs(replacements) do
			wiktionaryText = ugsub(wiktionaryText, regex, replacement)
		end
	end

	return wiktionaryText
end

local function createWiktionaryLink(wiktionaryText, linkText, languageCode)
	if languageCode then
		local data = langData[languageCode]
		local name
		if data and data.name then
			name = data.name
		else
			-- On other languages' wikis, use mw.getContentLanguage():getCode(),
			-- or replace 'en' with that wiki's language code.
			-- name = mw.language.fetchLanguageName(languageCode, mw.getContentLanguage():getCode())
			name = mw.language.fetchLanguageName(languageCode, 'en')
		end

		if name == "" then
			return get_error_message(string.format(error_messages["LANGUAGE_NAME_FOR_CODE_NOT_FOUND"], languageCode))
		end

		if wiktionaryText:sub(1, 1) == "*" then
			wiktionaryText = string.format(strings["RECONSTRUCTION"], name, wiktionaryText:sub(2))

		elseif data and data.type == "reconstructed" then
			-- Track reconstructed entries with no asterisk by transcluding
			table.insert(activeTrackingCategories, tracking_categories["RECONSTRUCTED_WITH_NO_ASTERISK"])
			wiktionaryText = string.format(strings["RECONSTRUCTION"], name, wiktionaryText)

		elseif data and data.type == "appendix" then
			wiktionaryText = string.format(strings["APPENDIX"], name, wiktionaryText)
		end

		return string.format(strings["PIPED_LINK"], wiktionaryText, name, linkText)
	else
		return string.format(strings["LINK"], wiktionaryText, linkText)
	end
end


-- TODO: see if all or some of the logic can be handled by [[Module:Lang]]
local function tag(wiktionaryLink, languageCode, script, italics)
	local data = langData[languageCode]

	local textDirectionMarkers = {"", "", ""}
	if data and data["direction"] == "rtl" then
		textDirectionMarkers = {' dir="rtl"', '&rlm;', '&lrm;'}
	end

	local out = {textDirectionMarkers[2]}

	-- Use Wikipedia code if it has been given: for instance,
	-- Proto-Indo-European has the Wiktionary code "ine-pro" but the Wikipedia
	-- code "ine-x-proto".
	languageCode = data and data.Wikipedia_code or languageCode
	
	local italicize = script == "Latn" and italics
	if italicize then
		table.insert(out, string.format(strings["HTML_ITALIC_LANG"], languageCode, languageCode, textDirectionMarkers[1], wiktionaryLink))
	else
		table.insert(out, string.format(strings["HTML_SPAN_LANG"], languageCode, languageCode, textDirectionMarkers[1], wiktionaryLink))
	end

	table.insert(out, textDirectionMarkers[3])
	return table.concat(out)
end

function p.wikt(frame)
	frame['no_tag'] = true
	return p.wiktlang(frame)
end

function p.wiktlang(frame)
	local getArgs = require('Module:Arguments').getArgs
	local args = getArgs(frame)

	local code = args[1] and mw.text.trim(args[1])
	if not code then
		return get_error_message(error_messages["NO_LANGUAGE_CODE"])
	end

	local wiktionaryText = args[2]
	if not wiktionaryText then
		return get_error_message(error_messages["NO_WIKTIONARY_ENTRY"])
	end

	local displayText = args[3]
	local languageCode, scriptCode, errorMessage = getCodes(code, displayText or wiktionaryText)

	if errorMessage then
		return errorMessage
	end

	local italics = args.italics or args.i
	italics = not (italics == "n" or italics == "-")

	local wiktionaryTextCleaned = cleanWiktionaryText(wiktionaryText, languageCode)

	local linkText
	if displayText then
		linkText = displayText
	else
		linkText = wiktionaryText
	end

	local wiktionaryLink = createWiktionaryLink(wiktionaryTextCleaned, linkText, languageCode)
	if not args['no_tag'] then
		wiktionaryLink = tag(wiktionaryLink, languageCode, scriptCode, italics)
	end

	return wiktionaryLink .. table.concat(activeTrackingCategories)
end

return p