Aegisub 自动化 笔记
本文最后更新于 86 天前。

正则替换

选出每句话

正则表达式: ctrl+h调出搜索替换的框框,勾选使用正则表达式,搜索内容写入^替换内容写入你要添加的内容,注意\要转意,比如你要添加{\blur1}就要写入{\blur1}

选出每个字

(?=.)

数字取整数

(\d*)\.\d*
保留$1

Karaoke Template

简单记录一些Karaoke Template的编写语法。

格式

文本行特效写打Karaoke(可多行),代码行改注释,特效中加指定类型。选中所有行,运行脚本。

Template行特效类型

template pre-line

直接在句子前面加上代码。

template line

整句(line)进行代码操作。

将文本中的{\k__}替代为template line中的内容(文字或代码),例如:

Comment: 0,0:00:00.00,0:00:00.00,CN_UP,,0,0,0,template line,测试
Comment: 0,0:00:00.00,0:00:05.00,CN_UP,,0,0,0,karaoke,{\k1}a{\k1}b{\k1}c{\k1}d
Dialogue: 0,0:00:00.00,0:00:05.00,CN_UP,,0,0,0,fx,测试a测试b测试c测试d

template syl

音节(syllable),即每个被{\k__}划分的字符,进行代码操作,并将字符以单行的形式显示。

需要注意的是,在第一个{\k__}前,会默认存在一个字符(即使是空)。

Comment: 0,0:00:00.00,0:00:00.00,CN_UP,,0,0,0,template syl,测试
Comment: 0,0:00:00.00,0:00:05.00,CN_UP,,0,0,0,karaoke,{\k1}a{\k1}b{\k1}c{\k1}d
Dialogue: 0,0:00:00.00,0:00:05.00,CN_UP,,0,0,0,fx,测试
Dialogue: 0,0:00:00.00,0:00:05.00,CN_UP,,0,0,0,fx,测试a
Dialogue: 0,0:00:00.00,0:00:05.00,CN_UP,,0,0,0,fx,测试b
Dialogue: 0,0:00:00.00,0:00:05.00,CN_UP,,0,0,0,fx,测试c
Dialogue: 0,0:00:00.00,0:00:05.00,CN_UP,,0,0,0,fx,测试d

template syl char

对每个字符(character)进行操作。syl可写可不写,因为tempate默认是对音节进行操作的。

Comment: 0,0:00:00.00,0:00:00.00,CN_UP,,0,0,0,template syl char,{\pos($sx,$sy)}
Comment: 0,0:00:00.00,0:00:05.00,CN_UP,,0,0,0,karaoke,{\k100}one{\k100}two

Dialogue: 0,0:00:00.00,0:00:05.00,CN_UP,,0,0,0,fx,{\pos(588,360)}o
Dialogue: 0,0:00:00.00,0:00:05.00,CN_UP,,0,0,0,fx,{\pos(609,360)}n
Dialogue: 0,0:00:00.00,0:00:05.00,CN_UP,,0,0,0,fx,{\pos(631,360)}e
Dialogue: 0,0:00:00.00,0:00:05.00,CN_UP,,0,0,0,fx,{\pos(648,360)}t
Dialogue: 0,0:00:00.00,0:00:05.00,CN_UP,,0,0,0,fx,{\pos(667,360)}w
Dialogue: 0,0:00:00.00,0:00:05.00,CN_UP,,0,0,0,fx,{\pos(692,360)}o

可以看到,以上代码把单个字符进行了分行,并指定到了对应的绝对位置。

template syl noblank

使生成代码时删去空行。

template syl notext

使生成代码时,所有文字被删除,但时间依然保留。

template syl noblank

使生成代码时删去空行。

template syl noblank notext

使生成代码时,只剩下有文字的,且被替换成了空行。

template syl keeptags

正常执行template时,形如{\an}的标签会被自动删除。为了保留标签,可以打上keeptags。

