置顶公告:【置顶】关于临时开启评论区所有功能的公告(2022.10.22) | 【置顶】关于本站Widget恢复使用的公告
  • 你好~!欢迎来到萌娘百科镜像站!如需查看或编辑,请联系本站管理员注册账号。
  • 本镜像站和其他萌娘百科的镜像站无关,请注意分别。

Module:Sandbox/C8H17OH/Lyrics/colors

猛汉♂百科,万男皆可猛的百科全书!转载请标注来源页面的网页链接,并声明引自猛汉百科。内容不可商用。
跳到导航 跳到搜索
Template-info.svg 模块文档  [创建] [刷新]
local module = {}
 
local getArgs = require('Module:Arguments').getArgs
local rainbow = require('Module:rainbow')._main
local genCharaBlock = require('Module:Lyrics/colors/sub')._charaBlock
local buildLyrics = require('Module:Lyrics')._lyrics
local initHandler = require('Module:HooksHandler').init
 
function module.parseArgs(colorsStr, charasStr, charaBlock)
    local colors = mw.text.split(mw.ustring.gsub(colorsStr, ';+$', ''), '%s*;+%s*')
    local aliases = {}
    for idx, val in ipairs(colors) do
        if mw.ustring.find(val, '=', 1, true) then
            colors[idx], aliases[idx] = mw.ustring.match(val, '^%s*([^=]+)%f[%s=]%s*=%s*(.+)%f[%s%z]%s*$')
        end
    end
 
    local charas = mw.text.split(mw.ustring.gsub(charasStr, ';+$', ''), '%s*;+%s*')
    for idx, val in ipairs(charas) do
        if charaBlock then
            charas[idx] = mw.ustring.gsub(val, '%(.+%)', '')
        end
    end
 
    local map_aliases = {}
    for idx, val in pairs(aliases) do
        map_aliases[val] = idx
    end
    for idx, val in pairs(charas) do
        map_aliases[val] = idx
    end
 
    return colors, map_aliases, charas
end
 
function module.parse(colors, charas, chorusName, sentence)
    local count_colors = #colors
    -- 包裹节点
    local chorus = '合唱'
    if #charas > count_colors then chorus = charas[#charas] end
    if chorusName ~='' then chorus = chorusName end
    for i=1, #sentence do
        local preParsed = mw.ustring.gsub(sentence[i], '(@%d%d?)([^@\n]+)\n-', function(m1, m2)
            if m1:len() > 2 and tonumber(m1:sub(2)) > count_colors then
                m1 = m1:sub(1, 2)
                m2 = m1:sub(3) .. m2
            end
            return mw.ustring.format('<*span title="%s" style="color:%s">【%s】%s<*/span>', m1, m1, m1, m2)
        end)
        if mw.ustring.find(sentence[i], '^@d+.-@.') or mw.ustring.find(sentence[i], '^[^@]') then
            preParsed = '<span class="NoTitlebox" title="'..chorus..'">'..preParsed..'</span>'
        end
        sentence[i] = preParsed
    end
 
    local mode = {
        lg = 'linear',
        rg = 'radial',
        rlg = 'repeating-linear',
        rrg = 'repeating-radial',
        rb = 'linear'
    }
    local special_color = {}
    for idx, val in ipairs(colors) do
        local match = val:match('^([lrc][lr]?[gbo])%(', 1)
        if match and (mode[match] or match == 'co') then
            special_color[idx] = match
        end
    end
    for i, material in ipairs(sentence) do
        local need_special = {}
        material = mw.ustring.gsub(material, 'color:@(%d+)', function (m)
            m = tonumber(m)
            if special_color[m] then need_special[special_color[m]] = true end
            return 'color:' .. (colors[m] or '')
        end)
        material = mw.ustring.gsub(material, 'title="@(%d+)"', function (m)
            m = tonumber(m)
            return charas[m] and ('title="' .. charas[m] ..'"') or ''
        end)
        material = mw.ustring.gsub(material, '【@(%d+)】', function (m)
            m = tonumber(m)
            return charas[m] and ('<span class="Lyrics-charatext" lang="zh">【' .. charas[m] ..'】</span>') or ''
        end)
 
        -- 渐变色实现
        for k, _ in pairs(need_special) do
            v = mode[k]
            if v then
                material = mw.ustring.gsub(material, '<%*span ([^>]-)style="color:'..k..'(%(.-%))">(.-)<%*/span>', function(s1, s2, s3)
                    if k == 'rb' then
                        local pattern = ''
                        s2 = mw.ustring.gsub(s2, '%((.+)%)', '%1')
                        local colors = mw.text.split(s2, ',', true)
                        local quotient = 100 / #colors
                        for i, v in ipairs(colors) do
                            local color = mw.text.trim(v)
                            if i == 1 then
                                pattern = color..' '..quotient..'%'
                            else
                                pattern = pattern..', '..color..' '..(quotient * (i - 1))..'%'..', '..color..' '..(quotient * i)..'%'
                            end
                        end
                        s2 = '('..pattern..')'
                    end
                    local style = 'background:-webkit-'..v..'-gradient'..s2..';-webkit-background-clip:text;-webkit-text-fill-color:transparent;-webkit-box-decoration-break:clone;'
                    --[[
                    s3 = mw.ustring.gsub(s3, '<rt%s*([^>]-)%s*>', function(s)
                        if s ~= '' then
                            local before, attr, after = mw.ustring.match(s, '^(.-style=")([^"]*)(".*)$')
                            if attr ~= nil and mw.text.trim(attr) == '' then attr = nil end
                            if attr ~= nil then
                                s = before..attr..'; '..style..after
                            else
                                s = (before or s..' style="')..style..(after or '"')
                            end
                        else
                            s = ' style="'..style..'"'
                        end
                        return '<rt '..s..'>'
                    end)
                    ]]--
                    -- 额外套一层span,以免影响titlebox
                    return '<span '..s1..'><span class="Lyrics-gradient" style="'..style..'">'..s3..'</span></span>'
                end)
            end
        end
 
        -- 交替色实现
        if need_special['co'] then
            material = mw.ustring.gsub(material, '<%*span ([^>]-)style="color:co%((.-)%)">(.-)<%*/span>', 
            function(s1, s2, s3)
                local colors = mw.text.split(s2, ',')
                for idx, val in ipairs(colors) do
                    colors[idx] = mw.text.trim(val)
                end    
                return '<span '..s1..'>'..rainbow(colors, s3)..'</span>'
            end)
        end
 
        -- 整理节点
        sentence[i] = mw.ustring.gsub(mw.ustring.gsub(material, '<%*(/?span)', '<%1'), '@', '')
    end
 
    return sentence
