From a3a3a294370c2ff1d15b45745ace2f6c761194ae Mon Sep 17 00:00:00 2001 From: Niels Martin Hansen Date: Mon, 17 Sep 2007 11:03:20 +0000 Subject: [PATCH] ai-chan's cleantags version 1.150 Originally committed to SVN as r1561. --- automation/autoload/clean-tags.lua | 124 +++++++++-------------------- automation/include/cleantags.lua | 112 ++++++++++++++++++++++++++ 2 files changed, 151 insertions(+), 85 deletions(-) create mode 100644 automation/include/cleantags.lua diff --git a/automation/autoload/clean-tags.lua b/automation/autoload/clean-tags.lua index 910dab5c9..83aa55c47 100644 --- a/automation/autoload/clean-tags.lua +++ b/automation/autoload/clean-tags.lua @@ -1,107 +1,61 @@ +--[[ +"Clean Tags" -- An Auto4 LUA script for cleaning up ASS subtitle lines of badly-formed override +blocks and redundant/duplicate tags +* Designed to work for Aegisub 2.0 and above (only pre-release version was available at the time of +writing) @ http://www.malakith.net/aegiwiki +* Requires cleantags.lua to be available in automation's include folder +* The changes performed on your subtitles are guaranteed to be undo-able provided that Aegisub's undo +mechanism works. Even so, I am not resposible if it damages your subtitles permanently, so please +back up your subtitle file before applying the cleaning up + +Copyright (c) 2007 ai-chan (Aegisub's forum member and registered nick holder of Rizon irc network) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and +associated documentation files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, +sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT +NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES +OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +]] + script_name = "Clean Tags" script_description = "Clean subtitle lines by re-arranging ASS tags and override blocks within the lines" script_author = "ai-chan" -script_version = "1.000" -script_modified = "10 September 2007" +script_version = "1.150" +script_modified = "12 September 2007" -ktag = "\\[kK][fo]?%d+" +include("cleantags.lua") -function cleantags(subtitles) +function cleantags_subs(subtitles) local linescleaned = 0 for i = 1, #subtitles do aegisub.progress.set(i * 100 / #subtitles) - if subtitles[i].class == "dialogue" and subtitles[i].text then - local l = subtitles[i] - local t = l.text - - --[[ Combine adjacent override override blocks into one ]] - function combineadjacentnotks(block1, block2) - if string.find(block1, ktag) and string.find(block2, ktag) then - -- if both adjacent override blocks have \k , let them be - return "{" .. block1 .. "}" .. string.char(1) .. "{" .. block2 .. "}" -- char(1) prevents infinite loop - else - -- either one or both override blocks don't have \k , so combine them into one override block - return "{" .. block1 .. block2 .. "}" - end - end - repeat - if aegisub.progress.is_cancelled() then return end - t, replaced = string.gsub(t,"{(.-)}{(.-)}", combineadjacentnotks) - until replaced == 0 - t = string.gsub(t, string.char(1), "") -- removes all char(1) we inserted - - --[[ Move first \k tag in override blocks to the front ]] - t = string.gsub(t, "{([^{}]-)(" .. ktag .. ")(.-)}", "{%2%1%3}") - - --[[ For some reasons if one override block has more than one \k tag, push those to behind the first \k tag (which has been pushed to front already) ]] - repeat - if aegisub.progress.is_cancelled() then return end - t, replaced = string.gsub(t, "{([^{}]-)(" .. ktag .. ")(\\[^kK][^}]-)(" .. ktag .. ")(.-)}", "{%1%2%4%3%5}") - until replaced == 0 - - --[[ Move to the front all tags that affect the whole line (i.e. not affected by their positions in the line) ]] - local linetags = "" - function first(pattern) - local p_s, _, p_tag = string.find(t, pattern) - if p_s then - t = string.gsub(t, pattern, "") - linetags = linetags .. p_tag - end - end - function firstoftwo(pattern1, pattern2) - local p1_s, _, p1_tag = string.find(t, pattern1) - local p2_s, _, p2_tag = string.find(t, pattern2) - t = string.gsub(t, pattern1, "") - t = string.gsub(t, pattern2, "") - if p1_s and (not p2_s or p1_s < p2_s) then - linetags = linetags .. p1_tag - elseif p2_s then - linetags = linetags .. p2_tag - end - end - -- \an or \a - first("(\\an?%d+)") - -- \org - first("(\\org%([^,%)]*,[^,%)]*%))") - -- \move and \pos (the first one wins) - firstoftwo("(\\move%([^,%)]*,[^,%)]*,[^,%)]*,[^,%)]*%))", "(\\pos%([^,%)]*,[^,%)]*%))") - -- \fade and \fad (the first one wins) - firstoftwo("(\\fade%([^,%)]*,[^,%)]*,[^,%)]*,[^,%)]*,[^,%)]*,[^,%)]*,[^,%)]*%))", "(\\fad%([^,%)]*,[^,%)]*%))") - -- integrate - if string.len(linetags) > 0 then - if string.sub(t, 1, 1) == "{" then - t = "{" .. linetags .. string.sub(t, 2) - else - t = "{" .. linetags .. "}" .. t - end - end - - --[[ Remove any spaces within parenteses within override blocks ]] - repeat - if aegisub.progress.is_cancelled() then return end - t, replaced2 = string.gsub(t, "({[^}]*%([^%s%)}]*)%s+(.*%)[^}]*})", "%1%2") - until replaced2 == 0 - - --[[ Remove all empty override blocks ==> {} ]] - t = string.gsub(t, "{%s*}", "") - - --[[ Finally, update subtitle line with changes ]] - l.text = t - subtitles[i] = l + if subtitles[i].class == "dialogue" and subtitles[i].text ~= "" then + ntext = cleantags(subtitles[i].text) + local nline = subtitles[i] + nline.text = ntext + subtitles[i] = nline -- I don't understand why we need these steps to incorporate new text linescleaned = linescleaned + 1 aegisub.progress.task(linescleaned .. " lines cleaned") end end - end function cleantags_macro(subtitles, selected_lines, active_line) - cleantags(subtitles) + cleantags_subs(subtitles) aegisub.set_undo_point(script_name) end function cleantags_filter(subtitles, config) - cleantags(subtitles) + cleantags_subs(subtitles) end aegisub.register_macro(script_name, script_description, cleantags_macro) diff --git a/automation/include/cleantags.lua b/automation/include/cleantags.lua new file mode 100644 index 000000000..9b4d50945 --- /dev/null +++ b/automation/include/cleantags.lua @@ -0,0 +1,112 @@ +--[[ +"Clean Tags" -- An Auto4 LUA script for cleaning up ASS subtitle lines of badly-formed override +blocks and redundant/duplicate tags +* Designed to work for Aegisub 2.0 and above (only pre-release version was available at the time of +writing) @ http://www.malakith.net/aegiwiki +* include()'ed this file from any auto4 script to use the cleantags() function below +* Might change from time to time so look out for cleantags_version below + +Copyright (c) 2007 ai-chan (Aegisub's forum member and registered nick holder of Rizon irc network) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and +associated documentation files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, +sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT +NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES +OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +]] + +cleantags_version = "1.200" +cleantags_modified = "13 September 2007" + +ktag = "\\[kK][fo]?%d+" + +--[[ The main function that performs the cleaning up +Takes: text +Returns: cleaned up text +]] +function cleantags(text) + --[[ Combine adjacentext override override blocks into one ]] + function combineadjacentnotks(block1, block2) + if string.find(block1, ktag) and string.find(block2, ktag) then + -- if both adjacentext override blocks have \k , letext them be + return "{" .. block1 .. "}" .. string.char(1) .. "{" .. block2 .. "}" -- char(1) prevents infinite loop + else + -- either one or both override blocks don'text have \k , so combine them into one override block + return "{" .. block1 .. block2 .. "}" + end + end + repeat + if aegisub.progress.is_cancelled() then return end + text, replaced = string.gsub(text,"{(.-)}{(.-)}", combineadjacentnotks) + until replaced == 0 + text = string.gsub(text, string.char(1), "") -- removes all char(1) we inserted + + --[[ Move firstext \k tag in override blocks to the frontext ]] + text = string.gsub(text, "{([^{}]-)(" .. ktag .. ")(.-)}", "{%2%1%3}") + + --[[ For some reasons if one override block has more than one \k tag, + push those to behind the firstext \k tag (which has been pushed to frontext already) ]] + repeat + if aegisub.progress.is_cancelled() then return end + text, replaced = string.gsub(text, "{([^{}]-)(" .. ktag .. ")(\\[^kK][^}]-)(" .. ktag .. ")(.-)}", "{%1%2%4%3%5}") + until replaced == 0 + + --[[ Move to the frontext all tags thatext affectext the whole line (i.e. notext affected by their positions in the line) ]] + local linetags = "" + function first(pattern) + local p_s, _, p_tag = string.find(text, pattern) + if p_s then + text = string.gsub(text, pattern, "") + linetags = linetags .. p_tag + end + end + function firstoftwo(pattern1, pattern2) + local p1_s, _, p1_tag = string.find(text, pattern1) + local p2_s, _, p2_tag = string.find(text, pattern2) + text = string.gsub(text, pattern1, "") + text = string.gsub(text, pattern2, "") + if p1_s and (not p2_s or p1_s < p2_s) then + linetags = linetags .. p1_tag + elseif p2_s then + linetags = linetags .. p2_tag + end + end + -- \an or \a + first("(\\an?%d+)") + -- \org + first("(\\org%([^,%)]*,[^,%)]*%))") + -- \move and \pos (the firstext one wins) + firstoftwo("(\\move%([^,%)]*,[^,%)]*,[^,%)]*,[^,%)]*%))", "(\\pos%([^,%)]*,[^,%)]*%))") + -- \fade and \fad (the firstext one wins) + firstoftwo("(\\fade%([^,%)]*,[^,%)]*,[^,%)]*,[^,%)]*,[^,%)]*,[^,%)]*,[^,%)]*%))", "(\\fad%([^,%)]*,[^,%)]*%))") + -- integrate + if string.len(linetags) > 0 then + if string.sub(text, 1, 1) == "{" then + text = "{" .. linetags .. string.sub(text, 2) + else + text = "{" .. linetags .. "}" .. t + end + end + + --[[ Remove any spaces within parenteses within override blocks ]] + --[[ (removed in v 1.2) + repeat + if aegisub.progress.is_cancelled() then return end + text, replaced2 = string.gsub(text, "({[^}]*%([^%s%)}]*,)%s+(.*%)[^}]*})", "%1%2") + until replaced2 == 0 ]] + + --[[ Remove all empty override blocks ==> {} ]] + text = string.gsub(text, "{%s*}", "") + + --[[ Finally, return the cleaned up text ]] + return text +end