循环:template syl loop 5

正常执行template时,代码只会被执行一次。为了多次执行,可以打上loop+数字。

相关的内联变量:!j! !maxj!``!maxloop()!
说明:j为计数器,maxj为总的次数
maxloop()可以用来设置循环次数。如果此函数指定了循环,那么就不用再写“template loop xxx”。

例如

Comment: 0,0:00:00.00,0:00:00.00,CN_UP,,0,0,0,template line loop 5,!j! | !maxj! | !j*100! 
Comment: 0,0:00:00.00,0:00:05.00,CN_UP,,0,0,0,karaoke,{\k100}one{\k100}two{\k100}{\fs50}three{\k100}four

Dialogue: 0,0:00:00.00,0:00:05.00,CN_UP,,0,0,0,fx,1 | 5 | 100 one1 | 5 | 100 two1 | 5 | 100 three1 | 5 | 100 four
Dialogue: 0,0:00:00.00,0:00:05.00,CN_UP,,0,0,0,fx,2 | 5 | 200 one2 | 5 | 200 two2 | 5 | 200 three2 | 5 | 200 four
Dialogue: 0,0:00:00.00,0:00:05.00,CN_UP,,0,0,0,fx,3 | 5 | 300 one3 | 5 | 300 two3 | 5 | 300 three3 | 5 | 300 four
Dialogue: 0,0:00:00.00,0:00:05.00,CN_UP,,0,0,0,fx,4 | 5 | 400 one4 | 5 | 400 two4 | 5 | 400 three4 | 5 | 400 four
Dialogue: 0,0:00:00.00,0:00:05.00,CN_UP,,0,0,0,fx,5 | 5 | 500 one5 | 5 | 500 two5 | 5 | 500 three5 | 5 | 500 four

此处j代表循环此处,min和max都是j在运行中的最大和最小值。

template syl fx hk

正常执行template时,每一个音节都会被执行。为了只执行选定的音节,可以打上fx+标记;并在音节前加入相同的标记“-标记”。这时会对标记之后的音节执行操作。

Comment: 0,0:00:00.00,0:00:00.00,CN_UP,,0,0,0,template syl fx hk,aaa
Comment: 0,0:00:00.00,0:00:05.00,CN_UP,,0,0,0,karaoke,{\k100}one{\k100}two{\k100\-hk}three{\k100}four

Dialogue: 0,0:00:00.00,0:00:05.00,CN_UP,,0,0,0,fx,aaathree
Dialogue: 0,0:00:00.00,0:00:05.00,CN_UP,,0,0,0,fx,aaafour

为了只执行选定范围的音节,可以在结束音节后添加一个无关标签表示结束。

Comment: 0,0:00:00.00,0:00:00.00,CN_UP,,0,0,0,template syl fx hk,aaa
Comment: 0,0:00:00.00,0:00:05.00,CN_UP,,0,0,0,karaoke,{\k100}one{\k100\-hk}two{\k100}three{\k100\-mc}four

Dialogue: 0,0:00:00.00,0:00:05.00,CN_UP,,0,0,0,fx,aaatwo
Dialogue: 0,0:00:00.00,0:00:05.00,CN_UP,,0,0,0,fx,aaathree

实际上,每个音节的原始标记都是空的。与fx相关的内联函数为!syl.inline_fx!,用于获取指定音节的标签名

Comment: 0,0:00:00.00,0:00:00.00,CN_UP,,0,0,0,template syl,!syl.inline_fx!
Comment: 0,0:00:00.00,0:00:05.00,CN_UP,,0,0,0,karaoke,{\k100}one{\k100\-hk}two{\k100}three{\k100\-mc}four

