FANDOM


-- <nowiki>
local l = {}
local getArgs = require('Dev:Arguments').getArgs
local fallbacks = mw.loadData('Dev:Fallbacklist')
local contentLang = mw.getContentLanguage():getCode()
local title = mw.title.getCurrentTitle()
 
local function escRx(text, spaces)
    text = text:gsub('[\\().+*?^$-/=!:]', '\\%0')
 
    if spaces then
        text = text:gsub(' ', '_')
    end
 
    return text
end
 
local function makeRedLink(page, text, query)
    page = mw.ustring.gsub(tostring(page), '^:*', '')
 
    local title = frame
        and frame:preprocess('{{int:red-link-title|{{ucfirst:' .. page .. '}}}}')
        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('[[:' .. page .. '|' .. 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 = {}
    }
 
    editintro = editintro or 'Template:I18ndoc/editintro'
 
    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 == contentLang 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 = 'Template:I18ndoc',
                    summary = 'Automatic generation of i18n documentation'
                }
 
                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(contentLang) .. ')')
 
        return mw.getContentLanguage()
    end
 
    local code = frame:preprocess('{{int:lang}}')
 
    if mw.language.fetchLanguageName(code) == '' then
        mw.log('userLang(): unrecognised language code, returning content language (' .. mw.language.fetchLanguageName(contentLang) .. ')')
 
        return mw.getContentLanguage()
    end
 
    return mw.language.new(code)
end
 
function l.pageLink(links, args1, args2)
    local keys = links.keys
    local frame = mw.getCurrentFrame()
    local link = {}
 
    local pageLang = #mw.language.fetchLanguageName(title.subpageText) ~= 0
        and title.subpageText
        or contentLang
    local userLang = frame
        and l.userLang():getCode()
        or 'szl'
 
    if pageLang == contentLang then
        link = keys[userLang]
 
        for i, l in ipairs(fallbacks[userLang] or {}) do
            if not link and keys[l] and not keys[l].new then
                link = keys[l]
 
                break
            end
        end
    end
 
    link = (link and not link.new)
        and link
        or keys[pageLang]
 
    if link.new then
        local langs = {}
 
        for l, _ in pairs(keys) do
            table.insert(langs, l)
        end
 
        table.sort(langs)
 
        link = keys[langs[1]]
    end
 
    do
        local lastPart = (link.page or ''):match('[^/]+$') or ''
 
        link.lang = mw.language.fetchLanguageName(lastPart) ~= ''
            and lastPart
            or contentLang
    end
 
    return link
end
 
function l.editData(links, args1, args2)
    local frame = mw.getCurrentFrame()
    local userLang = frame:preprocess('{{int:lang}}')
    local pageLang = #mw.language.fetchLanguageName(title.subpageText) ~= 0
        and title.subpageText
        or l.pageLink(links, args1, args2).lang
 
    return tostring(mw.html.create('span')
        :attr('class', 'lang-select-data wds-is-hidden')
        -- Start LangSelect.js attributes.
        :attr('data-lang', pageLang)
        :attr('data-lang-name', mw.language.fetchLanguageName(pageLang))
        :attr('data-userlang-name', mw.language.fetchLanguageName(userLang))
        :attr('data-userlang-exists', tostring(not (links.keys[userLang] or {}).new))
        -- End LangSelect.js attributes.
    )
end
 
l.formats = {}
 
function l.formats.default(links, args1, args2, uselangs)
    local frame = mw.getCurrentFrame()
 
    local div = mw.html.create('div')
        :addClass(args1.class)
 
    if frame and mw.ustring.lower(frame:preprocess('{{int:rte-ck-dir}}')) == 'rtl' then
        div:attr('dir', 'rtl')
    end
 
    div
        :tag('strong')
            :wikitext(frame and frame:preprocess('[[w:c:dev:Languages|{{int:oasis-interlang-languages}}]]') or 'Languages:')
            :done()
        :wikitext(' ')
 
    local separator = frame
        and frame:preprocess('{{int:pipe-separator}}')
        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
 
    if not uselangs then
        div = tostring(div) .. l.editData(links, args1, args2)
    end
 
    return div
end
 
