Module:Language and Module:Language/sandbox: Difference between pages

(Difference between pages)
Page 1
Page 2
Content deleted Content added
m Changed protection settings for "Module:Language": High-risk template or module: 2500 transclusions (more info) ([Edit=Require extended confirmed access] (indefinite) [Move=Require extended confirmed access] (indefinite))
 
use require("strict") instead of require("Module:No globals")
 
Line 1: Line 1:
require('strict')
require("strict")
local m_data = mw.loadData("Module:Language/data")
local m_data = mw.loadData("Module:Language/data/sandbox")
local langModule = require("Module:Lang/sandbox")
local langData = m_data.languages or m_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]]",
}

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 = {}
local p = {}


local function ifNotEmpty(value)
if value == "" then
return nil
else
return value
end
end


--[[ -------------------------- < G E T _ E R R O R _ M E S S A G E > --------------------------
local function makeLinkedName(languageCode)

local data = langData[languageCode]
Assembles an error message from message text and error category.
local article = data["article"]

local name = data["Wikipedia_name"] or data["name"]
]]
return "[[" .. article .. "|" .. name .. "]]:&nbsp;"

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
end



local function makeEntryName(word, languageCode)
--[[ -------------------------- < G E T _ C O D E > --------------------------
local data = langData[languageCode]

local ugsub = mw.ustring.gsub
This function checks if a code used is a redirect code.
word = tostring(word)
If it is, the code is convered to non-redirect version.
if word == nil then

error("The function makeEntryName requires a string argument")
]]
elseif word == "" then

return ""
local function getCode(code)
else
local redirectCode = m_data.redirects[code]
-- Remove bold and italics, so that words that contain bolding or emphasis can be linked without piping.
if redirectCode then
word = word:gsub("\'\'\'", "")
code = redirectCode
word = word:gsub("\'\'", "")
table.insert(activeTrackingCategories, trackingCategories["USING_REDIRECT_CODE"])
if data == nil then
return word
else
local replacements = data and data["replacements"]
if replacements == nil then
return word
else
-- 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.
if replacements.decompose then
word = mw.ustring.toNFD(word)
for i, from in ipairs(replacements.from) do
word = ugsub(
word,
from,
replacements.to and replacements.to[i] or "")
end
else
for regex, replacement in pairs(replacements) do
word = ugsub(word, regex, replacement)
end
end
return word
end
end
end
end
end


return code
p.makeEntryName = makeEntryName
end


local function fixScriptCode(firstLetter, threeLetters)
return string.upper(firstLetter) .. string.lower(threeLetters)
end


--[[ -------------------------- < C L E A N _ T E X T > --------------------------
local function getCodes(codes, text)

local languageCode, scriptCode, invalidCode
This function cleans the text by removing bold and italics.
local errorText
If the language used also has special replacements in in the /data sub-module,
if codes == nil or codes == "" then
it uses the data there to continue the process.
errorText = 'no language or script code provided'

elseif codes:find("^%a%a%a?$") or codes:find("^%a%a%a?%-%a%a%a%a$") then
]]
-- A three- or two-letter lowercase sequence at beginning of first parameter

languageCode =
local function cleanText(text, languageCode)
codes:find("^%a%a%a?") and (
local data = langData[languageCode]
codes:match("^(%l%l%l?)")
text = tostring(text)
or codes:match("^(%a%a%a?)")

:gsub("(%a%a%a?)", string.lower, 1)
-- Remove bold and italics, so that words that contain bolding or emphasis can be linked without piping.
)
text = text:gsub("\'\'\'", "")
-- One uppercase and three lowercase letters at the end of the first parameter
text = text:gsub("\'\'", "")
scriptCode =
codes:find("%a%a%a%a$") and (
codes:match("(%u%l%l%l)$")
or gsub(
codes:match("(%a%a%a%a)$"),
"(%a)(%a%a%a)",
fixScriptCode,
1
)
)
elseif codes:find("^%a%a%a?%-%a%a%a?$")
or codes:find("^%a%a%a%-%a%a%a%-%a%a%a$") then
languageCode = codes
-- If the language is not found, return text.
-- Private-use subtag: x followed by one or more sequences of 1-8 lowercase
if data == nil then
-- letters separated by hyphens. This only allows for one sequence, as it is
return text
-- needed for proto-languages such as ine-x-proto (Proto-Indo-European).
elseif codes:find("^%a%a%a?%-x%-%a%a?%a?%a?%a?%a?%a?%a?$") then
languageCode, scriptCode =
codes:match("^(%a%a%a%-x%-%a%a?%a?%a?%a?%a?%a?%a?)%-?(.*)$")
if not languageCode then
errorText = '<code>'..codes..'</code> is not a valid language or script code.'
elseif scriptCode ~= "" and not scriptCode:find("%a%a%a%a") then
errorText = '<code>'..scriptCode..'</code> is not a valid script code.'
else
scriptCode = scriptCode:gsub(
"(%a)(%a%a%a)",
fixScriptCode,
1
)
end
elseif codes:find("^%a%a%a?") then
languageCode, invalidCode = codes:match("^(%a%a%a?)%-?(.*)")
languageCode = string.lower(languageCode)
errorText = '<code>'..invalidCode..'</code> is not a valid script code.'
elseif codes:find("%-?%a%a%a%a$") then
invalidCode, scriptCode = codes:match("(.*)%-?(%a%a%a%a)$")
scriptCode = gsub(
scriptCode,
"(%a)(%a%a%a)",
fixScriptCode
)
errorText = '<code>'..invalidCode..'</code> is not a valid language code.'
else
errorText = '<code>'..codes..'</code> is not a valid language or script code.'
end
end

