Tropedia

  • Before making a single edit, Tropedia EXPECTS our site policy and manual of style to be followed. Failure to do so may result in deletion of contributions and blocks of users who refuse to learn to do so. Our policies can be reviewed here.
  • All images MUST now have proper attribution, those who neglect to assign at least the "fair use" licensing to an image may have it deleted. All new pages should use the preloadable templates feature on the edit page to add the appropriate basic page markup. Pages that don't do this will be subject to deletion, with or without explanation.
  • All new trope pages will be made with the "Trope Workshop" found on the "Troper Tools" menu and worked on until they have at least three examples. The Trope workshop specific templates can then be removed and it will be regarded as a regular trope page after being moved to the Main namespace. THIS SHOULD BE WORKING NOW, REPORT ANY ISSUES TO Janna2000, SelfCloak or RRabbit42. DON'T MAKE PAGES MANUALLY UNLESS A TEMPLATE IS BROKEN, AND REPORT IT THAT IS THE CASE. PAGES WILL BE DELETED OTHERWISE IF THEY ARE MISSING BASIC MARKUP.

READ MORE

Tropedia
Advertisement

Documentation for this module may be created at Module:Languages/doc

-- <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
Advertisement