本网站正在建设中(~ ̄▽ ̄)~

  • 你好~!欢迎来到中文歌声合成个人收集站-VCPedia.cn!
  • 若发现页面信息有误投稿至本站,请联系管理员。

Module:Lyrics/multi

VCPedia.cn ——关于中文歌声合成的一切。
跳到导航 跳到搜索

该模块提供了一种简便的创建大段带两个以上翻译版本歌词的方法,支持使用多种颜色来分辨不同演唱者。

该模块便会为您按照行一一对应的关系生成各版本译文的对照。在高分辨率情况下,它们将会被排版在同一行中。在低分辨率,各版本译文会各占一行。该模块还附带对应的模板{{LyricsKai/multi}},后者的额外两个样式参数能设置容器的颜色、大小等样式。

该模块仅用于处理带有多个翻译版本歌词的情况,若仅有唯一的翻译版本,请参考使用{{LyricsKai}};若同时要在歌词中使用多种颜色来分辨不同的演唱者,请参考使用{{LyricsKai/colors}}。

参数

该模块目前有以下参数

以下参数适用于模块:Lyrics/multi
  • (匿名参数列表):指示描述翻译版本的名称,以及顺序。
    每个参数都支持以下两种格式:
    • vername:允许使用除了括号[]外的任意字符。
    • vername[alias1, alias2, ..., aliasn]:支持添加多个缩写,用以方便书写lang和style参数,同时实现对{{LyricsKai}}的最大程度兼容。
  • vername:歌词的翻译文本。注意,这里只能使用全名vername,不能使用缩写aliasn
  • namelang:翻译版本name的语言标签,详见Help:语言标签。其中name可以使用全名vername,也可以使用缩写aliasn,如果前者不是空白则优先使用。
    ※提示:若未填写或留空此参数,则按照翻译版本的顺序,第一个版本的语言默认为日语(ja);第二个版本的语言默认为中文(zh)。
  • namestyle:翻译版本name的样式。颜色等样式可以在这里指定。其中name可以使用全名vername,也可以使用缩写aliasn,如果前者不是空白则优先使用。
  • nameColors:启用翻译版本name中的标记解析。其中name可以使用全名vername,也可以使用缩写aliasn,如果前者不是空白则优先使用。
    ※提示:若未填写或留空此参数,则按照翻译版本的顺序,第一个版本默认开启标记解析。
  • errMsg:将值设为off时能够关闭错误提示。当忽略错误提示时,模块将忽略一切引发错误的内容并继续处理剩余的内容,这可能使模块无法提供直观的错误的说明。
以下参数引自{{LyricsKai/colors}},详细说明请见模板文档。
  • colors:所有角色的颜色。
  • charas:所有角色的名字。
  • charaBlock:将值设为on时,在歌词栏上方生成一组类似{{CharaBlock}}的角色颜色提示。
  • groupName:合唱提示栏显示文字。
以下参数引自模块:Lyrics
  • width:设计模板的宽度,默认为100%。
  • containerstyle:对整个容器应用的样式。背景颜色等同时作用于原文和译文部分的样式可以在这里指定。
此外,还有与著作权标记相关的两个参数。
  • author: 词作者/歌曲版权所有者,如果在站内有条目的可以写成内链的形式。
  • override: 当且仅当值为“1”时隐藏著作权标记,请只在该模板被用于非歌词场合时使用。

使用方法

该模块最大程度兼容{{LyricsKai}}和{{LyricsKai/colors}},只需要添加几个参数便可完成从前两者到{{LyricsKai/multi}}写法的修改。

LyricsKai→LyricsKai/multi

{{LyricsKai
  |llang      = ja
  |rlang      = zh
  |lstyle     =
  |rstyle     =
  |original   =
原文
  |translated =
译文
}}
{{LyricsKai/multi
  |original[l]|translated[r]|another
  |llang        = ja
  |rlang        = zh
  |anotherlang  = en
  |lstyle       =
  |rstyle       =
  |anotherstyle =
  |original     =
原文
  |translated   =
译文
  |another      =
英文译文
}}

