mirror of https://github.com/odrling/Aegisub
add automation scripts back
This commit is contained in:
parent
5f14861a43
commit
6a890430be
|
@ -0,0 +1,46 @@
|
|||
local tr = aegisub.gettext
|
||||
|
||||
script_name = tr"Clean k tags"
|
||||
script_description = tr"Remove double k tags"
|
||||
script_author = "amoethyst"
|
||||
script_version = "1.0"
|
||||
|
||||
local double_k = "^(.-{\\k[^}]-)(\\k.+)$"
|
||||
-- if the first tag is K/kf this would break the timing for the previous timing
|
||||
local expr = "^(.-){\\(ko?)([0-9.]+)[^}]-}([^{]-){\\[kK][fo]?([0-9.]+)[^}]-}( -{(\\[kK][fo]?)[0-9.]+[^}]-}.*)$"
|
||||
|
||||
|
||||
function _special_k(subs, i)
|
||||
line = subs[i]
|
||||
|
||||
before, after = line.text:match(double_k)
|
||||
while after ~= nil do
|
||||
line.text = before .. "}{" .. after
|
||||
before, after = line.text:match(double_k)
|
||||
end
|
||||
|
||||
before, tag, k1, between, k2, after = line.text:match(expr)
|
||||
while after ~= nil do
|
||||
line.text = before .. "{\\" .. tag .. tonumber(k1) + tonumber(k2) .. "}" .. between .. after
|
||||
before, tag, k1, between, k2, after = line.text:match(expr)
|
||||
end
|
||||
|
||||
return line
|
||||
end
|
||||
|
||||
|
||||
function special_k(subs, sel)
|
||||
|
||||
for _, i in ipairs(sel) do
|
||||
ok, res = pcall(_special_k, subs, i)
|
||||
if ok then
|
||||
subs[i] = res
|
||||
else
|
||||
aegisub.log("error on line " .. i .. ": " .. line.text .. "\n")
|
||||
aegisub.log(res .. "\n")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
aegisub.register_macro(script_name, script_description, special_k)
|
|
@ -0,0 +1,26 @@
|
|||
local tr = aegisub.gettext
|
||||
|
||||
script_name = tr"driftfix"
|
||||
script_description = tr"shift drifting lines"
|
||||
script_author = "amoethyst"
|
||||
script_version = "1.0"
|
||||
|
||||
|
||||
function split_line(subs, sel)
|
||||
local step = -200 -- drift step in milliseconds
|
||||
local drift = step
|
||||
|
||||
for _, i in ipairs(sel) do
|
||||
line = subs[i]
|
||||
|
||||
line.start_time = line.start_time + drift
|
||||
line.end_time = line.end_time + drift
|
||||
drift = drift + step
|
||||
|
||||
subs[i] = line
|
||||
end
|
||||
|
||||
aegisub.set_undo_point(script_name)
|
||||
end
|
||||
|
||||
aegisub.register_macro(script_name, script_description, split_line)
|
|
@ -0,0 +1,175 @@
|
|||
local tr = aegisub.gettext
|
||||
|
||||
script_name = tr"Duetto Meika"
|
||||
script_description = tr"The ultimate tool for karaoke duets"
|
||||
script_author = "amoethyst"
|
||||
|
||||
include("utils.lua")
|
||||
|
||||
|
||||
function replace_style(line, style_name, style_string)
|
||||
before_style, after_style = line.text:match("^(.-{[^}]-)\\?s:".. style_name .."(.*)$")
|
||||
return before_style .. style_string .. after_style
|
||||
end
|
||||
|
||||
|
||||
function duetto(subs, sel)
|
||||
styles = {}
|
||||
|
||||
-- create the style map
|
||||
for _, line in ipairs(subs) do
|
||||
if line.class == "style" then
|
||||
styles[line.name] = line
|
||||
end
|
||||
end
|
||||
|
||||
-- duetto~
|
||||
for _, i in ipairs(sel) do
|
||||
line = subs[i]
|
||||
|
||||
current_style = styles[line.style]
|
||||
-- match every `s:` marker
|
||||
for style_name in line.text:gmatch("{[^}]*s:([^}\\]*)[^}]*}") do
|
||||
if style_name ~= current_style.name then
|
||||
|
||||
style = styles[style_name]
|
||||
-- build the tags to use the new style
|
||||
style_string = ""
|
||||
if current_style.color1 ~= style.color1 then
|
||||
style_string = style_string .. "\\c" .. style.color1
|
||||
end
|
||||
if current_style.color2 ~= style.color2 then
|
||||
style_string = style_string .. "\\2c" .. style.color2
|
||||
end
|
||||
if current_style.color3 ~= style.color3 then
|
||||
style_string = style_string .. "\\3c" .. style.color3
|
||||
end
|
||||
if current_style.color4 ~= style.color4 then
|
||||
style_string = style_string .. "\\4c" .. style.color4
|
||||
end
|
||||
|
||||
-- set style
|
||||
line.text = replace_style(line, style_name, style_string)
|
||||
current_style = style
|
||||
else
|
||||
-- remove marker to not break everything
|
||||
line.text = replace_style(line, style_name, "")
|
||||
end
|
||||
end
|
||||
subs[i] = line
|
||||
end
|
||||
|
||||
aegisub.set_undo_point(script_name)
|
||||
end
|
||||
|
||||
|
||||
function test_colors(c1, c2)
|
||||
return color_from_style(c1) == color_from_style(c2)
|
||||
end
|
||||
|
||||
|
||||
function get_script_style(style, styles)
|
||||
for key, script_style in pairs(styles) do
|
||||
if (test_colors(style.color1, script_style.color1)
|
||||
and test_colors(style.color2, script_style.color2)
|
||||
and test_colors(style.color3, script_style.color3)
|
||||
and test_colors(style.color4, script_style.color4)
|
||||
and tonumber(style.fontsize) == tonumber(script_style.fontsize)
|
||||
and style.fontname == script_style.fontname) then
|
||||
return script_style
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
function deduetto_meika(subs, sel)
|
||||
local styles = {}
|
||||
local last_style = -1
|
||||
|
||||
-- create the style map
|
||||
for i, line in ipairs(subs) do
|
||||
if line.class == "style" then
|
||||
styles[line.name] = line
|
||||
last_style = i
|
||||
end
|
||||
end
|
||||
|
||||
local new_styles = {}
|
||||
|
||||
for _, i in ipairs(sel) do
|
||||
local line = subs[i]
|
||||
local current_style = table.copy(styles[line.style])
|
||||
|
||||
local search_index = 1
|
||||
while search_index < #line.text do
|
||||
local match_start, match_end = line.text:find("{[^}]*}", search_index)
|
||||
if match_start == nil then
|
||||
break
|
||||
end
|
||||
|
||||
local bracketed = line.text:sub(match_start, match_end)
|
||||
local new_style = false
|
||||
|
||||
-- change style's colors
|
||||
for tag, value in bracketed:gmatch("\\([1-4]?c)([^}\\]*)") do
|
||||
new_style = true
|
||||
if tag == "c" or tag == "1c" then
|
||||
current_style.color1 = value
|
||||
elseif tag == "2c" then
|
||||
current_style.color2 = value
|
||||
elseif tag == "3c" then
|
||||
current_style.color3 = value
|
||||
elseif tag == "4c" then
|
||||
current_style.color4 = value
|
||||
end
|
||||
end
|
||||
|
||||
-- change style's font
|
||||
for tag, value in bracketed:gmatch("\\(f[sn])([^}\\]*)") do
|
||||
new_style = true
|
||||
if tag == "fs" then
|
||||
current_style.fontsize = value
|
||||
elseif tag == "fn" then
|
||||
current_style.fontname = value
|
||||
end
|
||||
end
|
||||
|
||||
if new_style then
|
||||
local script_style = get_script_style(current_style, styles)
|
||||
if script_style == nil then
|
||||
if get_script_style(current_style, new_styles) == nil then
|
||||
new_styles[#new_styles+1] = table.copy(current_style)
|
||||
end
|
||||
else
|
||||
-- remove inline colors
|
||||
bracketed = bracketed:gsub("\\[1-4]?c[^\\}]*", "")
|
||||
bracketed = bracketed:gsub("\\[1-4]?a[^\\}]*", "")
|
||||
-- remove inline fonts
|
||||
bracketed = bracketed:gsub("\\f[sn][^\\}]*", "")
|
||||
|
||||
-- add style marker
|
||||
bracketed = "{s:" .. script_style.name .. bracketed:sub(2, #bracketed)
|
||||
line.text = line.text:sub(1, match_start-1) .. bracketed .. line.text:sub(match_end + 1, #line.text)
|
||||
end
|
||||
end
|
||||
|
||||
search_index = match_start + 1
|
||||
end
|
||||
|
||||
subs[i] = line
|
||||
end
|
||||
|
||||
if #new_styles > 0 then
|
||||
for i, new_style in ipairs(new_styles) do
|
||||
new_style.name = "Deduetto style " .. i
|
||||
subs.insert(last_style, new_style)
|
||||
last_style = last_style + 1
|
||||
aegisub.log("Created new style: " .. new_style.name .. "\n")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
aegisub.register_macro(script_name, script_description, duetto)
|
||||
aegisub.register_macro(tr"Deduetto Meika", tr"Create styles from inline color tags", deduetto_meika)
|
|
@ -0,0 +1,176 @@
|
|||
local tr = aegisub.gettext
|
||||
|
||||
script_name = tr"Karaoke 1sec adjust lead-in"
|
||||
script_description = tr"Adjust karaoke leadin to 1sec"
|
||||
script_author = "Flore"
|
||||
script_version = "1.00"
|
||||
|
||||
include("cleantags.lua")
|
||||
|
||||
leadinmsec = 1000 --lead in time can be changed here
|
||||
|
||||
ktag = "\\[kK][fo]?%d+" --pattern used to detect karaoke tags
|
||||
|
||||
-- KM template line definition
|
||||
km_template_effect = "template pre-line all keeptags"
|
||||
km_template_text = '!retime("line",$start < 900 and -$start or -900,200)!{!$start < 900 and "\\\\k" .. ($start/10) or "\\\\k90"!\\fad(!$start < 900 and $start or 300!,200)}'
|
||||
|
||||
function hasleadin(line)--check if there is an existing lead in (2 consecutive bracket with karaoke tags at the start of the line)
|
||||
return line.text:find("^{[^{}]-" .. ktag .. "[^{}]-}%s*{[^{}]-" .. ktag .. "[^{}]-}")
|
||||
end
|
||||
|
||||
|
||||
function removeleadin(line)
|
||||
if not hasleadin(line) then
|
||||
return line
|
||||
end
|
||||
|
||||
leadin = tonumber( line.text:match("^{[^{}]-\\[kK][fo]?(%d+)[^{}]-}%s*{[^{}]-" .. ktag .. "[^{}]-}") ) --read lead-in value
|
||||
line.text = line.text:gsub("^({[^{}]-)\\[kK][fo]?%d+(.-}%s*{[^{}]-" .. ktag .. ".-})","%1%2") --remove lead in
|
||||
|
||||
line.text = cleantags(line.text) --clean tags
|
||||
|
||||
line.start_time = line.start_time + leadin*10 --adjust start time
|
||||
|
||||
--aegisub.log(line.text)
|
||||
|
||||
return line
|
||||
end
|
||||
|
||||
|
||||
function adjust_1sec(subs, sel)
|
||||
|
||||
for _, i in ipairs(sel) do
|
||||
local line = subs[i]
|
||||
|
||||
line.text = cleantags(line.text)
|
||||
|
||||
if( line.text:find(ktag)) then--don't do anything if there is no ktags in this line
|
||||
|
||||
--start by removing existing lead-in
|
||||
while hasleadin(line) do
|
||||
if aegisub.progress.is_cancelled() then return end
|
||||
line = removeleadin(line)
|
||||
end
|
||||
|
||||
--then add our lead in
|
||||
|
||||
if line.start_time >= leadinmsec then
|
||||
line.text = string.format("{\\k%d}%s",leadinmsec/10, line.text)
|
||||
line.start_time = line.start_time - leadinmsec
|
||||
|
||||
else --if line starts too early to put the needed lead in, make the line start at time 0 and fill with appropriate lead in
|
||||
line.text = string.format("{\\k%d}%s",line.start_time/10, line.text)
|
||||
line.start_time = 0
|
||||
end
|
||||
|
||||
subs[i] = line
|
||||
end
|
||||
end
|
||||
|
||||
aegisub.set_undo_point(tr"1sec adjust lead-in")
|
||||
end
|
||||
|
||||
|
||||
function remove_tag(line, tag)
|
||||
local expr = "^(.-{[^}]*)\\" .. tag .. "[^\\}]*(.*)"
|
||||
while true do
|
||||
before, after = line.text:match(expr)
|
||||
if before == nil then
|
||||
return line
|
||||
else
|
||||
line.text = cleantags(before .. after)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function is_template_line(line)
|
||||
return (line.class == "dialogue"
|
||||
and line.effect == km_template_effect
|
||||
and line.text == km_template_text)
|
||||
end
|
||||
|
||||
|
||||
function mugenizer(subs)
|
||||
local first = nil
|
||||
local styles_different = false
|
||||
local styles = 0
|
||||
local i_styles = {}
|
||||
local template_present = false
|
||||
|
||||
for i, line in ipairs(subs) do
|
||||
if line.class == "info" then
|
||||
if line.key == "PlayResX" or line.key == "PlayResY" then
|
||||
line.value = "0"
|
||||
end
|
||||
if line.key == "ScaledBorderAndShadow" then
|
||||
line.value = "yes"
|
||||
end
|
||||
end
|
||||
|
||||
if line.class == "style" then
|
||||
line.fontname = "Arial"
|
||||
line.fontsize = "24"
|
||||
line.outline = "1.5"
|
||||
line.shadow = "0"
|
||||
line.margin_l = "15"
|
||||
line.margin_r = "15"
|
||||
line.margin_t = "20"
|
||||
line.margin_b = "20"
|
||||
|
||||
i_styles[styles] = i
|
||||
if styles > 0 then
|
||||
styles_different = styles_different or line.color1 ~= subs[i_styles[styles-1]].color1 or line.color2 ~= subs[i_styles[styles-1]].color2 or line.color3 ~= subs[i_styles[styles-1]].color3 or line.color4 ~= subs[i_styles[styles-1]].color4
|
||||
end
|
||||
styles = styles + 1
|
||||
end
|
||||
|
||||
if is_template_line(line) then
|
||||
line.comment = true
|
||||
template_present = true
|
||||
end
|
||||
|
||||
if line.class == "dialogue" and not line.comment and line.effect ~= "fx" then
|
||||
if first == nil then
|
||||
first = i
|
||||
end
|
||||
|
||||
line.text = cleantags(line.text)
|
||||
|
||||
while hasleadin(line) do
|
||||
if aegisub.progress.is_cancelled() then return end
|
||||
line = removeleadin(line)
|
||||
end
|
||||
|
||||
line = remove_tag(line, "fad")
|
||||
end
|
||||
|
||||
subs[i] = line
|
||||
end
|
||||
|
||||
if not styles_different then
|
||||
for i = 0, styles-1, 1 do
|
||||
line = subs[i_styles[i]]
|
||||
line.color1 = "&H008AFF"
|
||||
line.color2 = "&HFFFFFF"
|
||||
line.color3 = "&H000000"
|
||||
line.color4 = "&H000000"
|
||||
subs[i_styles[i]] = line
|
||||
end
|
||||
end
|
||||
|
||||
if not template_present then
|
||||
-- add mugen's magic line
|
||||
line = subs[first]
|
||||
line.comment = true
|
||||
line.start_time = 0
|
||||
line.end_time = 0
|
||||
line.effect = km_template_effect
|
||||
line.text = km_template_text
|
||||
subs.insert(first, line)
|
||||
end
|
||||
end
|
||||
|
||||
aegisub.register_macro(script_name, script_description, adjust_1sec)
|
||||
aegisub.register_macro(tr"Mugenizer", tr"Mugenize your subs", mugenizer)
|
|
@ -0,0 +1,48 @@
|
|||
local tr = aegisub.gettext
|
||||
|
||||
script_name = tr"Split karaoke line"
|
||||
script_description = tr"Split line at {split} marker according to ktags"
|
||||
script_author = "amoethyst"
|
||||
script_version = "1.0"
|
||||
|
||||
function split_line(subs, sel)
|
||||
|
||||
function getduration(line)
|
||||
d = 0
|
||||
|
||||
kduration = "{[^}]-\\[kK][fo]?(%d+)[^}]-}"
|
||||
for match in line:gmatch(kduration) do
|
||||
d = d + tonumber(match)
|
||||
end
|
||||
|
||||
return d * 10
|
||||
end
|
||||
|
||||
insertions = 0
|
||||
for _, i in ipairs(sel) do
|
||||
i = i + insertions
|
||||
line1 = subs[i]
|
||||
line2 = subs[i]
|
||||
|
||||
split_expr = "(.-)%s*{split}%s*(.*)"
|
||||
line1.text, line2.text = line1.text:match(split_expr)
|
||||
|
||||
while line1.text ~= nil do
|
||||
line1.end_time = line1.start_time + getduration(line1.text)
|
||||
line2.start_time = line1.end_time
|
||||
|
||||
subs[i] = line1
|
||||
i = i + 1
|
||||
insertions = insertions + 1
|
||||
subs.insert(i, line2)
|
||||
line1 = subs[i]
|
||||
|
||||
line1.text, line2.text = line1.text:match(split_expr)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
aegisub.set_undo_point(tr"Karaoke split")
|
||||
end
|
||||
|
||||
aegisub.register_macro(script_name, script_description, split_line)
|
|
@ -0,0 +1,39 @@
|
|||
local tr = aegisub.gettext
|
||||
|
||||
script_name = tr"kf"
|
||||
script_description = tr"add kf tag for 'long' syllables"
|
||||
script_author = "amoethyst"
|
||||
script_version = "1.0"
|
||||
|
||||
|
||||
function split_line(subs, sel)
|
||||
local expr_k = "(.-{[^}]*\\)[kK][of]?(%d+)([^{]*)"
|
||||
local before, after, dur, text
|
||||
|
||||
for _, i in ipairs(sel) do
|
||||
line = subs[i]
|
||||
|
||||
-- replace k tags
|
||||
text = ""
|
||||
for before, dur, after in line.text:gmatch(expr_k) do
|
||||
if before == nil then
|
||||
break
|
||||
else
|
||||
if tonumber(dur) >= 90 then
|
||||
text = text .. before .. "kf" .. dur .. after
|
||||
else
|
||||
text = text .. before .. "k" .. dur .. after
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if text ~= "" then
|
||||
line.text = text
|
||||
subs[i] = line
|
||||
end
|
||||
end
|
||||
|
||||
aegisub.set_undo_point(script_name)
|
||||
end
|
||||
|
||||
aegisub.register_macro(script_name, script_description, split_line)
|
|
@ -0,0 +1,43 @@
|
|||
local tr = aegisub.gettext
|
||||
|
||||
script_name = tr"unkf"
|
||||
script_description = tr"replace kf/ko tags in selected lines by regular k tags"
|
||||
script_author = "amoethyst"
|
||||
script_version = "1.0"
|
||||
|
||||
|
||||
function split_line(subs, sel)
|
||||
local expr_kof = "^(.-{[^}]*\\k)[of](.*)$"
|
||||
local expr_K = "^(.-{[^}]*\\)K(.*)$"
|
||||
local before, after
|
||||
|
||||
for _, i in ipairs(sel) do
|
||||
line = subs[i]
|
||||
|
||||
-- replace ko and kf tags
|
||||
while true do
|
||||
before, after = line.text:match(expr_kof)
|
||||
if before == nil then
|
||||
break
|
||||
else
|
||||
line.text = before .. after
|
||||
end
|
||||
end
|
||||
|
||||
-- replace K tags
|
||||
while true do
|
||||
before, after = line.text:match(expr_K)
|
||||
if before == nil then
|
||||
break
|
||||
else
|
||||
line.text = before .. "k" .. after
|
||||
end
|
||||
end
|
||||
|
||||
subs[i] = line
|
||||
end
|
||||
|
||||
aegisub.set_undo_point(script_name)
|
||||
end
|
||||
|
||||
aegisub.register_macro(script_name, script_description, split_line)
|
|
@ -0,0 +1,55 @@
|
|||
local tr = aegisub.gettext
|
||||
|
||||
script_name = tr"Nihongo wa muzukashii"
|
||||
script_description = tr"Turn your \"o e\"s into \"wo he\"s"
|
||||
script_author = "amoethyst"
|
||||
script_version = "1.0"
|
||||
|
||||
function wohe(subs, sel)
|
||||
|
||||
-- "Unfortunately Lua patterns do not support this, only single characters can be repeated or chosen between, not sub-patterns or strings"
|
||||
-- well, fuck
|
||||
local exprs = {
|
||||
"^(.* {[^}]*})([oe])({[^}]*} .*)$",
|
||||
"^(.* )([oe])({[^}]*} .*)$",
|
||||
"^(.* {[^}]*})([oe])( .*)$",
|
||||
"^(.* )([oe])( .*)$",
|
||||
"^()([oe])( .*)$",
|
||||
}
|
||||
|
||||
for _, i in ipairs(sel) do
|
||||
line = subs[i]
|
||||
line.text = line.text .. " "
|
||||
|
||||
for _, expr in ipairs(exprs) do
|
||||
local before, o_or_e, after = line.text:match(expr)
|
||||
while o_or_e ~= nil do
|
||||
line.text = ""
|
||||
|
||||
if before ~= nil then
|
||||
line.text = before
|
||||
end
|
||||
|
||||
if o_or_e == "o" then
|
||||
line.text = line.text .. "wo"
|
||||
else
|
||||
line.text = line.text .. "he"
|
||||
end
|
||||
|
||||
if after ~= nil then
|
||||
line.text = line.text .. after
|
||||
end
|
||||
|
||||
before, o_or_e, after = line.text:match(expr)
|
||||
end
|
||||
end
|
||||
|
||||
line.text = line.text:gsub(" $", "")
|
||||
|
||||
subs[i] = line
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
aegisub.register_macro(script_name, script_description, wohe)
|
Loading…
Reference in New Issue