Dokumentaciju za ovaj modul možete napraviti na stranici Modul:links/dok

local languages = mw.loadData("Module:languages")
local scripts = mw.loadData("Module:scripts")
local utilities = require("Module:utilities")

local export = {}

-- This is supposed to be used in {{l}}.
function export.template_l(frame)
    local args = frame:getParent().args
    
    local lang = args[1]; if lang == nil or lang == "" then error("The first parameter (language code) has not been given") end
    local langinfo = languages[lang] or error("The language code \"" .. lang .. "\" is not valid.")
    local sc = args["sc"]; if sc == "" then sc = nil end
    
    local term = args[2]; if term == nil or term == "" then error("The second parameter (word) has not been given") end
    local alt = args[3]; if alt == "" then alt = nil end -- alternative text as link title
    local oth = args["oth"]; if oth == "" then oth = nil end
    local oth2 = args["oth2"]; if oth2 == "" then oth2 = nil end
    local id = args["id"]; if id == "" then id = nil end
    
    local tr = args["tr"]; if tr == "" then tr = nil end
    local gloss = args["gloss"]; if gloss == "" then gloss = nil end
    
    -- Determine script if not provided
    if not sc then
        -- Does this language have more than one script?
        if langinfo.scripts[2] then
            sc = utilities.detect_script(alt or term, lang) or langinfo.scripts[1]
        else
            sc = langinfo.scripts[1]
        end
    end
    
    -- Try to generate a transliteration if necessary
    if not tr and not (sc:find("Latn", nil, true) or sc == "Latinx" or sc == "unicode" or sc == "None") then
        tr = utilities.translit(lang, export.remove_links(alt or term))
    end
    
    -- Gather gender and number specifications
    -- Iterate over all gn parameters (g2, g3 and so on) until one is empty
    local genders = {}
    local g = args["g"] or ""
    local i = 2
    
    while g ~= "" do
        -- If any of the specifications contains a "?", add the entry
        -- to a cleanup category.
        if g:find("?", nil, true) then
            table.insert(categories, langinfo.names[1] .. " terms with incomplete gender")
        end
 
        table.insert(genders, g)
        g = args["g" .. i] or ""
        i = i + 1
    end
    
    -- Process the link and apply a wrapper for the the language and script
    local ret = "<span lang=\"" .. lang .. "\" class=\"" .. sc .. "\">" .. export.language_link(term, alt, lang, id) .. "</span>"
    
    -- "Alternative term" links. These are currently deprecated/discouraged.
    if oth then
        error("Parameter \"oth\" is deprecated.")
    end
    if oth2 then
        error("Parameter \"oth2\" is deprecated.")
    end
    
    return ret .. export.format_link_annotations(lang, {
        genders = genders,
        tr = tr,
        gloss = gloss})
end