function l.formats.uselangs(links, args1, args2, root)
    local div = l.formats.default(links, args1, args2, root, true)
 
    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
 
    div = tostring(div) .. l.editData(links, args1, args2)
 
    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('{{int:rte-ck-dir}}')) == '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)
    local frame = mw.getCurrentFrame()
 
    local lang = frame
        and l.userLang():getCode()
        or 'szl'
    local link = l.pageLink(links, args1, args2)
 
    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('{{int:custom-languages-notice|' .. link.page .. '|' .. tostring(mw.uri.fullUrl(link.page, 'action=edit')) .. '|}}') 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')
                :wikitext(frame and frame:preprocess('{{int:custom-languages-notice|' .. link.page .. '|' .. tostring(mw.uri.fullUrl(link.page, 'action=edit')) .. '|*}}') or 'Here goes the notice')
    end
 
    if frame and mw.ustring.lower(frame:preprocess('{{int:rte-ck-dir}}')) == '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 v.lang ~= contentLang then
            str = str .. '[[' .. v.lang .. ':' .. prefixedRoot .. '/' .. v.lang .. ']]'
        end
    end
 
    str = str .. l.editData(links, args1, args2)
 
    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('{{#dpl:namespace=' .. (namespace or '') .. '|titleregexp=^' .. escRx(page, true) .. '\\/[a-z-]+$|replaceintitle=/^' .. escRx(page, false) .. '\\//,|redirects=include|skipthispage=no|format=¦,%TITLE%¦|noresultsheader=¦¦}}'))
 
    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 rootTitle = args1.page
        and mw.title.new(args1.page)
        or mw.title.getCurrentTitle()
 
    if
        mw.ustring.find(rootTitle.subpageText, '[a-z-]+') and
        mw.language.fetchLanguageName(rootTitle.subpageText) ~= ''
    then
        root = rootTitle.baseText
    else
        root = rootTitle.text
    end
 
    local prefixedRoot = rootTitle.nsText
 
    prefixedRoot = mw.ustring.gsub(prefixedRoot .. ':' .. 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[contentLang] = true
 
    -- Go over subpages of root
    local existing = l.subpages(root, rootTitle.nsText) or {}
 
    for i, v in ipairs(existing) do
        if v ~= '' then
            if v == contentLang then -- English has a separate subpage
                langs[contentLang] = mw.ustring.gsub(rootTitle.nsText .. ':' .. root, '^:', '') .. '/' .. contentLang
            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 ~= contentLang then
            ordered[#ordered + 1] = k
        end
    end
 
    table.sort(ordered)
    table.insert(ordered, 1, contentLang) -- 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(args1.format or 'interwiki')
 
    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 = '{{Untranslated}}\n'
    local tbl, i18n
 
    -- Temporary parsing of legacy i18n
    local LANGSELECT = '{{LangSelect}}'
    local LANGUAGES = '{{Languages}}'
    local txtInline = mw.text.trim((txt:gsub('\n', '')))
 
    if
        txtInline == LANGSELECT or
        txtInline == LANGSELECT .. LANGUAGES or
        txtInline == LANGUAGES .. LANGSELECT
    then
        ret = ret .. mw.title.new(page .. '/en'):getContent():gsub('<!%-(.-)%->', '')
 
    elseif not txt:find('{{{') then
        ret = ret .. frame:preprocess(txt)
 
    -- Parsing parameter defaults in base page
   else
        ret = ret .. '{{:' .. page
 
        for en in txt:gmatch('{{%b{}}}') do
            en = en:match('^{{{(.-)}}}$')
            tbl = mw.text.split(en, '|')
            i18n = {
                key = en:match('^([^|]+)') or '',
                val = en:match('^[^|]+|*(.*)$') or ''
            }
 
            if not ret:find('| ' .. (i18n.key:gsub('%-', '%%-')) .. ' = ') then
                ret = ret .. '\n| ' .. i18n.key .. ' = ' .. i18n.val
            end
        end
 
        ret = ret .. '\n}}'
 
    end
 
    return ret
 
end
 
return l
Community content is available under CC-BY-SA unless otherwise noted.

Fandom may earn an affiliate commission on sales made from links on this page.

Stream the best stories.

Fandom may earn an affiliate commission on sales made from links on this page.

Get Disney+