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

мНет описания правки
Нет описания правки
 
(не показана 41 промежуточная версия этого же участника)
Строка 1: Строка 1:
local p = {}
local p = {}


local function apply_tag(tag, param, inner)
local function apply_tag(tag, params, inner)
     local t = mw.ustring.lower(tag or "")
     local t = mw.ustring.lower(tag or "")
     if t == "bold" then
     if t == "bold" then
Строка 9: Строка 9:
     elseif t == "bolditalic" then
     elseif t == "bolditalic" then
         return "<i><b>" .. inner .. "</b></i>"
         return "<i><b>" .. inner .. "</b></i>"
elseif t == "head" then
    elseif t == "bullet" then
    local level = math.min(math.max(param, 1), 3) -- clamp(levelParam, 1, 3)
        return "· " .. inner
    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 == "color" then
     elseif t == "color" then
         if not param or param == "" 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 = 100
        local size = math.ceil(defaultSize * 2 / math.sqrt(level))
        return '<span style="font-weight:bold; font-size:' .. size .. '%;">' .. 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>'
             return '<span>' .. inner .. '</span>'
        else
            return '<span style="' .. table.concat(style_parts, "; ") .. ';">' .. inner .. '</span>'
         end
         end
        return '<span style="color:' .. param .. ';">' .. inner .. '</span>'
    elseif t == "bullet" then
        return "· " .. inner
     else
     else
         return inner
         return inner
     end
     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*&#61;%s*", "")
    attr_str = trim(attr_str)
    if attr_str == "" then return nil end
    local params = {}
    local function unquote_val(v)
        if not v then return v end
        v = trim(v)
        v = mw.ustring.gsub(v, "^&#34;(.-)&#34;$", "%1")
        v = mw.ustring.gsub(v, '^"(.-)"$', "%1")
        return v
    end
    for k, v in mw.ustring.gmatch(attr_str, "([%w_%-%:]+)%s*&#61;%s*\"(.-)\"") do
        params[mw.ustring.lower(k)] = unquote_val(v)
    end
    attr_str = mw.ustring.gsub(attr_str, "([%w_%-%:]+)%s*&#61;%s*\"(.-)\"", "")
    for k, v in mw.ustring.gmatch(attr_str, "([%w_%-%:]+)%s*&#61;%s*([^%s%]]+)") do
        params[mw.ustring.lower(k)] = unquote_val(v)
    end
    attr_str = mw.ustring.gsub(attr_str, "([%w_%-%:]+)%s*&#61;%s*([^%s%]]+)", "")
    local unnamed = mw.ustring.match(attr_str, "%s*&#34;(.-)&#34;") or mw.ustring.match(attr_str, "%s*\"(.-)\"")
    if unnamed then
        params._value = unquote_val(unnamed)
        attr_str = mw.ustring.gsub(attr_str, "%s*&#34;(.-)&#34;", "", 1)
        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 = unquote_val(v) end
    end
    return params
end
local function convert_lists(s)
    if not s or s == "" then return s end
    local lines = mw.text.split(s, "\n")
    local enable_numeric = false
    for _, line in ipairs(lines) do
        local line_unescaped = mw.ustring.gsub(line, "&#32;", " ")
        if mw.ustring.match(line_unescaped, "^%s*%d+%.") then
            enable_numeric = true
            break
        end
    end
    local out_lines = {}
    for _, line in ipairs(lines) do
        local processed = line
        local handled = false
        local line_unescaped = mw.ustring.gsub(line, "&#32;", " ")
        if enable_numeric then
            local leading, num, rest = mw.ustring.match(line_unescaped, "^(%s*)(%d+)%.%s*(.*)$")
            if num then
                local indent = mw.ustring.len(leading or "")
                local level = math.floor(indent / 2)
                local hashes = string.rep('#', 1 + level)
                processed = hashes .. (rest ~= "" and (" " .. rest) or "")
                table.insert(out_lines, processed)
                handled = true
            end
        end
        if not handled then
            local leading, rest = mw.ustring.match(line_unescaped, "^(%s*)%-%s+(.*)$")
            if rest then
                local indent = mw.ustring.len(leading or "")
                local level = math.floor(indent / 2)
                local hashes = string.rep('#', 1 + level)
                processed = hashes .. (rest ~= "" and (" " .. rest) or "")
                table.insert(out_lines, processed)
                handled = true
            end
        end
        if not handled then
            table.insert(out_lines, processed)
        end
    end
    return table.concat(out_lines, "\n")