从LyricsKai/colors→LyricsKai/multi

{{LyricsKai/colors
  |llang      = ja
  |rlang      = zh
  |lstyle     =
  |rstyle     =
  |colors     =
  |charas     =
  |charaBlock = on
  |colorsMode = on
  |traColors  = on
  |original   =
原文
  |translated =
译文
}}
{{LyricsKai/multi
  |original[l]|translated[r,tra]|another
  |llang         = ja
  |rlang         = zh
  |anotherlang   = en
  |lstyle        =
  |rstyle        =
  |anotherstyle  =
  |colors        =
  |charas        =
  |charaBlock    = on
  |traColors     = on
  |anotherColors = on
  |original      =
原文
  |translated    =
译文
  |another       =
英文译文
}}

例子

修改自{{LyricsKai}}
喀秋莎
代码
{{LyricsKai/multi
|original[l]|translated[r]|another
|llang        = ru
|lstyle       = color:red;
|rstyle       = color:purple;
|anotherstyle = color:blue;
|original=
'''俄语'''
«Катю́ша»
Расцветали яблони и груши 
Поплыли туманы над рекой 
Выходила на берег Катю́ша 
На высокий берег на крутой 
Выходила на берег Катю́ша 
На высокий берег на крутой 

Выходила, песню заводила 
Про степного сизого орла 
Про того, которого любила 
Про того, чьи письма берегла 
Про того, которого любила 
Про того, чьи письма берегла

Ой, ты, песня, песенька девитья 
Ты лети за ясным солнцем вслед 
И бойцу на дальнем пограничье 
От Катюши передай привет 
И бойцу на дальнем пограничье 
От Катюши передай привет 

Пусть он вспомнит девушку простую 
Пусть услышит как она поет 
Пусть он землю бережет родную 
А любовь Катю́ша сбережет 
Пусть он землю бережет родную 
А любовь Катю́ша сбережет

Расцветали яблони и груши 
Поплыли туманы над рекой 
Выходила на берег Катю́ша 
На высокий берег на крутой
Выходила на берег Катю́ша 
На высокий берег на крутой

|translated=
'''拉丁化'''
''Katyusha''
Rastsvetali yabloni i grushi
Poplyli tumany nad rekoy
Vykhodila na bereg Katyusha
Na vysokiy bereg na krutoy
Vykhodila na bereg Katyusha
Na vysokiy bereg na krutoy

Vykhodila, pasnyu zabodila
Pro stepnogo sizogo orla
Pro togo, kotorogo lyubila
Pro togo, Ch'i pis'ma beregla
Pro togo, kotorogo lyubila
Pro togo, Ch'i pis'ma beregla

Oy, ty, pesnya, pecen'ka devit'ya
Ty leti za yasnym solntsem vsled
I boytsu na dal'nem pogranich'e
Ot Katyushi pereday privet
I boytsu na dal'nem pogranich'e
Ot Katyushi pereday privet

Pust' on vspomnit devushku prostuyu
Pust' uslyshit kak ona poet
Pust' on zemlyu berezhet rodnuyu
A lyubov' Katyusha sberezhet
Pust' on zemlyu berezhet rodnuyu
A lyubov' Katyusha sberezhet

Rastsvetali yabloni i grushi
Poplyli tumany nad rekoy
Vykhodila na bereg Katyusha
Na vysokiy bereg na krutoy
Vykhodila na bereg Katyusha
Na vysokiy bereg na krutoy

|another=
'''汉译'''
《喀秋莎》
正当梨花开遍了天涯,
河上飘着柔漫的轻纱;
喀秋莎站在峻峭的岸上,
歌声好像明媚的春光。 
喀秋莎站在峻峭的岸上,
歌声好像明媚的春光。

姑娘唱着美妙的歌曲,
她在歌唱草原的雄鹰;
她在歌唱心爱的人儿,
她还藏着爱人的书信。
她在歌唱心爱的人儿,
她还藏着爱人的书信。

啊,这歌声,姑娘的歌声,
跟着光明的太阳飞去吧!
去向远方边疆的战士,
把喀秋莎的问候传达。 
去向远方边疆的战士,
把喀秋莎的问候传达。

驻守边疆年轻的战士,
心中怀念遥远的姑娘;
勇敢战斗保卫祖国,
喀秋莎爱情永远属于他。
勇敢战斗保卫祖国,
喀秋莎爱情永远属于他。

正当梨花开遍了天涯,
河上飘着柔漫的轻纱;
喀秋莎站在峻峭的岸上,
歌声好像明媚的春光。
喀秋莎站在峻峭的岸上,
歌声好像明媚的春光。
}}
效果
本段落中所使用的歌词,其著作权属于原著作权人,仅以介绍为目的引用。Lua错误 在package.lua的第80行:module 'Module:Error' not found
修改自{{LyricsKai/colors}}
那就是我们的奇迹
代码
{{LyricsKai/multi
|original[l]|romaji|translated[r,tra]
|reserveWidth=300px
|colors={{llcc|honoka|eli|kotori|umi|rin|maki|nozomi|hanayo|nico}};lg({{llcc|honoka|kotori|umi|d=,}});lg({{llcc|rin|maki|hanayo|d=,}});lg({{llcc|eli|nozomi|nico|d=,}})
|charas=高坂穗乃果;绚濑绘里;南小鸟;园田海未;星空凛;西木野真姬;东条希;小泉花阳;矢泽妮可;高坂穗乃果、南小鸟、园田海未;星空凛、西木野真姬、小泉花阳;绚濑绘里、东条希、矢泽妮可
|charaBlock=on
|colorsMode=on
|romajiColors=on
|traColors=on
|original=作詞:畑 亜貴 作曲・編曲:黒須克彦

@1さあ…夢を叶えるのはみんなの勇気
@11負けない@12(こころで)@10明日へ駈けて行こう

@10強い強い願い事が
@10僕たちを導いてくれた
@11次は絶対ゆずれないよ
@11残された時間を握りしめて

@12ただの思い出 それだけじゃいやだよ
@12精一杯 力の限り走るんだ
(Chance for me! Chance for you!)

さあ…夢を抱きしめたら上を向いて
@10君の世界が 大きく変わるよ
さあ…夢を叶えるのはみんなの勇気
@11負けない@12(こころで)@明日へ駈けて行こう

@11熱い熱い期待のなかで
@11僕たちは喜びを歌おう
@12同じ想い感じてみてよ
@12限られた時間を楽しもうよ

@10もう止められない 情熱の勝ちだね
@10悔やむより走り続けよう
@10不意に見た空 こんなにも青いよ
@10大丈夫 あきらめないで走るんだ
(Dance with me! Dance with you!)

そう…あの日夢見たのはみんなの笑顔
@10君の笑顔さ だから笑ってよ
そう…あの日おなじ夢を描いたんだ
@11輝く@12(瞳は)@明日を信じてた

(Hi! Hi! 最後まで駆け抜けるよ!)

さあ…夢を抱きしめたら上を向いて
@10君の世界が 大きく変わるよ
さあ…夢を叶えるのはみんなの勇気
@11負けない@12(こころで)@明日へ駈けて行こう

そう…あの日夢見たのはみんなの笑顔
@10君の笑顔さ だから笑ってよ
そう…あの日おなじ夢を描いたんだ
@11輝く@12(瞳は)@明日を信じてた
@1負けない@(こころで)明日を信じてた

いまここで出会えた奇跡
忘れないで 僕たちの季節

|romaji=Romaji:

@1sa... yume o kanaeru no wa minna no yuki
@11makenai@12 (kokoro de) @10ashita e kakete ikou

@10tsuyoi tsuyoi negaigoto ga
@10bokutachi o michibiite kureta
@11tsugi wa zettai yuzurenai yo
@11nokosa reta jikan o nigirishimete

@12tada no omoide sore dake ja iyada yo
@12seiippai chikara no kagiri hashiru nda
(Chance for me! Chance for you!)

sa... yume o dakishimetara ue no muite
@10kimi no sekai ga okiku kawaru yo
sa... yume o kanaeru no wa minna no yuki
@11makenai@12 (kokoro de) @ashita e kakete ikou

@11atsui atsui kitai no naka de
@11bokutachi wa yorokobi o utaou
@12onaji omoi kanjite mite yo
@12kagirareta jikan o tanoshimou yo

@10mo tome rarenai jonetsu no kachida ne
@10kuyamu yori hashiri tsudzukeyou
@10fui ni mita sora konnanimo aoi yo
@10daijobu akiramenaide hashiru nda
(Dance with me! Dance with you!)

so... ano hi yumemita no wa minna no egao
@10kimi no egao sa dakara waratte yo
so... ano hi onaji yume o egaita nda
@11kagayaku@12 (hitomi wa) @ashita o shinji teta

(Hi! Hi! saigomade kakenukeru yo! )

sa... yume o dakishimetara ue o muite
@10kimi no sekai ga okiku kawaru yo
sa... yume o kanaeru no wa minna no yuki
@11makenai@12 (kokoro de) @ashita e kakete ikou

so... ano hi yumemita no wa minna no egao
@10kimi no egao sa dakara waratte yo
so... ano hi onaji yume o egaita nda
@11kagayaku@12 (hitomi wa) @ashita o shinji teta
@1makenai@ (kokoro de) ashita o shinji teta

ima koko de deaeta kiseki
wasurenaide bokutachi no kisetsu

|translated=翻译:

来吧 梦想的实现离不开大家的勇气
怀着不服输的决心 向着明天驰骋而去

强烈的非常强烈的愿望
为我们指明了方向
下一次绝对不能退让
仅存的时间要好好把握

仅仅只留下回忆 我可不愿意这样
竭尽全力 竭尽所能的冲刺
(Chance for me! Chance for you!)

来吧 紧紧拥抱着梦想它昂首望天
你的世界 就会发生很大的变化
来吧 梦想的实现离不开大家的勇气
怀着不服输的决心 向着明天驰骋而去

热烈的非常热烈的期待着
属于我们快乐的演唱
同样的想法一起感受着
在这有限的时间里去享受吧

已经停不下来 即将取胜了的这份热情
不留遗憾的继续奔跑下去吧
不经意间仰望 天空竟如此青蓝
没关系,不要放弃奔跑起来吧
(Dance with me! Dance with you!)

这样啊 那天梦中大家的笑容
也是你的笑容 因此微笑吧
这样啊 那天所描绘的是同样的梦
闪耀的眼中相信着明天

(一往直前到最后为止!)

来吧 紧紧拥抱着梦想它昂首望天
你的世界 就会发生很大的变化
来吧 梦想的实现离不开大家的勇气
怀着不服输的决心 向着明天驰骋而去

这样啊 那天梦中大家的笑容
也是你的笑容 因此微笑吧
这样啊 那天所描绘的是同样的梦
闪耀的眼中相信着明天
怀着不服输的决心 相信明天

如今在这里所邂逅的奇迹
请不要忘记 属于我们的季节
}}
效果
本段落中所使用的歌词,其著作权属于原著作权人,仅以介绍为目的引用。Lua错误 在package.lua的第80行:module 'Module:Error' not found
一列原文三列译文
Sogno di Volare
代码
{{LyricsKai/multi
|original|translated|another|mondegreen

|llang= it
|rlang= en
|anotherlang= zh
|mondegreenlang= zh

|original='''意大利语'''

Una volta che avrai
Spiccato il volo, deciderai
Sguardo verso il ciel saprai:
Lì a casa il cuore sentirai.

Una volta che avrai
Spiccato il volo, deciderai
Sguardo verso il ciel saprai:
Lì a casa il cuore sentirai.

Prenderà il primo volo
Verso il sole il grande uccello
Sorvolando il grande Monte Ceceri
Riempendo l'universo di stupore e gloria.

Una volta che avrai spiccato il volo,
Allora deciderai
Sguardo verso il ciel saprai:
Lì a casa il cuore sentirai.

L'uomo verrà portato dalla sua creazione
Come gli uccelli, verso il cielo...

(mood)

Riempendo l'universo di stupore e gloria.

Una volta che avrai
Spiccato il volo, deciderai
Sguardo verso il ciel saprai:
Lì a casa il cuore sentirai.

Gloria! Gloria!

|translated='''英语翻译'''

Once you have taken flight,
You'll decide,
Gaze towards the sky, you'll know that
That is where your heart will feel at home.

Once you have taken flight,
You'll decide,
Gaze towards the sky, you'll know that
That is where your heart will feel at home.

The first great bird
Will take flight toward the sun,
Sweeping over the great Mount Ceceri,
Filling the universe with wonder and glory.

Once you have taken flight,
You'll decide,
Gaze towards the sky, you'll know that
That is where your heart will feel at home.

Man will be lifted by his own creation,
Just like birds, towards the sky...

(mood)

Filling the universe with wonder and glory.

Once you have taken flight,
You'll decide,
Gaze towards the sky, you'll know that
That is where your heart will feel at home.

Glory! Glory!

|another='''中文翻译'''

张开双翼,踏向星辰,
是汝之抉择,
星空浩瀚,方知
此处乃汝之归宿

张开双翼,踏向星辰,
是汝之抉择
星空浩瀚,方知
此处乃汝归宿

鸟之头筹者
将迎日而升
其翼划过奇奇里山
奇迹同荣耀,是以盈于宇宙!

张开双翼,踏向星辰,
是汝之抉择
星空浩瀚,方知
此处乃汝之归宿!

其人,携他之造物,
似鸟,达至天之国!

(语气词)

心向自由,乘风而去,奇迹同荣耀是以盈于宇宙!

汝若张开双翼,踏向星辰
便是汝之抉择,
星空浩瀚,方知
此处乃汝之归宿!

荣耀!荣耀!

|mondegreen='''中文空耳'''

不要存档接着打
奇观太烦落地几个啦
这工业区建什么
你丫别采我的象的牙

读了存档接着打
奇观太烦落地七个了
这工业区建成了
你丫别踩我的商队呀

野蛮人哔了狗
敢小瞧了我的城防
扫荡蛮族,阴狠的甘地钳制你
低调的繁荣,无礼你忍受,必信我能搞你丫

若能多他一回合(谁刚才扔核弹喽)
你都炸平几个啦
曼哈顿是建什么
你让我尝过的送你丫

科技繁荣了产出,打的怂了停战条约
武力和智力并存兼容

污→~污↘~污→~污↗~污↘~污→~

低调的繁荣,无礼你忍受,必信我能搞你丫~~~

不能和他议了和
谁敢谴责核弹就给他
这移民去建什么
你要盖城我就宣你丫

搞你丫!搞你丫!!
}}
效果
本段落中所使用的歌词,其著作权属于原著作权人,仅以介绍为目的引用。Lua错误 在package.lua的第80行:module 'Module:Error' not found