Dialogue: 0,0:00:00.00,0:00:05.00,CN_UP,,0,0,0,fx,
Dialogue: 0,0:00:00.00,0:00:05.00,CN_UP,,0,0,0,fx,one
Dialogue: 0,0:00:00.00,0:00:05.00,CN_UP,,0,0,0,fx,hktwo
Dialogue: 0,0:00:00.00,0:00:05.00,CN_UP,,0,0,0,fx,hkthree
Dialogue: 0,0:00:00.00,0:00:05.00,CN_UP,,0,0,0,fx,mcfour

code syl

在code语句中可以加入lua语句。

! !来表示代码块。

模板

clip – 由左至右消失

{\pos($sx, $sy)\clip($sleft, $stop, $sright, $sbottom)\t($sstart, !$sstart+$sdur!, 1, \clip($sright, $stop, $sright, $sbottom))}

iclip – 由左至右显现

{\pos($sx, $sy)\iclip($sleft, $stop, $sright, $sbottom)\t($sstart, !$sstart+$sdur!, 1, \iclip($sright, $stop, $sright, $sbottom))}

内联变量

自适应变量 Automatic variants

时间类 $start $end $mid

行或音节的开始时间、结束时间、中点时间,行是绝对时间,音节是相对行的时间(通用,自动进行判断)

以下代码可以实现单词逐一fade出现:

Comment: 0,0:00:00.00,0:00:00.00,CN_UP,,0,0,0,template line,{\alpha&HFF\t($start,$end,\alpha&H00)}
Comment: 0,0:00:00.00,0:00:05.00,CN_UP,,0,0,0,karaoke,{\k100}one{\k100}two{\k100}three{\k100}four

Dialogue: 0,0:00:00.00,0:00:05.00,CN_UP,,0,0,0,fx,{\alpha&HFF\t(0,1000,\alpha&H00)}one{\alpha&HFF\t(1000,2000,\alpha&H00)}two{\alpha&HFF\t(2000,3000,\alpha&H00)}three{\alpha&HFF\t(3000,4000,\alpha&H00)}fourr

行持续时间

!line.duration!
$ldur
以上二者均可以表示行的持续时间,但是如果!line.duration!出现在retime函数后,其返回值变化。$ldur始终返回原字幕的持续时间。

位置类 $lleft $lright $ltop $lbottom

例如,表示一句话的完整clip范围

clip($lleft,$ltop,$lright,$lbottom)

$sx $sy
以上代码可以同样用template syl与$sx $sy来实现。$sx$sy是音节在默认对齐方式下的绝对位置(x,y),配合\pos和\move使用。

Comment: 0,0:00:00.00,0:00:00.00,CN_UP,,0,0,0,template syl,{\alpha&HFF\t($start,$end,\alpha&H00)\pos($sx,$sy)}
Comment: 0,0:00:00.00,0:00:05.00,CN_UP,,0,0,0,karaoke,{\k100}one{\k100}two{\k100}three{\k100}four

Dialogue: 0,0:00:00.00,0:00:05.00,CN_UP,,0,0,0,fx,{\alpha&HFF\t(0,0,\alpha&H00)\pos(452,23)}
Dialogue: 0,0:00:00.00,0:00:05.00,CN_UP,,0,0,0,fx,{\alpha&HFF\t(0,1000,\alpha&H00)\pos(495,23)}one
Dialogue: 0,0:00:00.00,0:00:05.00,CN_UP,,0,0,0,fx,{\alpha&HFF\t(1000,2000,\alpha&H00)\pos(579,23)}two
Dialogue: 0,0:00:00.00,0:00:05.00,CN_UP,,0,0,0,fx,{\alpha&HFF\t(2000,3000,\alpha&H00)\pos(679,23)}three
Dialogue: 0,0:00:00.00,0:00:05.00,CN_UP,,0,0,0,fx,{\alpha&HFF\t(3000,4000,\alpha&H00)\pos(783,23)}four

$lx $ly

对\pos代码使用的x,y坐标(当对齐方式未被重写时)

syl.width音节所占的宽度

$lcenter $lmiddle