end
end


local function transform(s)
local function transform(s)
     s = s or ""
     s = s or ""
    s = mw.ustring.gsub(s, "%[tooltip([^%]]*)%]", function(raw_attrs)
        local params = parse_attrs(raw_attrs)
        local tip = ""
        local visible = ""
        if params then
            if params.tooltip then tip = params.tooltip end
            if params.text then visible = params.text end
            if visible == "" and params._value then visible = params._value end
            if tip == "" and params._value and visible ~= params._value then tip = params._value end
        end
        return "{{altTooltip|1=" .. (visible or "") .. "|2={{#invoke:Loc|GetRawString|" .. (tip or "") .. "}}}}"
    end)
     while true do
     while true do
         local c_s, c_e, c_tag = mw.ustring.find(s, "%[/([%w_]+)%]")
         local c_s, c_e, c_tag = mw.ustring.find(s, "%[/([%w_]+)%]")
         if not c_s then break end
         if not c_s then break end
         local last_o_s, last_o_e = nil, nil
         local last_o_s, last_o_e = nil, nil
         local search_pos = 1
         local search_pos = 1
         while true do
         while true do
             local a, b = mw.ustring.find(s, "%[" .. c_tag .. "=?[^%]]*%]", search_pos)
             local a, b = mw.ustring.find(s, "%[" .. c_tag .. "[^%]]*%]", search_pos)
             if not a or a > c_s then break end
             if not a or a > c_s then break end
             last_o_s, last_o_e = a, b
             last_o_s, last_o_e = a, b
             search_pos = b + 1
             search_pos = b + 1
         end
         end
         if not last_o_s then
         if not last_o_s then
             s = mw.ustring.sub(s, 1, c_s - 1) .. mw.ustring.sub(s, c_e + 1)
             s = mw.ustring.sub(s, 1, c_s - 1) .. mw.ustring.sub(s, c_e + 1)
         else
         else
             local inner = mw.ustring.sub(s, last_o_e + 1, c_s - 1)
             local inner = mw.ustring.sub(s, last_o_e + 1, c_s - 1)
             local _, _, param = mw.ustring.find(s, "%[" .. c_tag .. "=([^%]]+)%]", last_o_s)
             local _, _, raw_attrs = mw.ustring.find(s, "%[" .. c_tag .. "([^%]]*)%]", last_o_s)
             local replacement = apply_tag(c_tag, param, inner)
            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)
             s = mw.ustring.sub(s, 1, last_o_s - 1) .. replacement .. mw.ustring.sub(s, c_e + 1)
         end
         end
     end
     end
     s = mw.ustring.gsub(s, "%[/?[%w_]+[^%]]*%]", "")
     s = mw.ustring.gsub(s, "%[/?[%w_]+[^%]]*%]", "")
    s = convert_lists(s)
    return s
end


     return s
local function process_nowiki_equals(str)
    str = str:gsub('#', '&#35;')
            :gsub('=', '&#61;')
            :gsub(' ', '&#32;')
            :gsub('{"', '')
            :gsub('"}', '')
            :gsub('{', '&#123;')
            :gsub('"', '&#34;')
            :gsub("'", '&#10;')
            :gsub('*', '&#42;')
     return str
end
end


Строка 60: Строка 194:
     local args = frame.args or {}
     local args = frame.args or {}
     local text = args[1] or args.text or ""
     local text = args[1] or args.text or ""
     return frame:preprocess(transform(text))
 
    text = mw.text.unstripNoWiki(text)
    text = process_nowiki_equals(text)
 
     return frame:preprocess('<div class="list-reset-margin">\n' .. transform(text) .. '</div>')
end
end


return p
return p