Module:Languages

-- local l = {} local getArgs = require('Dev:Arguments').getArgs local fallbacks = mw.loadData('Dev:Fallbacklist')

local function escRx(text, spaces) text = mw.ustring.gsub(text, '%\\', '\\\\') text = mw.ustring.gsub(text, '%(', '\\(') text = mw.ustring.gsub(text, '%)', '\\)') text = mw.ustring.gsub(text, '%.', '\\.') text = mw.ustring.gsub(text, '%+', '\\+') text = mw.ustring.gsub(text, '%*', '\\*') text = mw.ustring.gsub(text, '%?', '\\?') text = mw.ustring.gsub(text, '%^', '\\^') text = mw.ustring.gsub(text, '%$', '\\$') text = mw.ustring.gsub(text, '%-', '\\-') text = mw.ustring.gsub(text, '/', '\\/') text = mw.ustring.gsub(text, '=', '\\=') text = mw.ustring.gsub(text, '!', '\\!') text = mw.ustring.gsub(text, ':', '\\:') if spaces then text = mw.ustring.gsub(text, ' ', '_') end return text end

local function makeRedLink(page, text, query) page = mw.ustring.gsub(tostring(page), '^:*', '') local title = frame and frame:preprocess() or  query = query or {} query['action'] = 'edit' query['redlink'] = 1 return mw.html.create('span'):addClass('redlink'):attr('title', title) :wikitext('[' .. tostring(mw.uri.fullUrl(page, query)) .. ' ' .. text .. ']') end

local function makeBlueLink(page, text) page = mw.ustring.gsub(tostring(page), '^:*', '') return mw.html.create():wikitext(..text..'') end

local function getAttr(t, name) for i, attr in ipairs( t.attributes ) do		if attr.name == name then return attr.val end end end

local function prepLinks(root, list, order, editintro) local links = { list = {}, keys = {} }   for _,k in ipairs(order) do        local lang = mw.language.fetchLanguageName(k) if lang ~= '' then local obj = { lang = k           } if list[k] then if type(list[k]) == 'string' then obj['link'] = makeBlueLink(list[k], lang) obj['page'] = list[k] elseif k == 'en' then obj['link'] = makeBlueLink(root, lang) obj['page'] = root else obj['link'] = makeBlueLink(root .. '/' .. k, lang) obj['page'] = root .. '/' .. k               end else local options = { editintro = editintro, preload = type(list['en']) == 'string' and list['en'] or root }               for i,v in ipairs(fallbacks[k] or {}) do                    if list[v] then options.preload = type(list[v]) == 'string' and list[v] or root .. '/' .. v                       break end end obj['link'] = makeRedLink(root .. '/' ..k, lang, options) obj['page'] = root .. '/' .. k               obj['new'] = true end table.insert(links.list, obj) links.keys[k] = obj end end return links end

function l.userLang local frame = mw.getCurrentFrame local lang if frame == nil then mw.log('userLang: can\'t get user\'s language without frame object, returning content language for now (' .. mw.language.fetchLanguageName(mw.getContentLanguage:getCode) ..')') return mw.getContentLanguage end local code = frame:preprocess('') if mw.language.fetchLanguageName(code) == '' then mw.log('userLang: unrecognised language code, returning content language (' .. mw.language.fetchLanguageName(mw.getContentLanguage:getCode) ..')') return mw.getContentLanguage end return mw.language.new(code) end

l.formats = {} function l.formats.default(links, args1, args2) local frame = mw.getCurrentFrame local div = mw.html.create('div'):addClass(args1['class']) if frame and mw.ustring.lower(frame:preprocess('')) == 'rtl' then div:attr('dir', 'rtl') end div:tag('strong'):wikitext(frame and frame:preprocess('Languages') or 'Languages:'):done:wikitext(' ') local separator = frame and frame:preprocess('') or '|' local highlight = mw.ustring.lower(args1['highlight'] or '') for i,v in ipairs(links.list) do       if i > 1 then div:wikitext(' ' .. separator .. ' ') end local link = v['link'] link.tagName = 'span' link:attr('data-lang', v['lang']) if highlight == v['lang'] then link:addClass('highlight') end div:node(link) end local selected = mw.ustring.lower(args1['select'] or '') if selected ~= '' then local flag = false if links.keys[selected] and not links.keys[selected].new then links.keys[selected].link:addClass('selected') flag = true else for i,v in ipairs(fallbacks[selected] or {}) do               if links.keys[v] and not links.keys[v].new then links.keys[v].link:addClass('selected') flag = true break end end end if not flag then links.keys['en'].link:addClass('selected') end end return div end function l.formats.uselangs(links, args1, args2, root) local div = l.formats.default(links, args1, args2, root) for i,v in ipairs(div.nodes) do       local node = div.nodes[i] if node.tagName ~= nil and getAttr(node, 'data-lang') then local lang = getAttr(node, 'data-lang') local langName = mw.language.fetchLanguageName(lang) if langName ~= '' then node.nodes = {} node:wikitext('[' .. tostring(mw.uri.fullUrl(root, {uselang = lang})) .. ' ' .. langName .. ']') end end end return div end function l.formats.list(links, args1, args2) local frame = mw.getCurrentFrame local ul = mw.html.create('ul'):addClass(args1['class']) if frame and mw.ustring.lower(frame:preprocess('')) == 'rtl' then ul:attr('dir', 'rtl') end local highlight = mw.ustring.lower(args1['highlight'] or '') for i,v in ipairs(links.list) do       local link = v['link'] link.tagName = 'li' link:attr('data-lang', v['lang']) if highlight == v['lang'] then link:addClass('highlight') end ul:node(link):newline end local selected = mw.ustring.lower(args1['select'] or '') if selected ~= '' then local flag = false if links.keys[selected] and not links.keys[selected].new then links.keys[selected].link:addClass('selected') flag = true else for i,v in ipairs(fallbacks[selected] or {}) do               if links.keys[v] and not links.keys[v].new then links.keys[v].link:addClass('selected') flag = true break end end end if not flag then links.keys['en'].link:addClass('selected') end end

