-
Notifications
You must be signed in to change notification settings - Fork 45
/
ua.TimeSigns.lua
185 lines (170 loc) · 6.66 KB
/
ua.TimeSigns.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
-- Times a sign with {TS 3:24} to 3:24-3:25. Can convert and use a few other formats, like {3:24}, {TS,3:24}, {3,24}, etc.
-- supported timecodes: {TS 1:23}, {TS 1:23 words}, {TS words 1:23}, {TS,1:23}, {1:23}, {1;23}, {1,23}, {1.23}, [1:23], and variations
-- Manual: http://unanimated.xtreemhost.com/ts/scripts-manuals.htm#timesigns
script_name="Time Signs"
script_description="Rough-times signs from TS timecodes"
script_author="unanimated"
script_version="2.8"
script_namespace="ua.TimeSigns"
local haveDepCtrl,DependencyControl,depRec=pcall(require,"l0.DependencyControl")
if haveDepCtrl then
script_version="2.8.0"
depRec=DependencyControl{feed="https://raw.githubusercontent.com/TypesettingTools/unanimated-Aegisub-Scripts/master/DependencyControl.json"}
end
function signtime(subs,sel)
for z=#sel,1,-1 do
i=sel[z]
line=subs[i]
text=line.text
-- format timecodes
text=text
:gsub("({.-})({TS.-})","%2%1")
:gsub("(%d+):(%d%d):(%d%d)",
function(a,b,c) return a*60+b..":"..c end) -- hours
:gsub("^(%d%d%d%d)%s%s*","{TS %1}") -- ^1234 text
:gsub("(%d%d)ish","%1") -- 1:23ish
:gsub("^([%d%s:,%-]+)","{%1}") -- ^1:23, 2:34, 4:56
:gsub("^(%d+:%d%d)%s%-%s","{TS %1}") -- ^12?:34 -
:gsub("^(%d+:%d%d%s*)","{TS %1}") -- ^12?:34
:gsub("^{(%d+:%d%d)","{TS %1") -- ^{12?:34
:gsub("^%[(%d+:%d%d)%]:?%s*","{TS %1}") -- ^[12?:34]:?
:gsub("{TS[%s%p]+(%d)","{TS %1") -- {TS ~12:34
:gsub("({[^}]-)(%d+)[%;%.,]?(%d%d)([^:%d][^}]-})","%1%2:%3%4") -- {1;23 / 1.23 / 1,23 123}
:gsub("{TS%s([^%d\\}]+)%s(%d+:%d%d)","{TS %2 %1") -- {TS comment 12:34}
:gsub(":%s?}","}") -- {TS 12:34: }
:gsub("|","\\N")
tc=text:match("^{[^}]-}") or ""
tc=tc:gsub("(%d+)(%d%d)([^:])","%1:%2%3")
text=text:gsub("^{[^}]-}%s*",tc)
if res.blur then text=text:gsub("\\blur[%d%.]+",""):gsub("{}",""):gsub("^","{\\blur"..res.bl.."}") end
line.text=text
tstags=text:match("{TS[^}]-}") or ""
times={} -- collect times if there are more
for tag in tstags:gmatch("%d+:%d+") do table.insert(times,tag) end
for t=#times,1,-1 do
tim=times[t]
-- convert to start time
tstid1,tstid2=tim:match("(%d+):(%d%d)")
if tstid1 then tid=(tstid1*60000+tstid2*1000-500) end
-- shifting times
if tid then
if res.shift then tid=tid+res.secs*1000 end
-- set start and end time [500ms before and after the timecode]
line.start_time=tid line.end_time=(tid+1000)
end
-- snapping to keyframes
if res.snap then
start=line.start_time
endt=line.end_time
startf=ms2fr(start)
endf=ms2fr(endt)
diff=250
diffe=250
startkf=keyframes[1]
endkf=keyframes[#keyframes]
-- check for nearby keyframes
for k,kf in ipairs(keyframes) do
-- startframe snap up to 24 frames back [scroll down to change default] and 5 frames forward
if kf>=startf-res.kfs and kf<startf+5 then
tdiff=math.abs(startf-kf)
if tdiff<=diff then diff=tdiff startkf=kf end
start=fr2ms(startkf)
line.start_time=start
end
-- endframe snap up to 24 frames forward [scroll down to change default] and 10 frames back
if kf>=endf-10 and kf<=endf+res.kfe then
tdiff=math.abs(endf-kf)
if tdiff<diffe then diffe=tdiff endkf=kf end
endt=fr2ms(endkf)
line.end_time=endt
end
end
end
line.text=line.text:gsub("{TS[^}]-}","{TS "..tim.."}")
if res.nots then line.text=line.text:gsub("{TS[^}]-}",""):gsub("{(\\[^}]-)}{(\\[^}]-)}","{%1%2}"):gsub("^({[^}]-})%s*","%1") end
subs.insert(i+1,line)
if t>1 then table.insert(sel,sel[#sel]+1) end
end
if #times>0 then subs.delete(i) end
end
if res.copy then taim=0 tame=0
for z,i in ipairs(sel) do
l=subs[i]
if l.start_time==0 then l.start_time=taim l.end_time=tame end
taim=l.start_time
tame=l.end_time
subs[i]=l
end
end
return sel
end
-- Config Stuff --
function saveconfig()
savecfg="Time Signs Settings\n\n"
for key,val in ipairs(GUI) do
if val.class=="floatedit" or val.class=="intedit" or val.class=="checkbox" and val.name~="save" then
savecfg=savecfg..val.name..":"..tf(res[val.name]).."\n"
end
end
file=io.open(cfgpath,"w")
file:write(savecfg)
file:close()
ADD({{class="label",label="Config saved to:\n"..cfgpath}},{"OK"},{close='OK'})
end
function loadconfig()
cfgpath=aegisub.decode_path("?user").."\\timesigns.conf"
file=io.open(cfgpath)
if file~=nil then
konf=file:read("*all")
file:close()
for key,val in ipairs(GUI) do
if val.class=="floatedit" or val.class=="checkbox" or val.class=="intedit" then
if konf:match(val.name) then val.value=detf(konf:match(val.name..":(.-)\n")) end
end
end
end
end
function tf(val)
if val==true then ret="true"
elseif val==false then ret="false"
else ret=val end
return ret
end
function detf(txt)
if txt=="true" then ret=true
elseif txt=="false" then ret=false
else ret=txt end
return ret
end
function timesigns(subs,sel)
ADD=aegisub.dialog.display
GUI={
{x=0,y=0,width=4,class="label",label="Check this if all your timecodes are too late or early:"},
{x=0,y=1,class="checkbox",name="shift",label="Shift timecodes by "},
{x=1,y=1,width=2,class="floatedit",name="secs",value=-10,hint="Negative=backward / positive=forward",step=0.5},
{x=3,y=1,class="label",label=" sec."},
{x=0,y=2,width=4,class="checkbox",name="copy",label="For lines without timecodes, copy from the previous line"},
{x=0,y=3,width=4,class="checkbox",name="nots",label="Automatically remove {TS ...} comments"},
{x=0,y=4,width=2,class="checkbox",name="blur",label="Automatically add blur:"},
{x=2,y=4,width=2,class="floatedit",name="bl",value="0.6"},
{x=0,y=5,width=2,class="checkbox",name="snap",label="Snapping to keyframes:",value=true},
{x=0,y=6,width=2,class="label",label="Frames to search back:"},
{x=0,y=7,width=2,class="label",label="Frames to search forward:"},
{x=2,y=6,width=2,class="intedit",name="kfs",value="24",step=1,min=1,max=250},
{x=2,y=7,width=2,class="intedit",name="kfe",value="24",step=1,min=1,max=250},
{x=0,y=8,width=2,class="checkbox",name="save",label="Save current settings"},
{x=2,y=8,width=2,class="label",label=" [Time Signs v"..script_version.."]"},
}
loadconfig()
buttons={"No more suffering with SHAFT signs!","Exit"}
P,res=ADD(GUI,buttons,{ok='No more suffering with SHAFT signs!',cancel='Exit'})
if P=="Exit" then aegisub.cancel() end
ms2fr=aegisub.frame_from_ms
fr2ms=aegisub.ms_from_frame
keyframes=aegisub.keyframes()
if res.save then saveconfig() end
if P=="No more suffering with SHAFT signs!" then sel=signtime(subs,sel) end
aegisub.set_undo_point(script_name)
return sel
end
if haveDepCtrl then depRec:registerMacro(timesigns) else aegisub.register_macro(script_name,script_description,timesigns) end