dotfiles/.aegisub/automation/autoload/lyger.KaraHelper.lua

176 lines
4.3 KiB
Lua

--[[
README
Karaoke Helper
Does simple karaoke tasks. Adds blank padding syllables to the beginning of lines,
and also adjusts final syllable so it matches the line length.
Will add more features as ktimers suggest them to me.
]]--
script_name = "Karaoke helper"
script_description = "Miscellaneous tools for assisting in karaoke timing."
script_version = "0.2.0"
script_author = "lyger"
script_namespace = "lyger.KaraHelper"
local DependencyControl = require("l0.DependencyControl")
local rec = DependencyControl{
feed = "https://raw.githubusercontent.com/TypesettingTools/lyger-Aegisub-Scripts/master/DependencyControl.json",
{
{"lyger.LibLyger", version = "2.0.0", url = "http://github.com/TypesettingTools/lyger-Aegisub-Scripts"},
}
}
local LibLyger = rec:requireModules()
local libLyger = LibLyger()
function make_config(styles)
local stopts={"selected lines"}
for i=1,styles.n,1 do
stopts[i+1] = ("style: %q").format(styles[i].name)
end
local config=
{
--What to apply the automation on
{
class="label",
label="Apply to:",
x=0,y=0,width=1,height=1
},
{
class="dropdown",
name="sselect",items=stopts,
x=1,y=0,width=1,height=1,
value="selected lines"
},
--Match syls to line length
{
class="checkbox",
name="match",label="Match syllable lengths to line length",
x=0,y=1,width=2,height=1,
value=true
},
--Add blank syl at the start
{
class="checkbox",
name="leadin",label="Add start padding:",
x=0,y=2,width=1,height=1,
value=false
},
{
class="intedit",
name="leadindur",
x=1,y=2,width=1,height=1,
min=0,
value=0
},
--Add blank syl at the end
{
class="checkbox",
name="leadout",label="Add end padding:",
x=0,y=3,width=1,height=1,
value=false
},
{
class="intedit",
name="leadoutdur",
x=1,y=3,width=1,height=1,
min=0,
value=0
}
}
return config
end
--Match syllable and line durations
function match_durs(line)
local ldur=line.end_time-line.start_time
local cum_sdur=0
for sdur in line.text:gmatch("\\[Kk][fo]?(%d+)") do
cum_sdur=cum_sdur+tonumber(sdur)
end
local delta=math.floor(ldur/10)-cum_sdur
line.text=line.text:gsub("({[^{}]*\\[Kk][fo]?)(%d+)([^{}]*}[^{}]*)$",
function(pre,val,post)
return ("%s%d%s"):format(pre, tonumber(val)+delta, post)
end)
return line
end
--Add padding at the start
function add_prepad(line,pdur)
line.text=line.text:gsub("^({[^{}]*\\[Kk][fo]?)(%d+)",
function(pre,val)
return ("{\\k%d}%s%d"):format(pdur, pre, tonumber(val)-pdur)
end)
line.text=line.text:gsub("^{\\k(%d+)}({[^{}]*\\[Kk][fo]?)(%-?%d+)([^{}]*}{)",
function(val1,mid,val2,post)
return ("%s%d%s"):format(mid, tonumber(val1)+tonumber(val2), post)
end)
return line
end
--Add padding at the end
function add_postpad(line,pdur)
line.text=line.text:gsub("(\\[Kk][fo]?)(%d+)([^{}]*}[^{}]*)$",
function(pre,val,post)
return ("%s%d%s{\\k%d}"):format(pre, tonumber(val)-pdur, post, pdur)
end)
line.text=line.text:gsub("(\\[Kk][fo]?)(%-?%d+)([^{}]*}){\\k(%d+)}$",
function(pre,val1,mid,val2)
return ("%s%d%s"):format(pre, tonumber(val1)+tonumber(val2), mid)
end)
return line
end
--Load config and display
function load_kh(sub,sel)
libLyger:set_sub(sub, sel)
-- Basic header collection, config, dialog display
local config = make_config(libLyger.styles)
local pressed,results=aegisub.dialog.display(config)
if pressed=="Cancel" then aegisub.cancel() end
--Determine how to retrieve the next line, based on the dropdown selection
local tstyle, line_cnt, get_next = results["sselect"], #sub
if tstyle:match("^style: ") then
tstyle=tstyle:match("^style: \"(.+)\"$")
get_next = function(uindex)
for i = uindex, line_cnt do
local line = libLyger.dialogue[uindex]
if line.style == tstyle and (not line.comment or line.effect == "karaoke") then
return line, i
end
end
end
else
get_next = function(uindex)
if uindex <= #sel then
return libLyger.lines[sel[uindex]], uindex+1
end
end
end
--Control loop
local line, uindex = get_next(1)
while line do
if results["match"] then match_durs(line) end
if results["leadin"] then add_prepad(line, results["leadindur"]) end
if results["leadout"] then add_postpad(line, results["leadoutdur"]) end
sub[line.i] = line
line, uindex = get_next(uindex)
end
aegisub.set_undo_point(script_name)
end
rec:registerMacro(load_kh)