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

Module:Lyrics/colors

贴贴♀百科,万娘皆可贴的百科全书!转载请标注来源页面的网页链接,并声明引自贴贴百科。内容不可商用。
跳到导航 跳到搜索
Template-info.svg 模块文档  [查看] [编辑] [历史] [刷新]

该模块提供了一种简便的创建大段带翻译歌词的方法,可以在歌词中使用多种颜色来分辨不同的演唱者。

本模块被包装成模板{{LyricsKai/colors}}使用,不建议在只有单个演唱者的歌曲条目中使用本模块。

  1. local module = {}
  2. local getArgs = require('Module:Arguments').getArgs
  3. local rainbow = require('Module:rainbow')._main
  4. local genCharaBlock = require('Module:Lyrics/colors/sub')._charaBlock
  5. local buildLyrics = require('Module:Lyrics')._lyrics
  6. local initHandler = require('Module:HooksHandler').init
  7. function module.parseArgs(colorsStr, charasStr, charaBlock)
  8. local colors = mw.text.split(mw.ustring.gsub(colorsStr, ';+$', ''), '%s*;+%s*')
  9. local aliases = {}
  10. for idx, val in ipairs(colors) do
  11. if mw.ustring.find(val, '=', 1, true) then
  12. colors[idx], aliases[idx] = mw.ustring.match(val, '^%s*([^=]+)%f[%s=]%s*=%s*(.+)%f[%s%z]%s*$')
  13. end
  14. end
  15. local charas = mw.text.split(mw.ustring.gsub(charasStr, ';+$', ''), '%s*;+%s*')
  16. for idx, val in ipairs(charas) do
  17. if charaBlock then
  18. charas[idx] = mw.ustring.gsub(val, '%(.+%)', '')
  19. end
  20. end
  21. local map_aliases = {}
  22. for idx, val in pairs(aliases) do
  23. map_aliases[val] = idx
  24. end
  25. for idx, val in pairs(charas) do
  26. map_aliases[val] = idx
  27. end
  28. return colors, map_aliases, charas
  29. end
  30. function module.parse(colors, charas, chorusName, sentence)
  31. local count_colors = #colors
  32. -- 包裹节点
  33. local chorus = '合唱'
  34. if #charas > count_colors then chorus = charas[#charas] end
  35. if chorusName ~='' then chorus = chorusName end
  36. for i=1, #sentence do
  37. local preParsed = mw.ustring.gsub(sentence[i], '(@%d%d?)([^@\n]+)\n-', function(m1, m2)
  38. if m1:len() > 2 and tonumber(m1:sub(2)) > count_colors then
  39. m1 = m1:sub(1, 2)
  40. m2 = m1:sub(3) .. m2
  41. end
  42. return mw.ustring.format('<*span title="%s" style="color:%s">%s<*/span>', m1, m1, m2)
  43. end)
  44. if mw.ustring.find(sentence[i], '^@d+.-@.') or mw.ustring.find(sentence[i], '^[^@]') then
  45. preParsed = '<span class="NoTitlebox" title="'..chorus..'">'..preParsed..'</span>'
  46. end
  47. sentence[i] = preParsed
  48. end
  49. local mode = {
  50. lg = 'linear',
  51. rg = 'radial',
  52. rlg = 'repeating-linear',
  53. rrg = 'repeating-radial',
  54. rb = 'linear'
  55. }
  56. local special_color = {}
  57. for idx, val in ipairs(colors) do
  58. local match = val:match('^([lrc][lr]?[gbo])%(', 1)
  59. if match and (mode[match] or match == 'co') then
  60. special_color[idx] = match
  61. end
  62. end
  63. for i, material in ipairs(sentence) do
  64. local need_special = {}
  65. material = mw.ustring.gsub(material, 'color:@(%d+)', function (m)
  66. m = tonumber(m)
  67. if special_color[m] then need_special[special_color[m]] = true end
  68. return 'color:' .. (colors[m] or '')
  69. end)
  70. material = mw.ustring.gsub(material, 'title="@(%d+)"', function (m)
  71. m = tonumber(m)
  72. return charas[m] and ('title="' .. charas[m] ..'"') or ''
  73. end)
  74. -- 渐变色实现
  75. for k, _ in pairs(need_special) do
  76. v = mode[k]
  77. if v then
  78. material = mw.ustring.gsub(material, '<%*span ([^>]-)style="color:'..k..'(%(.-%))">(.-)<%*/span>', function(s1, s2, s3)
  79. if k == 'rb' then
  80. local pattern = ''
  81. s2 = mw.ustring.gsub(s2, '%((.+)%)', '%1')
  82. local colors = mw.text.split(s2, ',', true)
  83. local quotient = 100 / #colors
  84. for i, v in ipairs(colors) do
  85. local color = mw.text.trim(v)
  86. if i == 1 then
  87. pattern = color..' '..quotient..'%'
  88. else
  89. pattern = pattern..', '..color..' '..(quotient * (i - 1))..'%'..', '..color..' '..(quotient * i)..'%'
  90. end
  91. end
  92. s2 = '('..pattern..')'
  93. end
  94. local style = 'background:-webkit-'..v..'-gradient'..s2..';-webkit-background-clip:text;-webkit-text-fill-color:transparent;-webkit-box-decoration-break:clone;'
  95. --[[
  96. s3 = mw.ustring.gsub(s3, '<rt%s*([^>]-)%s*>', function(s)
  97. if s ~= '' then
  98. local before, attr, after = mw.ustring.match(s, '^(.-style=")([^"]*)(".*)$')
  99. if attr ~= nil and mw.text.trim(attr) == '' then attr = nil end
  100. if attr ~= nil then
  101. s = before..attr..'; '..style..after
  102. else
  103. s = (before or s..' style="')..style..(after or '"')
  104. end
  105. else
  106. s = ' style="'..style..'"'
  107. end
  108. return '<rt '..s..'>'
  109. end)
  110. ]]--
  111. -- 额外套一层span,以免影响titlebox
  112. return '<span '..s1..'><span class="Lyrics-gradient" style="'..style..'">'..s3..'</span></span>'
  113. end)
  114. end
  115. end
  116. -- 交替色实现
  117. if need_special['co'] then
  118. material = mw.ustring.gsub(material, '<%*span ([^>]-)style="color:co%((.-)%)">(.-)<%*/span>',
  119. function(s1, s2, s3)
  120. local colors = mw.text.split(s2, ',')
  121. for idx, val in ipairs(colors) do
  122. colors[idx] = mw.text.trim(val)
  123. end
  124. return '<span '..s1..'>'..rainbow(colors, s3)..'</span>'
  125. end)
  126. end
  127. -- 整理节点
  128. sentence[i] = mw.ustring.gsub(mw.ustring.gsub(material, '<%*(/?span)', '<%1'), '@', '')
  129. end
  130. return sentence
  131. end
  132. local preSplit = function (original, translated, customArgs)
  133. local ce = {}
  134. local deal = function (text)
  135. text = mw.ustring.gsub(text, '%$([%d%$%[@])', function(s)
  136. if not ce[s] then ce[s] = mw.getCurrentFrame():expandTemplate{ title = 'ce', args = {s} } end
  137. return ce[s]
  138. end)
  139. text = mw.ustring.gsub(text, '@%[([^%[]-)%]', function(match) return '@' .. (customArgs.map_aliases[match] and customArgs.map_aliases[match] or '['..match..']') end)
  140. return text
  141. end
  142. return deal(original), deal(translated)
  143. end
  144. local preParse = function (original, translated, customArgs)
  145. original = module.parse(customArgs.colors, customArgs.charas, customArgs.chorusName, original)
  146. if customArgs.traColors and translated then
  147. translated = module.parse(customArgs.colors, customArgs.charas, customArgs.chorusName, translated)
  148. end
  149. end
  150. local preOutput = function (html, customArgs)
  151. if customArgs.doCharaBlock then
  152. html = '<p>' .. genCharaBlock(customArgs.genCharaBlock) .. '</p>' .. html
  153. end
  154. local css = mw.getCurrentFrame():extensionTag{ name = 'templatestyles', args = { src = 'Template:LyricsKai/colors/styles.css' } }
  155. return css .. html
  156. end
  157. function module.initHooks(args, hooksHandler, customArgs)
  158. customArgs.traColors = (args.traColors or '') == 'on'
  159. customArgs.doCharaBlock = (args.charaBlock or '') == 'on'
  160. customArgs.chorusName = args.chorusName or ''
  161. customArgs.colors, customArgs.map_aliases, customArgs.charas = module.parseArgs(args.colors or '', args.charas or '', customArgs.doCharaBlock)
  162. customArgs.genCharaBlock = { colors = args.colors or '', charas = args.charas or '', groupName = args.groupName, groupColor = args.lstyle }
  163. return hooksHandler({ preSplit = preSplit, preParse = preParse, preOutput = preOutput })
  164. end
  165. function module.main(frame)
  166. local args = getArgs(frame, { wrappers = 'Template:LyricsKai/colors' })
  167. local hooksHandler, customArgs = initHandler(), {}
  168. local hookTrigger = module.initHooks(args, hooksHandler, customArgs)
  169. return buildLyrics(args, hookTrigger, customArgs)
  170. end
  171. return module