end
 
local preSplit = function (original, translated, customArgs)
    local ce = {}
    local deal = function (text)
        text = mw.ustring.gsub(text, '%$([%d%$%[@])', function(s)
            if not ce[s] then ce[s] = mw.getCurrentFrame():expandTemplate{ title = 'ce', args = {s} } end
            return ce[s]
        end)
        text = mw.ustring.gsub(text, '@%[([^%[]-)%]', function(match) return '@' .. (customArgs.map_aliases[match] and customArgs.map_aliases[match] or '['..match..']') end)
        return text
    end
    return deal(original), deal(translated)
end
 
local preParse = function (original, translated, customArgs)
    original = module.parse(customArgs.colors, customArgs.charas, customArgs.chorusName, original)
    if customArgs.traColors and translated then
        translated = module.parse(customArgs.colors, customArgs.charas, customArgs.chorusName, translated)
    end
end
 
local preOutput = function (html, customArgs)
    if customArgs.doCharaBlock then
        html =  '<p>' .. genCharaBlock(customArgs.genCharaBlock) .. '</p>' .. html
    end
    local css = mw.getCurrentFrame():extensionTag{ name = 'templatestyles', args = { src = 'Template:LyricsKai/colors/styles.css' } }
    return css .. html
end
 
function module.initHooks(args, hooksHandler, customArgs)
    customArgs.traColors = (args.traColors or '') == 'on'
    customArgs.doCharaBlock = (args.charaBlock or '') == 'on'
    customArgs.chorusName = args.chorusName or ''
    customArgs.colors, customArgs.map_aliases, customArgs.charas = module.parseArgs(args.colors or '', args.charas or '', customArgs.doCharaBlock)
    customArgs.genCharaBlock = { colors = args.colors or '', charas = args.charas or '', groupName = args.groupName, groupColor = args.lstyle }
 
    return hooksHandler({ preSplit = preSplit, preParse = preParse, preOutput = preOutput })
end
 
function module.main(frame)
    local args = getArgs(frame, { wrappers = 'User:C8H17OH/Sandbox/Template' })
    local hooksHandler, customArgs = initHandler(), {}
    local hookTrigger = module.initHooks(args, hooksHandler, customArgs)
 
    return buildLyrics(args, hookTrigger, customArgs)
end
 
return module