全站通知:

模块:HighlightNumbers

来自代号鸢WIKI_BWIKI_哔哩哔哩
跳到导航 跳到搜索

此模块的文档可以在模块:HighlightNumbers/doc创建

local p = {}

function p.highlight(frame)
    -- 1. 获取输入文本
    local args = frame.args
    if frame == mw.getCurrentFrame() and (not args[1]) then
        args = frame:getParent().args
    end
    
    local text = args[1] or args.text or ""
    
    -- 2. 检测是否已经包含颜色标签(已处理过的直接返回)
    if text:find('<font') or text:find('<span') or text:find('</font>') or text:find('</span>') then
        return text
    end
    
    local red_color = "#AA1111"
    local green_color = "#60cb18"
    
    -- 3. 清洗旧的{{颜色}}模板 (ASCII范围内操作,原生gsub安全)
    text = text:gsub("{{%s*颜色%s*|[^|]+|([^}]+)}}", "%1")
    
    -- 4. 清除常见不可见字符 (精准的文本匹配,原生gsub安全)
    text = text:gsub("\226\128\139", "")   -- U+200B
    text = text:gsub("\226\128\140", "")   -- U+200C
    text = text:gsub("\226\128\141", "")   -- U+200D
    text = text:gsub("\239\187\191", "")   -- U+FEFF
    text = text:gsub("\194\173", "")       -- U+00AD
    
    -- 5. 括号规范化:【修复核心问题】
    -- 绝对不要在原生 gsub 的 [] 中放入中文!改为连续的纯字符串替换
    text = text:gsub("%[", "【"):gsub("[", "【")
    text = text:gsub("%]", "】"):gsub("]", "】")
    
    -- 6. 数字高亮(绿色):【修复核心问题】
    -- 由于包含了中文正则 [点个],必须调用 mw.ustring 库以 UTF-8 模式处理
    local num_pattern = "([%d%.%%]+)([点个]?)"
    text = mw.ustring.gsub(text, num_pattern, function(num, unit)
        if num == "." or num == "%" then 
            return num .. (unit or "")
        end
        return '<font style="color:' .. green_color .. ';">' .. num .. '</font>' .. (unit or "")
    end)
    
    -- 7. 【内容】高亮(红色)—— 纯文本查找替换,原生的 string.find 纯文本模式是安全的
    text = highlightBrackets(text, red_color)
    
    return text
end

-- 纯文本查找替换【...】对,完全不用正则
function highlightBrackets(text, color)
    local result = ""
    local current = 1
    local len = #text
    
    while current <= len do
        -- 查找左括号“【”(纯文本查找,忽略模式)
        local left_start, left_end = text:find("【", current, true)
        if not left_start then
            -- 没有左括号了,追加剩余部分
            result = result .. text:sub(current)
            break
        end
        
        -- 追加【之前的内容
        result = result .. text:sub(current, left_start - 1)
        
        -- 查找对应的右括号“】”
        local right_start, right_end = text:find("】", left_end + 1, true)
        if not right_start then
            -- 没有闭合右括号,原样输出剩余部分
            result = result .. text:sub(left_start)
            break
        end
        
        -- 提取中间内容
        local content = text:sub(left_end + 1, right_start - 1)
        -- 包装
        result = result .. '<font style="color:' .. color .. ';">【' .. content .. '】</font>'
        
        -- 移动到右括号之后
        current = right_end + 1
    end
    
    return result
end

p.template = p.highlight

return p