Module:Dir
From Neodyland Wiki
More actions
This documentation is transcluded from Module:Dir/doc.
-- This module implements [[Template:Dir]].
--local rtlOverrides = mw.loadData('Module:Dir/RTL overrides') -- !!! mw.loadData() is broken, it does NOT load anything
local rtlOverrides = require('Module:Dir/RTL overrides')
local p = {}
local function trim(s)
if s then
return s:match('^%s*(.-)%s*$')
else
return nil
end
end
local function trimAndRemoveBlanks(s)
s = trim(s)
if s ~= '' then
return s
end
return nil
end
function p.rtlLangs()
return rtlOverrides[true] or {}
end
function p.ltrLangs()
return rtlOverrides[false] or {}
end
function p.isRTL(code)
code = trimAndRemoveBlanks(code)
local v = rtlOverrides[code]
if v ~= nil then return v end
local success, ret = pcall(function ()
return mw.language.new(code):isRTL() -- expensive and limited to 20 languages per MediaWiki instance
end)
return success and ret
end
function p.main(frame)
local args = frame:getParent().args
local code = args[1]
if p.isRTL(code) then
return trim(args[2]) or 'rtl'
else
return trim(args[3]) or 'ltr'
end
end
setmetatable(p, { quickTests = function ()
rtlLangs = p.rtlLangs()
ltrLangs = p.ltrLangs()
-- utility: reverse order iterator on sequences
local function revipairs(t)
return function(t, i)
i = i - 1
local v = t[i]
if v == nil then return nil end
return i, v
end, t, #t + 1
end
-- Basic check of data format
local function checkLangs(name, langs)
for k, lang in pairs(langs) do
assert(type(k) == 'number' and k == math.floor(k)
and type(lang) == 'string' and #lang >= 2 and #lang <= 16
and lang:find('^[a-z][%-0-9a-z]*[0-9a-z]$') == 1,
": Invalid sequence of language codes, " .. name .. "['" .. k .. "'] = '" .. lang .. "'")
end
return true
end
local ok, msg
ok, msg = pcall(checkLangs, 'rtlLangs', rtlLangs)
if not ok then return false, msg end
ok, msg = pcall(checkLangs, 'ltrLangs', ltrLangs)
if not ok then return false, msg end
-- Build inverse maps of languages having each direction
local isrtl, isltr = {}, {}
for _, lang in ipairs(rtlLangs) do isrtl[lang] = true end
for _, lang in ipairs(ltrLangs) do isltr[lang] = true end
-- Check conflicts using the two inverse maps
for _, lang in ipairs(rtlLangs) do
if isltr[lang] then return false, ": Direction conflict for '" .. lang .. "'" end
end
for _, lang in ipairs(ltrLangs) do
if isrtl[lang] then return false, ": Direction conflict for '" .. lang .. "'" end
end
-- Log missing languages (allows filling the tables above) according to MediaWiki internal data
langs = mw.language.fetchLanguageNames()
for lang, _ in pairs(langs) do
if p[lang] == nil then -- only if we still don't have data for this language
-- Note: we cannot check more than 20 languages at once, then MediaWiki raises an error.
-- So this test only runs on the Lua console, where you can update the tables at top.
ok, value = pcall(function() return tostring(mw.language.new(lang):isRTL()) end)
mw.log("Missing direction for language '" .. lang .. "', MediaWiki returns '" .. value .. "'")
end
end
-- Sort and deduplicate language code values (by scanning backward) for data cleanup
table.sort(rtlLangs)
table.sort(ltrLangs)
for i, lang in revipairs(rtlLangs) do
if rtlLangs[i - 1] == rtlLangs[i] then table.remove(rtlLangs, i) end
end
for i, lang in revipairs(ltrLangs) do
if ltrLangs[i - 1] == ltrLangs[i] then table.remove(ltrLangs, i) end
end
-- Final presentation of current lists, sorted and deduplicated
mw.log("local rtlLangs = { '" .. table.concat(rtlLangs, "', '") .. "' }")
mw.log("local ltrLangs = { '" .. table.concat(ltrLangs, "', '") .. "' }")
return true
end })
return p