if not scriptCode or scriptCode == "" then
-- If the language does not have diacritics, return text.
scriptCode = require("Module:Unicode data").is_Latin(text) and "Latn" or "unknown"
local replacements = data and data["replacements"]
if replacements == nil then
return text
end
end

if errorText then
-- Decompose so that the diacritics of characters such
errorText = ' <span style="font-size: smaller">[' .. errorText .. ']</span>'
-- 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
else
for regex, replacement in pairs(replacements) do
errorText = ""
text = ugsub(text, regex, replacement)
end
end
end
languageCode = m_data.redirects[languageCode] or languageCode
return languageCode, scriptCode, errorText
end


return text
local function tag(text, languageCode, script, italics)
local data = langData[languageCode]
-- 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 not text then text = "[text?]" end
local textDirectionMarkers = { "", "", "" }
if data and data["direction"] == "rtl" then
textDirectionMarkers = { ' dir="rtl"', '&rlm;', '&lrm;' }
end
local out = { textDirectionMarkers[2] }
if italicize then
table.insert(out, "<i lang=\"" .. languageCode .. "\"" .. textDirectionMarkers[1] .. ">" .. text .. "</i>")
else
table.insert(out, "<span lang=\"" .. languageCode .. "\"" .. textDirectionMarkers[1] .. ">" .. text .. "</span>")
end
table.insert(out, textDirectionMarkers[3])
return table.concat(out)
end
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.
function p.lang(frame)
local parent = frame:getParent()
local args = parent.args[1] and parent.args or frame.args
local codes = args[1] and mw.text.trim(args[1])
local text = args[2] or error("Provide text in the second parameter")
local languageCode, scriptCode, errorText = getCodes(codes, text)
local italics = args.italics or args.i or args.italic
italics = not (italics == "n" or italics == "-" or italics == "no")
return tag(text, languageCode, scriptCode, italics) .. errorText
end


]]
local function linkToWiktionary(entry, linkText, languageCode)

local data = langData[languageCode]
local function createWiktionaryLink(wiktionaryText, displayText, languageCode)
local name
if languageCode then
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
if data and data.name then
name = data.name
name = data.name
elseif nameFromTag and not nameFromTag:find("error") then
name = nameFromTag
else
else
-- On other languages' wikis, use mw.getContentLanguage():getCode(),
-- On other languages' wikis, use mw.getContentLanguage():getCode(),
-- or replace 'en' with that wiki's language code.
-- or replace 'en' with that wiki's language code.
-- name = mw.language.fetchLanguageName(languageCode, mw.getContentLanguage():getCode())
name = mw.language.fetchLanguageName(languageCode, 'en')
name = mw.language.fetchLanguageName(languageCode, 'en')
if name == "" then
error("Name for the language code " .. ("%q"):format(languageCode or nil)
.. " could not be retrieved with mw.language.fetchLanguageName, "
.. "so it should be added to [[Module:Language/data]]")
end
end
end

if entry:sub(1, 1) == "*" then
if name ~= "" then
if name == "" then
return getErrorMessage(string.format(errorMessages["LANGUAGE_NAME_FOR_CODE_NOT_FOUND"], languageCode))
entry = "Reconstruction:" .. name .. "/" .. entry:sub(2)
else
end

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

elseif data and data.type == "reconstructed" then
elseif data and data.type == "reconstructed" then
mw.log("Reconstructed language without asterisk:", languageCode, name, entry)
local frame = mw.getCurrentFrame()
-- Track reconstructed entries with no asterisk by transcluding
-- Track reconstructed entries with no asterisk by transcluding
table.insert(activeTrackingCategories, trackingCategories["RECONSTRUCTED_WITH_NO_ASTERISK"])
-- a nonexistent template. This technique is used in Wiktionary:
wiktionaryText = string.format(strings["RECONSTRUCTION"], name, wiktionaryText)
-- see [[wikt:Module:debug]].

