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:Languag 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)
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"', '‏', '‎'}
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.wikilang(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