return ul end function l.formats.transclude(links, args1, args2) links = links.keys local frame = mw.getCurrentFrame local lang = frame and l.userLang:getCode or 'szl' local link if links[lang] and not links[lang].new then link = links[lang] else link = links['en'] for i,v in ipairs(fallbacks[lang] or {}) do           if links[v] and not links[v].new then link = links[v] break end end end link.lang = (function(sp)       return #mw.language.fetchLanguageName(sp[#sp]) ~= 0            and sp[#sp]            or  'en'    end)(mw.text.split(link.page, '/')) if args1.noen then link.page, _ = mw.ustring.gsub(link.page, '/en$', '') end local res = mw.html.create('') local notice = mw.ustring.lower(args1['notice'] or '') if notice == 'top' or notice == 'both' then res:tag('div') :addClass('transclude-notice transclude-notice-top') :wikitext(frame and frame:preprocess('') or 'Here goes the notice') :done:newline end if frame then if not pcall(function           res:wikitext(frame:expandTemplate{ title = mw.ustring.gsub(link.page, '^:*', ':') })        end) then return args1['missing'] or  .. link.page ..  end else res:wikitext('Here goes the transcluded page: ' .. mw.ustring.gsub(link.page, '^:*', ':')) end if notice == 'bottom' or notice == 'both' then res:newline:tag('div') :addClass('transclude-notice transclude-notice-bottom') -- Start LangSelectEdit attributes. :attr('data-lang', link.lang) :attr('data-lang-name', mw.language.fetchLanguageName(link.lang)) :attr('data-userlang-name', mw.language.fetchLanguageName(lang)) -- End LangSelectEdit attributes. :wikitext(frame and frame:preprocess('') or 'Here goes the notice') end if frame and mw.ustring.lower(frame:preprocess('')) == 'rtl' then ul:attr('dir', 'rtl') end return res end function l.formats.interwiki(links, args1, args2, prefixedRoot) local str = '' local frame = mw.getCurrentFrame for k, v in ipairs(links.list) do       if not v['new'] and not v['lang'] == 'en' then str = str ..  .. v['lang'] .. ':' .. prefixedRoot .. '/' .. v['lang'] ..  end end return frame and frame:preprocess(str) or mw.text.nowiki(str) end

function l.subpages(page, namespace) local frame = mw.getCurrentFrame if frame == nil then return {'en','fr','pl','es','de','bad-code'} end local existing = mw.ustring.lower(frame:preprocess('')) existing = select(3, mw.ustring.find(existing, '^%s*%|([%|a-z-]*)%|%s*$')) if existing then return mw.text.split(existing, '%s*|%s*') end end

function l.langs(frame) -- Invoke-only parameters local args1 = getArgs(frame, {   	trim = true,    	removeBlanks = true,    	frameOnly = true,    	readOnly = true    }) -- Overwritable parameters local args2 = getArgs(frame, {   	trim = true,    	removeBlanks = true,    	parentFirst = true,    	readOnly = true    }) -- Get the root page name local root local title = args1['page'] and mw.title.new(args1['page']) or mw.title.getCurrentTitle if mw.ustring.find(title.subpageText, '[a-z-]+') and mw.language.fetchLanguageName(title.subpageText) ~= '' then root = title.baseText else root = title.text end local prefixedRoot = mw.ustring.gsub(title.nsText .. ':' .. root, '^:*', '') -- Must-have languages local langs = {} for i,v in ipairs(args1 or {}) do       v = mw.ustring.lower(mw.text.trim(v or '')) if v ~= '' then langs[v] = false end end langs['en'] = true -- Go over subpages of root local existing = l.subpages(root, title.nsText) or {} for i,v in ipairs(existing) do       if v ~= '' then if v == 'en' then -- English has a separate subpage langs['en'] = mw.ustring.gsub(title.nsText .. ':' .. root, '^:', '') .. '/en' else langs[v] = true end end end -- Look for parameters overriding language pages for k,v in pairs(args2) do       if type(k) == "string" and mw.language.fetchLanguageName(k) ~= '' then langs[k] = v       end end -- Get a list of langs sorted by code local ordered = {} for k,v in pairs(langs) do       if k ~= 'en' then ordered[#ordered+1] = k       end end table.sort(ordered) table.insert(ordered, 1, 'en') -- with English being first -- Get list of links local links = prepLinks(prefixedRoot, langs, ordered, args1['editintro']) -- Pass to format function local format = mw.ustring.lower(args2['format'] or 'default') return l.formats[format](links, args1, args2, prefixedRoot) end

-- Preload function for i18n documentation function l.preload(frame) -- Fetch page local page = frame.args[1] local txt = mw.title.new(page):getContent:gsub('<!%-(.-)%->', '') -- Generate untranslated doc local ret = '\n' return ret

end

return l