require("strict")
local m_data = mw.loadData("Module:Language/data/sandbox")
local langModule = require("Module:Lang/sandbox")
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]]",
}
local errorMessages = {
["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 trackingCategories = {
["ERROR_CATEGORY"] = "[[Category:Language module errors]]",
["RECONSTRUCTED_WITH_NO_ASTERISK"] = "[[Category:Language module reconstructed with no asterisk]]",
["USING_REDIRECT_CODE"] = "[[Category:Languag module using redirect code]]",
}
local activeTrackingCategories = {}
local p = {}
--[[ -------------------------- < G E T _ E R R O R _ M E S S A G E > --------------------------
Assembles an error message from message text and error category.
]]
local function getErrorMessage(message)
return string.format('<span style="font-size: 100%%; font-style: normal;" class="error">Error: %s</span>', message) .. trackingCategories["ERROR_CATEGORY"]
end
--[[ -------------------------- < G E T _ C O D E > --------------------------
This function checks if a code used is a redirect code.
If it is, the code is convered to non-redirect version.
]]
local function getCode(code)
local redirectCode = m_data.redirects[code]
if redirectCode then
code = redirectCode
table.insert(activeTrackingCategories, trackingCategories["USING_REDIRECT_CODE"])
end
return code
end
--[[ -------------------------- < C L E A N _ T E X T > --------------------------
This function cleans the text by removing bold and italics.
If the language used also has special replacements in in the /data sub-module,
it uses the data there to continue the process.
]]
local function cleanText(text, languageCode)
local data = langData[languageCode]
text = tostring(text)
-- Remove bold and italics, so that words that contain bolding or emphasis can be linked without piping.
text = text:gsub("\'\'\'", "")
text = text:gsub("\'\'", "")
-- If the language is not found, return text.
if data == nil then
return text
end
-- If the language does not have diacritics, return text.
local replacements = data and data["replacements"]
if replacements == nil then
return text
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
text = mw.ustring.toNFD(text)
for i, from in ipairs(replacements.from) do
text = ugsub(text, from, replacements.to and replacements.to[i] or "")
end
else
for regex, replacement in pairs(replacements) do
text = ugsub(text, regex, replacement)
end
end
return text
end
--[[ -------------------------- < C R E A T E _ W I K T I O N A R Y _ L I N K > --------------------------
This function creates a link to a Wiktionary entry.
]]
local function createWiktionaryLink(wiktionaryText, displayText, languageCode)
if languageCode then
local data = langData[languageCode]
local nameFromTag = langModule._name_from_tag({languageCode})
-- The name used is determined by the following logic:
-- Uses the name in /data sub-module, if set.
-- If not, uses the name from the Module:Lang database, if set.
-- Finally, uses the MediaWiki name from mw.language.fetchLanguageName().
local name
if data and data.name then
name = data.name
elseif nameFromTag and not nameFromTag:find("error") then
name = nameFromTag
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 getErrorMessage(string.format(errorMessages["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, trackingCategories["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, displayText)
else
return string.format(strings["LINK"], wiktionaryText, displayText)
end
end
--[[ -------------------------- < W I K T > --------------------------
Entry point for {{wt}}.
]]
function p.wikt(frame)
frame['no_tag'] = true
return p.wiktlang(frame)
end
--[[ -------------------------- < W I K T L A N G > --------------------------
Entry point for {{wikt-lang}}.
]]
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 getErrorMessage(errorMessages["NO_LANGUAGE_CODE"])
end
local wiktionaryText = args[2]
if not wiktionaryText then
return getErrorMessage(errorMessages["NO_WIKTIONARY_ENTRY"])
end
local displayText = args[3]
local languageCode = getCode(code)
local _, _, _, _, _, errorText = langModule.get_ietf_parts(languageCode)
if errorText then
return getErrorMessage(errorText)
end
local italics = args.italic or args.italics or args.i
local wiktionaryTextCleaned = cleanText(wiktionaryText, languageCode)
if not displayText then
displayText = wiktionaryText
end
local wiktionaryLink = createWiktionaryLink(wiktionaryTextCleaned, displayText, languageCode)
if not args['no_tag'] then
local langArgs = {code = languageCode, text = wiktionaryLink, italic = italics}
wiktionaryLink = langModule._lang(langArgs)
end
-- Used for testing
if args["no_cat"] then
return wiktionaryLink
else
return wiktionaryLink .. table.concat(activeTrackingCategories)
end
end
return p