句子/音节(s)默认中心位置
例如:获得单个字/音节逐个变大的K效果

an5\pos($scenter,$smiddle)\1a&HFF&\t($start,$end,\bord13\3a&HFF&)

Lua语法

更多Lua语法相关请转到单独文章:Lua For Aegisub

计算

用!和!来表示lua语句和运算。

例如:

行结束时间

行结束时间
$lend
又可以写作
!$lstart+$ldur!

数值运算

Comment: 0,0:00:00.00,0:00:00.00,CN_UP,,0,0,0,template syl,!100+99!
Comment: 0,0:00:00.00,0:00:05.00,CN_UP,,0,0,0,karaoke,文字

Dialogue: 0,0:00:00.00,0:00:05.00,CN_UP,,0,0,0,fx,199
Dialogue: 0,0:00:00.00,0:00:05.00,CN_UP,,0,0,0,fx,199文字

文字

" "string,用 ..来连接字符串。

Comment: 0,0:00:00.00,0:00:00.00,CN_UP,,0,0,0,template syl,!"AB".."CD"!
Comment: 0,0:00:00.00,0:00:05.00,CN_UP,,0,0,0,karaoke,文字

Dialogue: 0,0:00:00.00,0:00:05.00,CN_UP,,0,0,0,fx,ABCD
Dialogue: 0,0:00:00.00,0:00:05.00,CN_UP,,0,0,0,fx,ABCD文字

基础函数

数学函数

绝对值 math.abs(a)
向下取整 math.floor(a)
向上取整 math.ceil(a)
正切 math.tan(a)
a^b math.pow(a,b)

设置层

!relayer()!

调用字幕文字

!syl.text_stripped!可以使文字重复一次,并带上此函数后面的标签。

随机数

!(math.random(10,80))!表示生成一个10~80之间的随机数

赋值/调用

!remember("变量名",值)!
!recall.变量名!
这两个函数不能隔行使用。

用table来实现全局记忆的随机数

注意:此处用的是无序表。

Comment: 0,0:00:00.00,0:00:05.00,Default,,0,0,0,code once,rd = {time = math.random(500,1000)}
Comment: 0,0:00:00.00,0:00:05.00,Default,,0,0,0,template char,!rd.time!
Comment: 0,0:00:00.00,0:00:05.00,Default,,0,0,0,karaoke,test 

用函数实现全局记忆

创建一个函数,用于将随机数存入表中。

Comment: 0,0:00:00.00,0:00:00.00,Default,,0,0,0,code once,temp={}
Comment: 0,0:00:00.00,0:00:00.00,Default,,0,0,0,code once,function setTemp(ref,value) temp[re*f]=value return value end
Comment: 0,0:00:00.00,0:00:00.00,Default,,0,0,0,template line,!setTemp("测试",11)! !temp.测试!

颜色函数

更多颜色函数,查看颜色和渐变
_G.ass_color()
这是一个用来设定转换颜色的函数,ass表示颜色的格式,_G.ass_color(42,220,187)即表示HBBDC2A色

例如,生成随机颜色

{\1c!_G.ass_color(math.random(255),math.random(255),math.random(255))!}

重设时间函数retime

标准格式:retime("mode",调整时间t1,调整时间t2)
注:t1,t2是相对于当前模式下的开始结束时间的偏移量。
retime手册

模式

syl
start_time= line.start_time + syl.start_time + t1
end_time= line.start_time + syl.end_time + t2
开始时间为音节的开始时间,结束时间为音节的结束时间,即k标签的开始到结束时间。

presyl
start_time
end_time =line.start_time + Syl.start_time + t1/t2
开始结束时间均为音节的开始时间,通常用于提前音节的开始时间。
举例:音节出现前的修饰图案,例如桜都巨人4的ED。

postsyl
start_time
end_time =line.start_time + Syl.end_time + t1/t2
开始结束时间均为音节的结束时间