-- This is supposed to be used in {{term}}.
function export.template_term(frame)
    -- Compatibility mode.
    -- If given a nonempty value, the function uses lang= to specify the
    -- language, and all the positional parameters shift one number lower.
    local compat = (frame.args["compat"] or "") ~= ""
    local args = frame:getParent().args
    
    local lang = args[(compat and "lang" or 1)]
    if lang == nil or lang == "" then
        -- Temporary. Unfortunately, many pages are missing the language parameter.
        -- These all need to be fixed, but until then this is needed to avoid
        -- thousands of script errors. See [[:Category:term cleanup]]!
        if compat then
            lang = "und"
        else
            error("The first parameter (language code) has not been given")
        end
    end
    
    local langinfo = languages[lang] or error("The language code \"" .. lang .. "\" is not valid.")
    local sc = args["sc"]; if sc == "" then sc = nil end
    
    local term = args[(compat and 1 or 2)]; if term == "" then term = nil end
    local alt = args[(compat and 2 or 3)]; if alt == "" then alt = nil end
    local id = args["id"]; if id == "" then id = nil end
    
    local tr = args["tr"]; if tr == "" then tr = nil end
    local gloss = args[(compat and 3 or 4)]; if gloss == "" then gloss = nil end
    local pos = args["pos"]; if pos == "" then pos = nil end
    local lit = args["lit"]; if lit == "" then lit = nil end
    
    -- Determine script if not provided
    if not sc then
        -- Does this language have more than one script?
        if langinfo.scripts[2] then
            sc = utilities.detect_script(alt or term, lang) or langinfo.scripts[1]
        else
            sc = langinfo.scripts[1]
        end
    end
    
    -- Try to generate a transliteration if necessary
    if not tr and not (sc:find("Latn", nil, true) or sc == "Latinx" or sc == "unicode" or sc == "None") then
        tr = utilities.translit(lang, export.remove_links(alt or term))
    end
    
    local ret = ""
    
    -- Process the link and apply a wrapper for the the language and script
    if term and lang ~= "und" then
        ret = "<i lang=\"" .. lang .. "\" class=\"" .. sc .. " mention\">" .. export.language_link(term, alt, lang, id) .. "</i>"
    else
        ret = "<i lang=\"" .. lang .. "\" class=\"" .. sc .. " mention\">" .. (term or alt or "") .. "</i>"
        --This is putting pages into categories when it shouldn't. Needs to be changed a bit before it can be used.
        --"[[Category:" .. langinfo.names[1] .. " entries which need " .. scripts[sc].names[1] .. " script]]"
    end
    
    return ret .. export.format_link_annotations(lang, {
        tr = tr,
        gloss = gloss,
        lit = lit,
        pos = pos})
end

-- TODO: What is this used for? Give this a more descriptive name, maybe?
function export.template_l_xform(frame)
    
    local args = frame.args
    local lang = (args[1] ~= '') and args[1] or nil
    local langinfo = lang and (languages[lang] or error("The language code \"" .. lang .. "\" is not valid.")) or nil
    
    local text = args[2] or ''
    local autolink = args["autolink"]

    if not mw.ustring.match(text, "%[%[.-%]%]") then
        error("No links provided in the SOP translation")
        if autolink == 'words' then
            text = mw.ustring.gsub(text, "([^{}%[%]%(%)%s,]+)", function (word)
                return '[[' .. word .. ']]'
            end)
        elseif autolink == 'all' then
            if mw.ustring.match(text, "^[^{}%[%]%(%)%s,]+$") then
                text = '[[' .. text .. ']]'
            end
        end
    end
    
    if not lang then
        return text
    end
    
    local id = langinfo.names[1]

    text = mw.ustring.gsub(text, "%[%[([^#]-)|(.-)%]%]", function(pagetitle, linktitle)
        return "[[" .. export.prepare_title(pagetitle, lang) .. "#" .. id .. "|" .. linktitle .. "]]"
    end)
    text = mw.ustring.gsub(text, "%[%[([^#|]-)%]%]", function(pagetitle)
        return "[[" .. export.prepare_title(pagetitle, lang) .. "#" .. id .. "|" .. pagetitle .. "]]"
    end)

    return text
end

function export.format_link_annotations(lang, info)
    local ret = ""
    
    if info["genders"] and #info["genders"] > 0 then
        local gen = require("Module:gender and number")
        ret = ret .. " " .. gen.format_list(info["genders"])
    end
    
    local glosses = {}
    
    if info["tr"] then
        table.insert(glosses, "<span lang=\"\" class=\"mention-tr\">" .. info["tr"] .. "</span>")
    end
    
    if info["gloss"] then
        table.insert(glosses, "<span class=\"mention-gloss-double-quote\">“</span><span class='mention-gloss'>" .. info["gloss"] .. "</span><span class=\"mention-gloss-double-quote\">”</span>")
    end
    
    if info["lit"] then
        table.insert(glosses, "literally <span class=\"mention-gloss-double-quote\">“</span><span class='mention-gloss'>" .. info["lit"] .. "</span><span class=\"mention-gloss-double-quote\">”</span>")
    end
    
    if #glosses > 0 then
        ret = ret .. " (" .. table.concat(glosses, ", ") .. ")"
    end
    
    return ret
