Модуль:FtlMarking: различия между версиями

Материал из Space Station 14 Вики
мНет описания правки
мНет описания правки
Строка 111: Строка 111:


     return s
     return s
end
local function process_nowiki_equals(str)
str = str:gsub('==', '==')
            :gsub('  ', '  ')
return str
end
end


Строка 117: Строка 123:
     local text = args[1] or args.text or ""
     local text = args[1] or args.text or ""
     text = mw.text.unstripNoWiki(text)
     text = mw.text.unstripNoWiki(text)
     return transform(text)
    text = transform(text)
     return process_nowiki_equals(text)
end
end


return p
return p

Версия от 03:01, 13 января 2026

Для документации этого модуля может быть создана страница Модуль:FtlMarking/doc

local p = {}

local function apply_tag(tag, params, inner)
    local t = mw.ustring.lower(tag or "")
    if t == "bold" then
        return "<b>" .. inner .. "</b>"
    elseif t == "italic" then
        return "<i>" .. inner .. "</i>"
    elseif t == "bolditalic" then
        return "<i><b>" .. inner .. "</b></i>"
    elseif t == "bullet" then
        return "· " .. inner
    elseif t == "color" then
        local color = params and params._value or ""
        return '<span style="color:' .. color .. ';">' .. inner .. '</span>'
    elseif t == "head" then
        local level = params and tonumber(params._value) or 1
        level = math.max(1, math.min(3, level))
        local defaultSize = 12
        local size = math.ceil(defaultSize * 2 / math.sqrt(level))
        return '<span style="font-weight:bold; font-size:' .. size .. 'px;">' .. inner .. '</span>'
    elseif t == "font" then
        local family = params and params._value or nil
        local size = params and tonumber(params.size) or nil

        local style_parts = {}
        if family and family ~= "" then
            table.insert(style_parts, "font-family:" .. family)
        end
        if size and size ~= "" then
            table.insert(style_parts, "font-size:" .. size .. "px")
        end

        if #style_parts == 0 then
            return '<span>' .. inner .. '</span>'
        else
            return '<span style="' .. table.concat(style_parts, "; ") .. ';">' .. inner .. '</span>'
        end
    else
        return inner
    end
end

local function trim(s)
    if not s then return s end
    s = mw.ustring.gsub(s, "^%s+", "")
    s = mw.ustring.gsub(s, "%s+$", "")
    return s
end

local function parse_attrs(attr_str)
    if not attr_str then return nil end
    attr_str = mw.ustring.gsub(attr_str, "^%s*=%s*", "")
    attr_str = trim(attr_str)
    if attr_str == "" then return nil end

    local params = {}

    for k, v in mw.ustring.gmatch(attr_str, "([%w_%-%:]+)%s*=%s*\"(.-)\"") do
        params[mw.ustring.lower(k)] = v
    end
    attr_str = mw.ustring.gsub(attr_str, "([%w_%-%:]+)%s*=%s*\"(.-)\"", "")

    for k, v in mw.ustring.gmatch(attr_str, "([%w_%-%:]+)%s*=%s*([^%s%]]+)") do
        params[mw.ustring.lower(k)] = v
    end
    attr_str = mw.ustring.gsub(attr_str, "([%w_%-%:]+)%s*=%s*([^%s%]]+)", "")

    local unnamed = mw.ustring.match(attr_str, "%s*\"(.-)\"")
    if unnamed then
        params._value = unnamed
        attr_str = mw.ustring.gsub(attr_str, "%s*\"(.-)\"", "", 1)
    end

    if not params._value then
        local v = mw.ustring.match(attr_str, "%s*([^%s%]]+)")
        if v then params._value = v end
    end

    return params
end

local function transform(s)
    s = s or ""
    while true do
        local c_s, c_e, c_tag = mw.ustring.find(s, "%[/([%w_]+)%]")
        if not c_s then break end

        local last_o_s, last_o_e = nil, nil
        local search_pos = 1
        while true do
            local a, b = mw.ustring.find(s, "%[" .. c_tag .. "[^%]]*%]", search_pos)
            if not a or a > c_s then break end
            last_o_s, last_o_e = a, b
            search_pos = b + 1
        end

        if not last_o_s then
            s = mw.ustring.sub(s, 1, c_s - 1) .. mw.ustring.sub(s, c_e + 1)
        else
            local inner = mw.ustring.sub(s, last_o_e + 1, c_s - 1)
            local _, _, raw_attrs = mw.ustring.find(s, "%[" .. c_tag .. "([^%]]*)%]", last_o_s)
            local params = parse_attrs(raw_attrs)
            local replacement = apply_tag(c_tag, params, inner)

            s = mw.ustring.sub(s, 1, last_o_s - 1) .. replacement .. mw.ustring.sub(s, c_e + 1)
        end
    end

    s = mw.ustring.gsub(s, "%[/?[%w_]+[^%]]*%]", "")

    return s
end

local function process_nowiki_equals(str)
	str = str:gsub('==', '&#61;&#61;')
             :gsub('  ', '&#32;&#32;')
	return str
end

function p.main(frame)
    local args = frame.args or {}
    local text = args[1] or args.text or ""
    text = mw.text.unstripNoWiki(text)
    text = transform(text)
    return process_nowiki_equals(text)
end

return p