-

本WIKI编辑权限开放,欢迎收藏起来防止迷路,也希望有爱的小伙伴和我们一起编辑哟~ 编辑帮助:目录BWIKI反馈留言板

请假条:下周WIKI数据暂停更新3天(19日-21日),22日恢复更新。理由:站长要去考试,可能没人更新数据。望周知!
请选择语言:

版本250722.2
全站通知:

模块:效果说明高亮

来自赛尔号WIKI_BWIKI_哔哩哔哩
跳到导航 跳到搜索

此模块的文档可以在模块:效果说明高亮/doc创建

-- Module:KeywordTooltip
local p = {}

-- 1. 模块加载时只解析一次关键词
local txt = mw.title.new('模板:效果说明'):getContent() or ''
local descDict = {}
for key, desc in string.gmatch(txt, '|%s*([^=|]+)%s*=%s*([^\n]+)') do
    key = mw.text.trim(key)
    desc = mw.text.trim(desc)
    if key ~= '' and desc ~= '' then
        descDict[key] = desc
    end
end

-- 2. 关键词按长度排序
local sorted = {}
for k in pairs(descDict) do table.insert(sorted, k) end
table.sort(sorted, function(a, b) return #a > #b end)

-- 3. esc函数
local function esc(s)
    return s:gsub('[%(%)%.%%%+%-%*%?%[%]%^%$]', '%%%1')
end

-- 4. 带内存保护的缓存
local cache = {}
local cacheSize = 0
local MAX_CACHE_SIZE = 5000 -- 最多缓存5000个技能描述

function p.annotate(frame)
    local text = frame.args[1] or ''
    local cacheKey = 'skill_' .. tostring(#text) .. '_' .. text:sub(1, 50)
    
    if cache[cacheKey] then
        return cache[cacheKey]
    end
    
    -- 扫描所有关键词位置
    local marks = {}
    for _, k in ipairs(sorted) do
        local pat = esc(k)
        local startPos = 1
        while true do
            local pos = text:find(pat, startPos, true)
            if not pos then break end
            
            local conflict = false
            for _, m in ipairs(marks) do
                if pos >= m.start and pos <= m.finish then
                    conflict = true
                    break
                end
            end
            
            if not conflict then
                table.insert(marks, {
                    start = pos,
                    finish = pos + #k - 1,
                    keyword = k,
                    desc = descDict[k]
                })
            end
            startPos = pos + 1
        end
    end
    
    -- 倒序替换为HTML
    table.sort(marks, function(a, b) return a.start > b.start end)
    local result = text
    for _, m in ipairs(marks) do
        local before = result:sub(1, m.start - 1)
        local after = result:sub(m.finish + 1)
        result = before .. string.format(
            '<span class="smwr-highlighter" data-title="%s" style="border-bottom:1px solid;color:#FFEB3B;">%s</span>',
            mw.text.nowiki(m.desc),
            m.keyword
        ) .. after
    end
    
    -- 缓存并控制大小
    if cacheSize < MAX_CACHE_SIZE then
        cache[cacheKey] = result
        cacheSize = cacheSize + 1
    end
    
    return result
end

return p