local p = {}

local getArgs = require("Module:Arguments").getArgs
local lang = require("Module:Lang")
local errmsg = require("Module:Error")
local lrcmod = require("Module:Lyrics/colors")

local getCharaBlock = require("Module:Lyrics/colors/sub")._charaBlock

local showErrorMessage = function(msg, args)
    if args.errMsg ~= "off" then
        return errmsg.error{ message = msg }
    end
end

local ce_cache = {}
local apply_ce = function(text)
	text = mw.ustring.gsub(text, '%$([%d%$%[@])', function(s)
		if not ce_cache[s] then ce_cache[s] = mw.getCurrentFrame():expandTemplate{ title = 'ce', args = {s} } end
		return ce_cache[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

function p._lyrics(args)
    ------------------------ 处理参数 ------------------------
    local colorsMode = args.colorsMode == "on" -- 是否开启彩色显示开关。
    
    local colors, map_aliases, charas = lrcmod.parseArgs(args.colors or '', args.charas or '', args.charaBlock)
    
    local versions = {}
    for k, v in pairs(args) do
        if type(k) == "number" then
            local def = mw.text.trim(mw.ustring.gsub(v or "", "\n", "")) -- 删除名称定义语句中的所有换行及首尾空白字符。
            local key, aliases = mw.ustring.match(def, "^([^%[]*)%[([^%]]*)%]$") -- 匹配名称和缩写列表。
            if key == nil then
                if mw.ustring.find(def, "[%[%]]") then -- 有意定义缩写列表,因此为格式错误。
                    if args.errMsg ~= "off" then
                        return errmsg.error{ message = mw.ustring.format("格式错误:第%d个名称定义语句“%s”中括号“[”和“]”不配对。", k, v) }
                    end
                else
                    key = def -- 无意定义缩写列表,将整个字符串视为名称。
                end
            end
            key = mw.text.trim(key) -- 去除首尾空白字符。
            if key == "" then
                if args.errMsg ~= "off" then
                    return errmsg.error{ message = mw.ustring.format("格式错误:在第%d个名称定义语句“%s”中未找到名称或者全部为空白字符。", k, v) }
                end
            else
                -- 获取所有缩写名称
                local inter = mw.text.gsplit(aliases or "", ",")
                aliases = {}
                for alias in inter do
                    alias = mw.text.trim(alias)
                    if alias ~= "" and aliases[alias] == nil then
                        table.insert(aliases, alias)
                        aliases[alias] = true
                    end
                end
                
                -- 获取名称及缩写对应参数值的通用函数。
                local getParam = function(postfix)
                    local temp = args[key..postfix] -- 以名称优先。
                    if mw.text.trim(temp or "") == "" then -- 名称对应参数不存在,则按顺序检查缩写对应参数。
                        temp = nil
                        for _, alias in ipairs(aliases) do
                            if mw.text.trim(args[alias..postfix] or "") ~= "" then -- 这个缩写对应的参数符合条件。
                                if temp ~= nil then -- 已有符合条件的对应参数。
                                    if args.errMsg ~= "off" then
                                        return false, errmsg.error{ message = mw.ustring.format("检测到重复的参数“%s”和“%s”,它们使用的名称缩写“%s”和“%s”都表示“%s”。", temp..postfix, alias..postfix, temp, alias, key) }
                                    end
                                    --temp = alias -- 顺序后的覆盖顺序前的。
                                end
                                temp = alias
                            end
                        end
                        if temp ~= nil then
                            temp = args[temp..postfix]
                        end
                    end
                    return true, temp
                end
                
                local success, result
                -- 获取语言代码。
                success, result = getParam("lang")
                if not success then
                    return result
                end
                local lang = result
                
                -- 获取自定义样式。
                success, result = getParam("style")
                if not success then
                    return result
                end
                local style = result
                
                -- 获取歌词的所有行。
                local lines = mw.text.split(apply_ce(args[key] or ""):match("^(.-)%s*$"), "\n")
                if colorsMode then -- 开启颜色模式。
                    -- 检查该列是否需要颜色处理。
                    success, result = getParam("Colors")
                    if not success then
                        return result
                    end
                    -- 默认第一列需要颜色处理。
                    if #versions == 0 then
                        result = result or "on"
                        lines = lrcmod.parse(colors, charas, args.chorusName or '', lines)
                    elseif result == "on" then
                        -- 解析颜色歌词。
                        lines = lrcmod.parse(colors, charas, args.chorusName or '', lines)
                    end
                end
                
                -- 将每一个翻译版本创建成项。
                if args[key] ~= nil then
                    table.insert(versions, key)
                    local entry = {
                        lines = lines,
                        lang = lang,
                        style = style
                    }
                    if #versions == 1 then entry.lang = entry.lang or "ja" -- 默认第一列时日文。
                    else entry.lang = entry.lang or "zh" -- 默认第二列时中文。
                    end
                    
                    versions[key] = entry
                end
            end
        end
    end
    
    ------------------------ 核心代码 ------------------------
    local html = mw.html.create("div")
        :addClass("Lyrics")
        :css("width", args.width)
        :cssText(args.containerstyle)
    
    -- 检查任何一列歌词是否包含ruby。
    if mw.text.trim(args.hasRuby or "") ~= "" then
        html:addClass("Lyrics-has-ruby")
    else
        local hasRuby = false
        for i = 1, #versions do
            if args[versions[i]]:find("<ruby") then
                hasRuby = true
                break
            end
        end
        
        if hasRuby then
            html:addClass("Lyrics-has-ruby")
        else
            html:addClass("Lyrics-no-ruby")
        end
    end

    -- 创建charaBlock。
    if args.charaBlock == "on" then
        html:tag("p"):node(getCharaBlock{
            colors = args.colors,
            charas = args.charas,
            groupName = args.groupName,
            groupColor = versions[versions[1]].style -- 默认为第1列的样式
        })
    end

    local len = 0 -- 行数的最大值
    for i = 1, #versions do
        len = math.max(len, #(versions[versions[i]].lines))
    end

    for line = 1, len do
        local div = html:tag("div"):addClass("Lyrics-line")
        
        local emptyline = true -- 是否为空行。
        for i = 1, #versions do
            if (versions[versions[i]].lines[line] or "") ~= "" then
                emptyline = false
            end
        end
        if emptyline then
            div:tag("div")
                :attr("data-column", 1) -- 当前的列编号。
                :attr("data-column-count", 1) -- 列的总数。
                :addClass("Lyrics-column") -- 通用列样式。
                :newline()
        else
            for i = 1, #versions do
                local entry = versions[versions[i]]
                local nlang = lang.wrap(entry.lines[line] or "", entry.lang)
                div:tag("div")
                    :attr("data-column", i) -- 当前的列编号。
                    :attr("data-column-count", #versions) -- 列的总数。
                    :addClass("Lyrics-column") -- 通用列样式。
                    :addClass("Lyrics-column-"..entry.lang) -- 针对语言的样式。
                    :addClass("Lyrics-col"..tostring(i)) -- 针对特定列的样式。
                    :addClass("Lyrics-column-suppressed") -- 宽屏时压缩在一行内的列的样式。
                    :cssText(entry.style)
                    :css("width", "calc(95% / "..tostring(#versions)..")") -- 在一行内放下所有列。
                    :node(nlang)
                div:tag("div")
                    :attr("data-column", i) -- 当前的列编号。
                    :attr("data-column-count", #versions) -- 列的总数。
                    :addClass("Lyrics-column") -- 通用列样式。
                    :addClass("Lyrics-column-"..entry.lang) -- 针对语言的样式。
                    :addClass("Lyrics-col"..tostring(i)) -- 针对特定列的样式。
                    :addClass("Lyrics-column-wrapped") -- 窄屏时拆分为多行的列的样式。
                    :cssText(entry.style)
                    :node(nlang)
            end
        end
    end

    -- Clear the floating
    html:tag("div"):css("clear", "both")

    local css = mw.getCurrentFrame():extensionTag{ name = "templatestyles", args = { src = "Template:LyricsKai/multi/styles.css" } }
    
    return css .. tostring(html)
end

function p.lyrics(frame)
    local args = getArgs(frame, { wrappers = "Template:LyricsKai/multi" })
    return p._lyrics(args)
end

return p