Lompat ke isi

Modul:pranala

Dari Wikikato

Dokumentasi untuk modul ini dapat dibuat di Modul:pranala/doc

local p = {}

local langModule = require('Modul:bahasa')
local scriptsModule = require('Modul:aksara')

-- Style text depending on script/lang
local function wrapText(text, langcode, noitalic, bold)
    if not text or text == "" then return "" end
    local sc = scriptsModule.detect(text)
    local wrapped = scriptsModule.wrap(text, sc)

    -- Protolanguage: no italics, bold allowed
    if langModule.protoLangs[langcode] then
        if sc == "Latn" and bold == "1" then
            wrapped = "<b>" .. wrapped .. "</b>"
        end
        return wrapped
    end

    -- Normal language: italicize Latin unless noitalic
    if sc == "Latn" then
        if noitalic ~= "1" then
            wrapped = "<i>" .. wrapped .. "</i>"
        end
        if bold == "1" then
            wrapped = "<b>" .. wrapped .. "</b>"
        end
    end

    return wrapped
end

-- Build entry link
local function makeEntryLink(linkTarget, langcode, id, displayEntry, noitalic, bold)
    local langName = langModule.getLangName({ args = { langcode } })
    local isProto = langModule.protoLangs[langcode]

    -- Protolanguage
    if isProto then
        if mw.ustring.sub(linkTarget, 1, 1) ~= "*" then
            return string.format(
                "<strong class='error'>Galat: Rekonstruksi bahasa purba “%s” mesti diawali dengan tanda bintang (*)</strong>[[Bangsaan:Pranala rekonstruksi tanpa tanda bintang]]",
                linkTarget
            )
        end

        local bareEntry = mw.ustring.sub(linkTarget, 2) -- remove leading *
        local protoName = langModule.getLangName({args={langcode, nocap="1"}})
        local text = displayEntry and displayEntry ~= "" and displayEntry or linkTarget
        text = wrapText(text, langcode, "1", bold) -- force noitalic, bold allowed

        return string.format("[[Lampiran:Rekonstruksi %s/%s|%s]]", protoName, bareEntry, text)
    end

    -- Normal language
    local anchor
    if id and id ~= "" then
        anchor = string.format("#%s:%s", langName, id)
    else
        anchor = "#" .. langName
    end

    local text
    if displayEntry and displayEntry ~= "" then
        text = wrapText(displayEntry, langcode, noitalic, bold)
    else
        text = wrapText(linkTarget, langcode, noitalic, bold)
    end

    return string.format("[[%s%s|%s]]", linkTarget, anchor, text)
end

-- Build final display
local function buildDisplay(linkTarget, langcode, id, tr, t, lit, q, displayEntry, class, noitalic, notext, bold)
    local parts = {}

    if q and q ~= "" then
        table.insert(parts, string.format("(<i>%s</i>)", q))
    end

    if notext ~= "1" then
        local langname = langModule.getLangName({args={langcode, nocap="1"}})
        table.insert(parts, langname .. " punya setilah")
    end

    -- Skip linking if entry is just a hyphen
    if linkTarget ~= "-" then
        local entryPart = makeEntryLink(linkTarget, langcode, id, displayEntry, noitalic, bold)

        -- Append class right after entry
        if class and class ~= "" then
            entryPart = entryPart .. " <span style='font-variant:small-caps;'>" .. class .. "</span>"
        end

        table.insert(parts, entryPart)
    end

    local needParens = (tr and tr ~= "") or (t and t ~= "") or (lit and lit ~= "")
    if needParens then
        local subparts = {}
        if tr and tr ~= "" then
            subparts[#subparts+1] = wrapText(tr, langcode, noitalic, "")
        end
        if t and t ~= "" then
            subparts[#subparts+1] = string.format('"%s"', t)
        end
        if lit and lit ~= "" then
            subparts[#subparts+1] = string.format('harfiahnya, "%s"', lit)
        end
        parts[#parts+1] = "(" .. table.concat(subparts, ", ") .. ")"
    end

    return table.concat(parts, " ")
end

-- Parse inline <tr:...>, <t:...>, <lit:...>, <id:...>, <entry:...>, <q:...>, <class:...>
local function parseInline(entry, idx, args)
    local tr_inline      = entry:match("<tr:(.-)>")
    local t_inline       = entry:match("<t:(.-)>")
    local lit_inline     = entry:match("<lit:(.-)>")
    local id_inline      = entry:match("<id:(.-)>")
    local display_inline = entry:match("<entry:(.-)>")
    local q_inline       = entry:match("<q:(.-)>")
    local class_inline   = entry:match("<class:(.-)>")

    local cleaned = entry
        :gsub("<tr:.->", "")
        :gsub("<t:.->", "")
        :gsub("<lit:.->", "")
        :gsub("<id:.->", "")
        :gsub("<entry:.->", "")
        :gsub("<q:.->", "")
        :gsub("<class:.->", "")

    return {
        entry   = cleaned,
		tr      = tr_inline  or args["tr"..idx]     or args.tr    or "",
		t       = t_inline   or args["t"..idx]      or args.t     or "",
		lit     = lit_inline or args["lit"..idx]    or args.lit   or "",
		id      = id_inline  or args["id"..idx]     or args.id    or "",
        display = display_inline and mw.text.trim(display_inline:gsub("<.->", "")) or "",
		q       = q_inline   or args["q"..idx]      or args.q     or "",
		class   = class_inline or args["class"..idx] or args.class or "",
    }
end

-- Internal core
local function makeMention(args)
    local langcode = args[1] or ""
    local rawEntry = args[2] or ""
    local idx = tonumber(args.idx or 1) or 1

    -- Inline parsing
    local parsed = parseInline(rawEntry, idx, args)
    local linkTarget  = parsed.entry
    local id          = parsed.id
    local tr          = parsed.tr
    local t           = parsed.t
    local lit         = parsed.lit
    local q           = parsed.q
    local class       = parsed.class
    local noitalic    = args.noitalic or ""
    local notext      = args.notext or ""
    local bold        = args.bold or ""

    -- Display preference
    local displayEntry = args.entry or parsed.display
    if displayEntry == "" and args[3] then
        displayEntry = args[3]
    end
    if displayEntry == "" then
        displayEntry = linkTarget
    end
    if not linkTarget or linkTarget == "" then
    	return "<strong class='error'>Galat: Pranala sasaran kosong</strong>"
    end

    return buildDisplay(linkTarget, langcode, id, tr, t, lit, q, displayEntry, class, noitalic, notext, bold)
end

-- Exports
function p.mention(frame)
    return makeMention(frame.args)
end

function p.link(frame)
    local args = frame.args
    args.noitalic = "1"
    return makeMention(args)
end

p.makeMention = makeMention
p.parseInline = parseInline

return p