-- [[Special:WhatLinksHere/tracking/wikt-lang/reconstructed with no asterisk]]
pcall(frame.expandTemplate, frame,
{ title = 'tracking/wikt-lang/reconstructed with no asterisk' })
if name ~= "" then
entry = "Reconstruction:" .. name .. "/" .. entry
else
error("Language name is empty")
end
elseif data and data.type == "appendix" then
elseif data and data.type == "appendix" then
wiktionaryText = string.format(strings["APPENDIX"], name, wiktionaryText)
if name ~= "" then
entry = "Appendix:" .. name .. "/" .. entry
else
error("Language name is empty")
end
end
if entry and linkText then
return "[[wikt:" .. entry .. "#" .. name .. "|" .. linkText .. "]]"
else
error("linkToWiktionary needs a Wiktionary entry or link text, or both")
end
end

return string.format(strings["PIPED_LINK"], wiktionaryText, name, displayText)
else
else
return string.format(strings["LINK"], wiktionaryText, displayText)
return "[[wikt:" .. entry .. "|" .. linkText .. "]]"
end
end
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)
function p.wiktlang(frame)
local getArgs = require('Module:Arguments').getArgs
local parent = frame:getParent()
local args = parent.args[1] and parent.args or frame.args
local args = getArgs(frame)

local codes = args[1] and mw.text.trim(args[1])
local code = args[1] and mw.text.trim(args[1])
if not code then
local word1 = ifNotEmpty(args[2])
return getErrorMessage(errorMessages["NO_LANGUAGE_CODE"])
local word2 = ifNotEmpty(args[3])
if not args[2] then
error("Parameter 2 is required")
end
end

local wiktionaryText = args[2]
local languageCode, scriptCode, errorText = getCodes(codes, word2 or word1)
if not wiktionaryText then
return getErrorMessage(errorMessages["NO_WIKTIONARY_ENTRY"])
local italics = args.italics or args.i or args.italic
italics = not (italics == "n" or italics == "-" or italics == "no")
local entry, linkText
if word2 and word1 then
entry = makeEntryName(word1, languageCode)
linkText = word2
elseif word1 then
entry = makeEntryName(word1, languageCode)
linkText = word1
end
end

local out
local displayText = args[3]
if languageCode and entry and linkText then
local languageCode = getCode(code)

out = tag(linkToWiktionary(entry, linkText, languageCode), languageCode, scriptCode, italics)
local _, _, _, _, _, errorText = langModule.get_ietf_parts(languageCode)
elseif entry and linkText then
if errorText then
out = linkToWiktionary(entry, linkText)
return getErrorMessage(errorText)
else
out = '<span style="font-size: smaller;">[text?]</span>'
end
end

local italics = args.italic or args.italics or args.i
if out and errorText then

return out .. errorText
local wiktionaryTextCleaned = cleanText(wiktionaryText, languageCode)
else

return errorText or error("The function wiktlang generated nothing")
if not displayText then
displayText = wiktionaryText
end
end
end


local wiktionaryLink = createWiktionaryLink(wiktionaryTextCleaned, displayText, languageCode)
function p.wikt(frame)
if not args['no_tag'] then
local parent = frame:getParent()
local langArgs = {code = languageCode, text = wiktionaryLink, italic = italics}
local args = parent.args[1] and parent.args or frame.args
wiktionaryLink = langModule._lang(langArgs)
local codes = args[1] and mw.text.trim(args[1])
local word1 = ifNotEmpty(args[2])
local word2 = ifNotEmpty(args[3])
if not word1 then
error("Provide a word in parameter 2.")
end
local languageCode, scriptCode, errorText = getCodes(codes, word1)
local entry, linkText
if word2 and word1 then
entry = makeEntryName(word1, languageCode)
linkText = word2
elseif word1 then
entry = makeEntryName(word1, languageCode)
linkText = word1
end
local out
if languageCode and entry and linkText then
out = linkToWiktionary(entry, linkText, languageCode)
elseif entry and linkText then
out = linkToWiktionary(entry, linkText)
else
out = '<span style="font-size: smaller;">[text?]</span>'
end
end
-- Used for testing
if out and errorText then
if args["no_cat"] then
return out and out .. errorText
return wiktionaryLink
else
else
return wiktionaryLink .. table.concat(activeTrackingCategories)
return errorText or error("The function wikt generated nothing")
end
end
end
end