line
开始时间为行的开始时间,结束时间为行的结束时间。

preline
开始结束时间均为行的开始时间。

postline
开始结束时间均为行的结束时间。

start2syl
开始时间为行的开始时间,结束时间为音节的开始时间。

syl2end
开始时间为音节的结束时间,结束时间为行的结束时间。

setorabs
开始时间为t1,结束时间为t2。
例:逐帧抖动

Comment: 0,0:00:00.00,0:00:05.00,Default,,0,0,0,template line,!maxloop($ldur/1000*24)!!retime("abs",(j-1)*1000/24,j*1000/24)!{\an5\pos(!$scenter+math.random(-10,10)!,!$smiddle+math.random(-10,10)!)}
Dialogue: 0,0:00:00.00,0:00:00.85,Default,,0,0,0,,{\k33}献{\k33}上{\k33}心{\k33}脏{\k33}!

sylpct
start_time = line.start_time + syl.start_time + t1*syl.duration/100
end_time = line.start_time + syl.start_time + t2*syl.duration/100
开始结束时间为音节的开始时间+(t*音节持续时间ms/100)

音节序数内联函数$si

si是一个表示音节位次的函数。例如
单句: 心 臓 を 捧 げ よ
序数: 1 2 3 4 5 6

在未设置k的时候,可以自建一个计数器ci

返回视频一帧的持续时间

_G.aegisub.ms_from_frame(1)
参数为视频的有效帧数编号

返回视频大小

_G.aegisub.video_size()

逻辑语句

见专题文章。And和Or

分离整数小数

math.modf() 输出两个数

a,b=math.modf(123.45)

>

a=123 b=0.45

保留指定位数函数[1]

function num(origin,count) a=origin*(10^count); a_j=a-math.modf(a); if math.abs(a_j)>=0.5 then num_out=math.modf(a+origin/math.abs(origin))/(10^count); else num_out=math.modf(a)/(10^count);end; return num_out; end;
function num(origin,count) 
    a=origin*(10^count); 
    a_j=a-math.modf(a); 
    if math.abs(a_j)>=0.5 
        then
        num_out=math.modf(a+origin/math.abs(origin))/(10^count);
        else 
        num_out=math.modf(a)/(10^count);
    end; 
    return num_out; 
end;

Yutils 文字转图形

见相关专题

判断类型

_G.type()

String相关高级函数

字符和数值转换

在Aegisub中,调用tostringtonumber两个函数需要调用库。
实际使用如下
!_G.tonumber("123")!

tonumber还可以实现进制(2~36,默认10)的转换,例如
_G.tonumber("F",16) >> 15

!_G.tostring(123)!

参数检查assert

assert用来检查参数类型正确与否。

Comment: 0,0:00:00.00,0:00:00.00,Default,,0,0,0,code line,if _G.assert(_G.type(line) == "table", "line is not a table") then  xxx=2223 end
Comment: 0,0:00:00.00,0:00:00.00,Default,,0,0,0,template line,!xxx!

assert函数有两项,第一项为判断条件,第二项为错误内容。

_G.assert(_G.type(line)=="table", "line is not a table")

此行执行,如果line的类型为table,那么返回true,如果line类型不是table,则报错"line is not a table",并结束执行代码。

匹配字符函数string.match

string.match("string","pattern")此函数用于在字符串中匹配指定内容。第一个参数为字符串,第二个参数为模式,用正则表达式表示。

需要特别注意的是,lua的正则与普通的有所区别。[2]

string.match("te1standte2st","e%d")
>
e1

可以分组输出多个结果,例如

xxx,xx= string.match("te1standte2st","(%w+%d)(%w+%d%w+)")
print(xxx..xx)
>
te1  standte2st

语法糖/自函数:
string.match("string","pattern")也可以写作"string".match("pattern")

aa="te1standte2st"
!aa:match("e%d")!
>
e1

高级匹配函数gmatch