end

-- Creates a basic wikilink to the given term. If the text already contains
-- links, these are replaced with links to the correct section.
function export.language_link(text, alt,  lang, id)
    local langinfo = languages[lang] or error("The language code \"" .. lang .. "\" is not valid.")
    
    id = "#" .. langinfo.names[1] .. (id and "-" .. id or "")
    
    if text:find("[[", nil, true) then
        if mw.ustring.sub(text, 0, 1) == "*" then
            text = mw.ustring.gsub(text, "%[%[([^%*][^#%]]-)|", "[[*%1|")
            text = mw.ustring.gsub(text, "%[%[([^%*][^#|]-)%]", "[[*%1|%1]")
        end
        
        text = mw.ustring.gsub(text, "%[%[([^#%]]-)|(.-)%]%]", function(target, linktitle)
            return "[[" .. export.prepare_title(target, lang, langinfo) .. id .. "|" .. linktitle .. "]]"
        end)
        text = mw.ustring.gsub(text, "%[%[([^#|]-)%]%]", function(target)
            return "[[" .. export.prepare_title(target, lang, langinfo) .. id .. "|" .. target .. "]]"
        end)
        
        text = mw.ustring.gsub(text, "^%*%[%[(.-)|%*", "[[%1|*") -- remove the initial "*"
    else
        text = "[[" .. export.prepare_title(text, lang, langinfo) .. id .. "|" .. (alt or text) .. "]]"
    end
    
    return text
end

-- Removes characters from a term that do not belong in the page name.
-- This includes any diacritics displayed in the headword line or alternative
-- display, but left out of the entry names.
function export.prepare_title(text, lang, langinfo)
    if not langinfo then
        langinfo = languages[lang] or error("The language code \"" .. lang .. "\" is not valid.")
    end
    
    -- Link to appendix for reconstructed terms and terms in appendix-only languages
    if mw.ustring.sub(text, 0, 1) == "*" then
        return "Appendix:" .. langinfo.names[1] .. "/" .. mw.ustring.sub(text, 2)
    elseif langinfo.type == "reconstructed" then
        error("The specified language " .. langinfo.names[1] .. " is unattested,"
              .. " while the given word in not marked with '*' to indicate that it is reconstructed")
    elseif langinfo.type == "appendix-constructed" then
        return "Appendix:" .. langinfo.names[1] .. "/" .. text
    end
    
    -- Remove punctuation
    text = mw.ustring.gsub(text, "[؟?!՛՜ ՞ ՟]$", "")
    
    -- Replace diacritics and other characters according to the specifications of the language
    if langinfo.entry_name then
        for i, from in ipairs(langinfo.entry_name.from) do
            local to = langinfo.entry_name.to[i] or ""
            text = mw.ustring.gsub(text, from, to)
        end
    end
    
    return text
end

-- Strips all square brackets out or replaces them.
function export.remove_links(text)
    NAMESPACE = mw.title.getCurrentTitle().nsText
    
    if type(text) == "table" then
        local args = text.args
        text = args[1] or (NAMESPACE == "Template" and "text") or error("No text has been provided. Please pass parameter 1 to the module invocation.")
    end
    
    local repl = function(anchor, link, display, extra)
        -- Replace multiple spaces with a single space
        link = link:gsub("%s+", " ");
        
        local namespace = link:lower():match("^(.+):")
        
        -- Strip category and file links altogether
        if namespace == "category" or namespace == "file" or namespace == "image" then
            return "" .. extra
        else
            if display == '' then
                -- just trim link out
                return anchor .. extra
            else
                return display .. extra
            end
        end
    end
    
    return (string.gsub(text, "%[%[(%s*([^|%]]+)%s*)|?(.-)]](%a*)", repl))
end

return export