string.gmatch(str, pattern)
match函数只能匹配第一次得到的东西(参见:2.19 匹配字符函数 string.match)而gmatch可以返回每次得到的匹配内容[3]

返回一个迭代器函数(参见Lua for aegisub),每一次调用这个函数,返回一个在字符串 str 找到的下一个符合 pattern 描述的子串。如果参数 pattern 描述的字符串没有找到,迭代函数返回nil。[4]

例如,对于m25m26m27,用match("m$d+")只能得到m25,但是用gmatch可以得到m25 m26 m27

for word in string.gmatch("m25m26m27", "m%d+") do
    print(word) 
end

>

m25
m26
m27

因为传递参数每一次循环都会被赋新的值,所以通常需要在for循环前设置一个空表,来存储每次得到的内容。

向表中添加一个新元素的办法

xxx[#xxx+1]=k

也可以用自函数的形式来写gstring,例如
a:gmatch("%d")

匹配长绘图代码中的子代码

例如现在有一串长绘图代码

str="m 0 0 l 43 1 l 47 26 l 5 28 l 0 0 m 11 5 l 13 21 l 41 21 l 37 4 l 11 5 m 17 9 l 33 8 l 33 20 l 19 17 l 17 9 m 21 11 l 22 15 l 31 14 l 24 10 l 21 11 "
xxx={}  
for k in string.gmatch(str,"m [- .bl%d]+") do   
    xxx[#xxx+1]=k  
end

上面一段代码可以匹配m开头的图形代码,并存储到表xxx中。
ass代码如下;

Comment: 0,0:00:00.00,0:00:00.00,Default,,0,0,0,code syl noblank,str="m 0 0 l 43 1 l 47 26 l 5 28 l 0 0 m 11 5 l 13 21 l 41 21 l 37 4 l 11 5 m 17 9 l 33 8 l 33 20 l 19 17 l 17 9 m 21 11 l 22 15 l 31 14 l 24 10 l 21 11 "
Comment: 0,0:00:00.00,0:00:00.00,Default,,0,0,0,code syl noblank,xxx={}  for k in string.gmatch(str,"m [- .bl%d]+") do   xxx[#xxx+1]=k  end
Comment: 0,0:00:00.00,0:00:00.00,Default,,0,0,0,template syl noblank notext,!maxloop(#xxx)!{\p1}!xxx[j]!
Comment: 0,0:00:00.00,0:00:05.00,Default,,0,0,0,karaoke,{\k250}a

注:此方法并不能完全拆分出绘图的连通域,因为存在抵消覆盖的图形。

匹配绘图代码中的坐标

与上一节同理,只是更换了匹配的pattern。

Comment: 0,0:00:00.00,0:00:00.00,Default,,0,0,0,code syl noblank,str="m 0 0 l 43 1 l 47 26 l 5 28 l 0 0 m 11 5 l 13 21 l 41 21 l 37 4 l 11 5 m 17 9 l 33 8 l 33 20 l 19 17 l 17 9 m 21 11 l 22 15 l 31 14 l 24 10 l 21 11 "
Comment: 0,0:00:00.00,0:00:00.00,Default,,0,0,0,code syl noblank,xxx={}  for k in string.gmatch(str,"[-.%d]+ [-.%d]+") do   xxx[#xxx+1]=k  end
Comment: 0,0:00:00.00,0:00:00.00,Default,,0,0,0,template syl noblank notext,!maxloop(#xxx)!{\p1}!xxx[j]!
Comment: 0,0:00:00.00,0:00:05.00,Default,,0,0,0,karaoke,{\k250}a

分组匹配

延续上节,如果想把坐标的x、y值分别存入两个变量,则可以进行分组匹配。

Comment: 0,0:00:00.00,0:00:00.00,Default,,0,0,0,code syl noblank,str="m 0 0 l 43 1 l 47 26 l 5 28 l 0 0 m 11 5 l 13 21 l 41 21 l 37 4 l 11 5 m 17 9 l 33 8 l 33 20 l 19 17 l 17 9 m 21 11 l 22 15 l 31 14 l 24 10 l 21 11 "
Comment: 0,0:00:00.00,0:00:00.00,Default,,0,0,0,code syl noblank,xxx={}  for i,v in string.gmatch(str,"([-.%d]+) ([-.%d]+)") do   xxx[#xxx+1]={x=_G.tonumber(i),y=_G.tonumber(v)}    end
Comment: 0,0:00:00.00,0:00:00.00,Default,,0,0,0,template syl noblank notext,!maxloop(#xxx)!{\p1}!xxx[j].x!  !xxx[j].y!
Comment: 0,0:00:00.00,0:00:05.00,Default,,0,0,0,karaoke,{\k250}a

重复字符串string.rep

string.rep(string, n (,string))
返回字符串string的n个拷贝,第三个参数为间隔符。

string.rep("abcd",3," X ")

>

abcd X abcd X abcd

提取第一个单词 string.headtail

string.headtail(string)是Aegisub中特有的函数。函数会返回字符串开头到第一个空格的所有字符。

text = string.headtail("abc1 def")

>

text= "abc1"

去掉头尾空头 string.trim

string.trim(string)是Aegisub中特有的函数。可以去掉字符串头尾多个空格,留下中间的内容。中间的空格不会被删除。

text = string.trim("   abc1 def  ")

>

text = "abc1 def"

Table相关高级函数

连接Table元素_G.table.concat

_G.table.concat (table, sep, start, end)
第一个为表名,第二个为元素分隔符(如果不需要,则写""nil),第三个为从第几个元素开始连接,第四个为结束元素位置。
_G.table.concat只能连接表中下标是连续数字的元素。

Comment: 0,0:00:00.00,0:00:00.00,Default,,0,0,0,code line,tab={1,2,3,"a","b"}
Comment: 0,0:00:00.00,0:00:00.00,Default,,0,0,0,template line,!_G.table.concat(tab)!
Comment: 0,0:00:00.00,0:00:05.00,Default,,0,0,0,karaoke,
Dialogue: 0,0:00:00.00,0:00:05.00,Default,,0,0,0,fx,123ab
Comment: 0,0:00:00.00,0:00:00.00,Default,,0,0,0,code line,tab={1,2,3,"a","b"}
Comment: 0,0:00:00.00,0:00:00.00,Default,,0,0,0,template line,!_G.table.concat(tab," ",1,4)!
Comment: 0,0:00:00.00,0:00:05.00,Default,,0,0,0,karaoke,
Dialogue: 0,0:00:00.00,0:00:05.00,Default,,0,0,0,fx,1 2 3 a

将多种内容封装为表table.pack

_G.table.pack(...)可以随便填多个参数,此函数会把这些所有参数放入一个table中。此外,还会在表尾添加一个n,其值为表的元素数量。

注意:实际上n并不会被算作是一个元素。
如下,向tbl添加了三个元素后,#tbl=3tbl.n=3

Comment: 0,0:00:00.00,0:00:00.00,Default,,0,0,0,code line,tbl=_G.table.pack("aaa","vv","ccc")
Comment: 0,0:00:00.00,0:00:00.00,Default,,0,0,0,template line noblank notext,!maxloop(#tbl)! !#tbl!  !tbl[j]!  !tbl.n!
Comment: 0,0:00:00.00,0:00:05.00,Default,,0,0,70,karaoke,test
Dialogue: 0,0:00:00.00,0:00:05.00,Default,,0,0,70,fx, 3  aaa  3
Dialogue: 0,0:00:00.00,0:00:05.00,Default,,0,0,70,fx, 3  vv  3
Dialogue: 0,0:00:00.00,0:00:05.00,Default,,0,0,70,fx, 3  ccc  3

表拆解table.unpack

_G.table.unpack(table)是上文table.pack的逆向操作,可以把表中元素一起输出。因此传入参数为一个表。需要用元素个数个变量去存储传出参数。

tbl=_G.table.pack("aaa","vv","ccc")  
a,b,c=_G.table.unpack(tbl)
!a! !b! !c!

>

aaa vv ccc

注:如果传出变量数与表元素数量不一致也不会报错。多出来的接受值不会被赋值,依然为nil.

复制表_G.table.copy

_G.table.copy(table)该函数可以复制一模一样(但是不同地址)的表,传入参数为一个表,传出也是一个表。
两表独立,不互相作用。

表内容转文字_G.Yutils.table.tostring

_G.Yutils.table.tostring可以把表中的内容以文本形式传出。(此函数主要用于调试)

Comment: 0,0:00:00.00,0:00:00.00,Default,,0,0,0,code line,tab={a="tet",b="foo",aa="11"}
Comment: 0,0:00:00.00,0:00:00.00,Default,,0,0,0,template line noblank,!_G.Yutils.table.tostring(tab)!
Comment: 0,0:00:00.00,0:00:05.00,Default,,0,0,0,karaoke,
Dialogue: 0,0:00:00.00,0:00:05.00,Default,,0,0,0,fx,["b"] = "foo"["a"] = "tet"["aa"] = "11"

image.png

生成闪电图形

function Lighting(x1,y1,x2,y2,displace,curDetail,thickness_min,thickness_max)
    pos_table = {} 
    pos_table_temp = {} 
    shape_table = {} 
    shape_table_reverse = {} 
    local function drawLightning(x1,y1,x2,y2,displace) 
        if (displace<curDetail) then 
            pos_table[#pos_table+1] = {x1,y1,x2,y2} 
        else 
            local mid_x = (x1+x2)/2 
            local mid_y = (y1+y2)/2 
            mid_x = mid_x + (math.random(0,1)-0.5) * displace 
            mid_y = mid_y + (math.random(0,1)-0.5) * displace 
            drawLightning(x1,y1,mid_x,mid_y,displace/2) 
            drawLightning(mid_x,mid_y,x2,y2,displace/2) 
        end 
    end 
    do drawLightning(x1,y1,x2,y2,displace) 
    end 
    for var=1,#pos_table do 
        shape_table[var] = _G.table.concat(pos_table[var]," ",3,4) 
        pos_table_temp[var] = {} 
        pos_table_temp[var][3] = pos_table[var][3] 
        pos_table_temp[var][4] = pos_table[var][4]+math.random(thickness_min,thickness_max) 
        shape_table_reverse[#pos_table-var+1] = _G.table.concat(pos_table_temp[var]," ",3,4) 
    end 
    return string.format("m %d %d l ",x1,y1).._G.table.concat(shape_table," ").." ".._G.table.concat(shape_table_reverse," ") 
end

来自文森特的分享[5],函数来自haiyang.
共8个参数。前两个为闪电绘图的起始坐标(绘图坐标系,非屏幕坐标系),3、4两个为绘图的终点坐标。第五个参数为设定闪电绘图的最大位移值,与曲折程度相关。第六个为最小切割值(即单条线段的长度)。最后两个参数设定闪电绘图的粗细范围,例如2,6为粗细范围在2~6之间。

image.png

参考

  1. ^https://www.bilibili.com/video/BV1zE411Z7wJ
  2. ^https://ihkk.net/lua-pattern-and-regular-regex/
  3. ^https://www.bilibili.com/video/BV1i7411M7eJ
  4. ^https://www.runoob.com/lua/lua-strings.html
  5. ^https://www.bilibili.com/video/BV1TE411s7mP
标题:Aegisub 自动化 笔记
作者:IKK
除转载和特殊声明外,所有文章采用 CC BY-NC-SA 4.0协议
上一篇
下一篇