mirror of
https://github.com/odrling/Aegisub
synced 2025-04-11 22:56:02 +02:00
1422 lines
47 KiB
Lua
1422 lines
47 KiB
Lua
script_name="Colourise"
|
|
script_description="RGB Magic and HSL Sorcery"
|
|
script_author="unanimated"
|
|
script_version="5.0"
|
|
script_namespace="ua.Colourise"
|
|
|
|
local haveDepCtrl,DependencyControl,depRec=pcall(require,"l0.DependencyControl")
|
|
if haveDepCtrl then
|
|
script_version="5.0.0"
|
|
depRec=DependencyControl{feed="https://raw.githubusercontent.com/unanimated/luaegisub/master/DependencyControl.json"}
|
|
end
|
|
|
|
info={}
|
|
info.colourise=[[
|
|
"Colourise letter by letter"
|
|
Alternates between 2-6 colours character by character, like 121212, or 123412341234.
|
|
Works for all colour types (one at a time), based on the 'Apply to' menu.
|
|
Handles inline tags and comments.
|
|
|
|
"Colourise by word"
|
|
Colourises by word instead of by letter.
|
|
|
|
"Bounce Back" will create a sequence like 123432123432 instead of 12341234.]]
|
|
info.shift=[[
|
|
"Shift"
|
|
Shift can be used on an already colourised line to shift the colours by one letter.
|
|
You have to set the right number of colours for it to work correctly.
|
|
You'll be shitfing the colour type in the 'Apply to' menu.
|
|
If "shift base" is "line", then it takes the colour for the first character from the last one.
|
|
This way it can shift colours no matter how few/many tags there are and where.
|
|
|
|
"Shift line by line"
|
|
If you select a bunch of the same colourised lines, this shifts the colours line by line.
|
|
First line is shifted by one letter, second one by two, etc.]]
|
|
info.tunecolours=[[
|
|
"Tune colours"
|
|
Loads all colours from a line into a GUI and lets you change them from there.
|
|
Useful for changing colours in transforms or just tuning lines with multiple colours.
|
|
|
|
"All selected" loads all 'unique' colours from all selected lines, rather than all from each line.
|
|
This is much more useful for tuning/replacing colours in a larger selection.
|
|
|
|
You can select "all/nontf/transf" to affect colours only from transforms, only those not from transforms, or all.]]
|
|
info.setcolours=[[
|
|
"Set colours across whole line"
|
|
This is like a preparation for a gradient by character.
|
|
Select number of colours, and choose the colours to be used.
|
|
For 3 colours, it will place one tag at the start, one in the middle, and one before the last character.
|
|
For 2 colours, it'll be the first and last characters.
|
|
Works for 2-10 colours and sets them evenly across the line.]]
|
|
info.gradient=[[
|
|
"Gradient"
|
|
Creates a gradient by character. (Uses Colourise button.)
|
|
There are two modes: RGB and HSL. RGB is the standard, like lyger's GBC;
|
|
HSL interpolates Hue, Saturation, and Lightness separately.
|
|
Use the \c, \3c, \4c, \2c checkboxes on the right to choose which colours to gradient.
|
|
|
|
"Short hue" makes sure that hue is interpolated in the shorter direction.
|
|
Unchecking it will give you a different gradient in 50% cases.
|
|
|
|
"Double HSL gradient" will make an extra round through Hue. Note that neither of these two options applies to RGB.
|
|
|
|
"Use asterisks" places asterisks like lyger's GBC so that you can ungradient the line with his script.
|
|
|
|
"Restart after each \N" will create the full gradient for each line if there are linebreaks.
|
|
|
|
The edit box below that is for acceleration. You can still type accel in Effect, the old way,
|
|
in the form: accel1.5, and this will override the GUI setting, ensuring you can have
|
|
different accel for different lines.
|
|
|
|
There are several differences from lyger's GBC:
|
|
- RGB / HSL option
|
|
- You can choose which types of colour you want to gradient
|
|
- Other tags don't interfere with the colour gradients
|
|
- You can use acceleration
|
|
|
|
The hotkeyable macros run with \c and \3c checked, and 'short hue' for HSL.]]
|
|
info.reverse=[[
|
|
"Reverse gradient"
|
|
On the right, select types of colours to apply this to.
|
|
For each colour type, colours from all tags in the line outside transforms are collected
|
|
and returned in the opposite direction.
|
|
A full gradient gets thus reversed.
|
|
(This is separate from the Gradient function, so no need to check that.)]]
|
|
info.match=[[
|
|
"Match Colours"
|
|
This should apply to all colour tags in the line.
|
|
|
|
c -> 3c: primary colour is copied to outline
|
|
3c -> c: outline colour is copied to primary
|
|
c -> 4c: primary colour is copied to shadow
|
|
3c -> 4c: outline colour is copied to shadow
|
|
c <-> 3c: primary and outline are switched
|
|
Invert: all colours are inverted (red->green, yellow->blue, black->white)]]
|
|
info.RGBHSL=[[
|
|
"Adjust RGB / HSL"
|
|
Adjusts Red/Green/Blue or Hue/Saturation/Lightness.
|
|
This works for lines with multiple same-type colour tags, including gradient by character.
|
|
You can select from -255 to 255.
|
|
Check types of colours you want it to apply to.
|
|
"Apply to missing" means it will be applied to the colour set in style if there's no tag in the line.
|
|
"Randomise" - if you set Lightness (or any RGB/HSL) to 20, the resulting colour will have anywhere between -20 and +20 of the original Lightness.]]
|
|
info.general=[[
|
|
"Remember last" - Remembers last settings of checkboxes and dropdown menus.
|
|
|
|
"Repeat last" - Repeat the function with last settings.
|
|
|
|
"Save config" - Saves a config file in your Application Data folder with current settings.
|
|
|
|
"Colourise" functions: if more selected, the one lowest in the GUI is run.
|
|
|
|
Full manual: http://unanimated.hostfree.pw/ts/scripts-manuals.htm#colourise
|
|
]]
|
|
|
|
re=require'aegisub.re'
|
|
|
|
function cuts(subs)
|
|
STAG="^{>?\\[^}]-}"
|
|
ATAG="{[*>]?\\[^}]-}"
|
|
COMM="{[^\\}]-}"
|
|
ACLR="&H%x+&"
|
|
ADD=aegisub.dialog.display
|
|
ADP=aegisub.decode_path
|
|
ak=aegisub.cancel
|
|
for i=1,#subs do if subs[i].class=="dialogue" then line0=i-1 break end end
|
|
end
|
|
|
|
function colourise(subs,sel)
|
|
cuts(subs)
|
|
validateCol(subs,sel)
|
|
GUI={
|
|
{x=0,y=0,class="label",label="Colours"},
|
|
{x=1,y=0,width=3,class="dropdown",name="clrs",items={"2","3","4","5","6","7"},value="2",hint="number of colours for\n'colourise letter by letter'"},
|
|
|
|
{x=0,y=1,class="label",label="Apply to: "},
|
|
{x=1,y=1,width=3,class="dropdown",name="kol",items={"\\c","\\3c","\\4c","\\2c"},value="\\c",hint="relevant for colourisng by letter, shifting, set across"},
|
|
|
|
{x=0,y=2,class="label",label="Shift base:"},
|
|
{x=1,y=2,width=3,class="dropdown",name="shit",items={"# of colours","line","1st2start","last2start","all2start"},value="# of colours",hint="shift by the number of colours the line had been colourised with,\nor shift the whole line (last colour becomes first)"},
|
|
|
|
{x=4,y=0,class="label",label="壹"},
|
|
{x=4,y=1,class="label",label="貳"},
|
|
{x=4,y=2,class="label",label="參"},
|
|
{x=4,y=3,class="label",label="肆"},
|
|
{x=4,y=4,class="label",label="伍"},
|
|
{x=4,y=5,class="label",label="陸"},
|
|
{x=4,y=6,class="label",label="漆"},
|
|
|
|
{x=5,y=0,class="color",name="c1"},
|
|
{x=5,y=1,class="color",name="c2"},
|
|
{x=5,y=2,class="color",name="c3"},
|
|
{x=5,y=3,class="color",name="c4"},
|
|
{x=5,y=4,class="color",name="c5"},
|
|
{x=5,y=5,class="color",name="c6"},
|
|
{x=5,y=6,class="color",name="c7"},
|
|
|
|
{x=0,y=3,width=3,class="checkbox",name="word",label="Colourise by word"},
|
|
{x=0,y=4,width=4,class="checkbox",name="bounce",label="Bounce back (123454321)",hint="colourise: sequence 1234321 instead of 12341234"},
|
|
{x=0,y=5,width=4,class="checkbox",name="cont",label="Shift line by line",hint="shift more with each line"},
|
|
{x=0,y=6,width=4,class="checkbox",name="across",label="Set colours across line"},
|
|
|
|
{x=6,y=0,class="label",label=" "},
|
|
|
|
{x=7,y=2,class="label",label="Red "},
|
|
{x=8,y=2,width=3,class="intedit",name="R",value=0,min=-255,max=255},
|
|
{x=7,y=3,class="label",label="Green "},
|
|
{x=8,y=3,width=3,class="intedit",name="G",value=0,min=-255,max=255},
|
|
{x=7,y=4,class="label",label="Blue "},
|
|
{x=8,y=4,width=3,class="intedit",name="B",value=0,min=-255,max=255},
|
|
|
|
{x=7,y=5,class="label",label="Hue"},
|
|
{x=8,y=5,width=3,class="intedit",name="huehue",value=0,min=-255,max=255},
|
|
{x=7,y=6,class="label",label="Saturation"},
|
|
{x=8,y=6,width=3,class="intedit",name="satur",value=0,min=-255,max=255},
|
|
{x=7,y=7,class="label",label="Lightness"},
|
|
{x=8,y=7,width=3,class="intedit",name="light",value=0,min=-255,max=255},
|
|
|
|
{x=7,y=8,class="checkbox",name="k1",label="\\c",value=true},
|
|
{x=8,y=8,class="checkbox",name="k3",label="\\3c"},
|
|
{x=9,y=8,class="checkbox",name="k4",label="\\4c"},
|
|
{x=10,y=8,class="checkbox",name="k2",label="\\2c"},
|
|
{x=7,y=9,width=2,class="checkbox",name="mktag",label="Apply to missing",hint="Apply even to colours without tags in line"},
|
|
{x=9,y=9,width=2,class="checkbox",name="randoom",label="Randomise",hint="randomise RGB/HSL within the\nspecified range in each direction"},
|
|
|
|
-- Match
|
|
{x=7,y=0,height=2,class="label",label="Match\ncolours:"},
|
|
{x=8,y=0,class="checkbox",name="match13",label="c->3c",hint="copy primary to outline"},
|
|
{x=9,y=0,class="checkbox",name="match31",label="3c->c",hint="copy outline to primary"},
|
|
{x=8,y=1,class="checkbox",name="match14",label="c->4c",hint="copy primary to shadow"},
|
|
{x=9,y=1,class="checkbox",name="match34",label="3c->4c",hint="copy outline to shadow"},
|
|
{x=10,y=0,class="checkbox",name="match131",label="c<->3c",hint="switch primary and outline"},
|
|
{x=10,y=1,class="checkbox",name="invert",label="Invert",hint="invert colours (applies to the types chacked below)"},
|
|
|
|
-- Gradient
|
|
{x=0,y=7,width=2,class="checkbox",name="grad",label="Gradient "},
|
|
{x=2,y=7,width=3,class="checkbox",name="hueshort",label="Shorter hue",value=true},
|
|
{x=5,y=7,class="dropdown",name="grtype",items={"RGB","HSL"},value="HSL"},
|
|
{x=0,y=8,width=4,class="checkbox",name="gradn",label="Restart after each \\N",hint="Restart gradient after each linebreak"},
|
|
{x=0,y=9,width=3,class="checkbox",name="double",label="Double HSL gradient"},
|
|
{x=0,y=10,width=3,class="checkbox",name="ast",label="Use asterisks"},
|
|
{x=0,y=11,width=3,class="floatedit",name="acc",value=1,min=0,hint="Acceleration for gradients"},
|
|
|
|
-- Tune/Reverse
|
|
{x=3,y=9,width=3,class="checkbox",name="tuneall",label="Tune all selected",hint="load from / apply to all selected lines\nrather than one by one"},
|
|
{x=5,y=8,class="dropdown",name="tfmode",items={"all tags","regular","transf"},value="all tags",
|
|
hint="all tags / regular tags / tags in transforms\napplies to 'Tune colours' and RGB/HSL"},
|
|
{x=3,y=10,width=3,class="checkbox",name="reverse",label="Reverse colours",
|
|
hint="Reverse the direction of non-transform colours across the line \nfor the types checked on the right"},
|
|
|
|
{x=7,y=10,width=2,class="checkbox",name="rem",label="Remember last",hint="Remember last settings"},
|
|
{x=9,y=10,width=2,class="checkbox",name="rept",label="Repeat last",hint="Repeat with last settings"},
|
|
{x=7,y=11,width=2,class="checkbox",name="save",label="Save config",hint="Saves current configuration\n(for most things)"},
|
|
{x=9,y=11,width=2,class="label",label="Colourise version "..script_version..""},
|
|
|
|
{x=3,y=11,width=3,class="dropdown",name="help",value=": Help Menu :",hint="Choose a topic. Use any button that's not 'Cancel'.",
|
|
items={": Help Menu :","colourise","shift","setcolours","gradient","tunecolours","reverse","match","RGBHSL","general"}}
|
|
}
|
|
loadconfig()
|
|
if colourblind and res.rem then
|
|
for key,val in ipairs(GUI) do
|
|
if val.class=="checkbox" or val.class=="dropdown" or val.class=="color" or val.class:match"edit" then val.value=res[val.name] end
|
|
if val.name=="save" then val.value=false end
|
|
if val.name=="help" then val.value=": Help Menu :" end
|
|
end
|
|
end
|
|
HELP=false
|
|
NOHELP=true
|
|
repeat
|
|
if HELP then
|
|
if NOHELP then table.insert(GUI,{x=0,y=12,width=11,height=7,class="textbox",name="helpbox"}) end
|
|
for key,val in ipairs(GUI) do
|
|
if val.class=="checkbox" or val.class=="dropdown" or val.class=="color" then val.value=res[val.name] end
|
|
if val.name=="save" then val.value=false end
|
|
if val.name=="rept" then val.value=false end
|
|
if val.name=="helpbox" then val.value=info[res.help] end
|
|
if val.name=="help" then val.value=": Help Menu :" end
|
|
end
|
|
NOHELP=false
|
|
end
|
|
P,res=ADD(GUI,{"Colourise","Shift","Tune/Rvrs","Match Colours","RGB/HSL","Black Out"},{ok='Colourise',close='Black Out'})
|
|
if res.help~=": Help Menu :" then HELP=true else HELP=false end
|
|
until P=="Black Out" or res.help==": Help Menu :"
|
|
if P=="Black Out" then ak() end
|
|
if res.save then saveconfig() ak() end
|
|
|
|
randomise=res.randoom
|
|
if res.tfmode=="all tags" or res.tfmode=="regular" then modereg=true else modereg=false end
|
|
if res.tfmode=="all tags" or res.tfmode=="transf" then modetf=true else modetf=false end
|
|
if P=="Colourise" then repetition()
|
|
if res.grad then gradient(subs,sel)
|
|
elseif res.across then gcolours(subs,sel)
|
|
else colors(subs,sel) end
|
|
end
|
|
if P=="Tune/Rvrs" then repetition()
|
|
if res.reverse then rvrsgrad(subs,sel) else ctune(subs,sel) end
|
|
end
|
|
if P=="Shift" then repetition() if res.shit:match'start' then shift2(subs,sel) else shift(subs,sel) end end
|
|
if P=="Match Colours" or P=="RGB/HSL" then repetition() styleget(subs) match_col(subs,sel) end
|
|
|
|
lastres=res
|
|
colourblind=true
|
|
return sel
|
|
end
|
|
|
|
|
|
-- Colour Ice --
|
|
function colors(subs,sel)
|
|
local c={}
|
|
for k=1,7 do
|
|
c[k]=res["c"..k]:gsub("#(%x%x)(%x%x)(%x%x)","&H%3%2%1&")
|
|
end
|
|
for z,i in ipairs(sel) do
|
|
progress("Colourising line #"..i-line0.." ["..z.."/"..#sel.."]")
|
|
line=subs[i]
|
|
text=line.text
|
|
tags=text:match(STAG) or ""
|
|
if not tags:match("\\p1") then
|
|
text=text:gsub("\\t(%b())",function(t) return "\\tra"..t:gsub("\\","/") end)
|
|
visible=nobrea(text)
|
|
|
|
local kl=res.kol
|
|
if kl=="\\c" then text=text:gsub("\\1?c[^l\\})]*([\\}])","%1") end
|
|
if kl=="\\3c" then text=text:gsub("\\3c[^\\})]*","") end
|
|
if kl=="\\4c" then text=text:gsub("\\4c[^\\})]*","") end
|
|
if kl=="\\2c" then text=text:gsub("\\2c[^\\})]*","") end
|
|
text=text:gsub("{}","")
|
|
|
|
local col={} -- table with colours to use
|
|
for t=1,res.clrs do table.insert(col,wrap(kl..c[t])) end
|
|
if res.bounce and tonumber(res.clrs)>2 then
|
|
for t=res.clrs-1,2,-1 do table.insert(col,wrap(kl..c[t])) end
|
|
end
|
|
|
|
orig=text:gsub(STAG,""):gsub("\\N","{\\N}")
|
|
-- save positions for inline tags and comments
|
|
inTags=inline_pos(orig)
|
|
if not res.word then
|
|
-- by letter
|
|
local letrz=re.find(visible,".") or {}
|
|
letrz=re_test(letrz,visible)
|
|
nt=""
|
|
local p=1
|
|
for k=2,#letrz do
|
|
local ltr=letrz[k].str
|
|
-- add colour tag positions to table
|
|
if ltr~=" " then
|
|
p=p%#col+1 -- cycle colours
|
|
table.insert(inTags,{n=k-1,t=col[p]})
|
|
end
|
|
end
|
|
table.sort(inTags,function(a,b) return a.n<b.n end)
|
|
-- put back all inline tags
|
|
local _=0
|
|
repeat
|
|
t2=inline_ret(visible,inTags)
|
|
local vis=t2:gsub("%b{}","")
|
|
_=_+1
|
|
until vis==visible or _==666
|
|
|
|
tags=tags..col[1]
|
|
text=tags..t2
|
|
else
|
|
-- by word
|
|
orig=orig:gsub("(%b{})",function(com) return com:gsub(" ","_SP_") end)
|
|
local n=0
|
|
t2=orig:gsub("%S+%s*",function(a) n=n%#col+1 b=col[n]..a return b end)
|
|
text=tags..t2
|
|
text=text:gsub("_SP_"," "):gsub("(%b{})(\\N)(%b{})","%2%3%1"):gsub("(%b{})(\\N)","%2%1")
|
|
end
|
|
|
|
text=text:gsub("{\\N","\\N{"):gsub("\\N}","}\\N"):gsub("{}","")
|
|
text=text:gsub("\\tra(%b())",function(t) return "\\t"..t:gsub("/","\\") end)
|
|
text=tagmerge(text)
|
|
text=text:gsub(ATAG,function(tg) return duplikill(tg) end)
|
|
visible2=nobrea(text)
|
|
txt_check(visible,visible2,i)
|
|
line.text=text
|
|
subs[i]=line
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
-- Tune Colours --
|
|
function ctune(subs,sel)
|
|
if res.tuneall then
|
|
local tuneallc=""
|
|
for z,i in ipairs(sel) do
|
|
t=subs[i].text
|
|
if res.tfmode=="regular" then t=t:gsub("\\t%b()","") end
|
|
if res.tfmode=="transf" then nt="" for tf in t:gmatch("\\t%b()") do nt=nt..tf end t=nt end
|
|
for kol in t:gmatch("\\%d?c%b&&") do
|
|
if not tuneallc:match(kol) then tuneallc=tuneallc..kol end
|
|
end
|
|
end
|
|
tuneallc=tuneallc:gsub("\\c&","\\1c&")
|
|
tunegui()
|
|
for l=1,4 do
|
|
if tuneallc:match(l.."c&") then table.insert(coltunegui,lbls[l]) end
|
|
end
|
|
for col in tuneallc:gmatch("(\\[1234]c&H%x%x%x%x%x%x&)") do
|
|
cType,B,G,R=col:match("\\([1234])c&H(%x%x)(%x%x)(%x%x)&")
|
|
ctNo=tonumber(cType)
|
|
C="#"..R..G..B
|
|
table.insert(coltunegui,{x=cType,y=wai[ctNo],class="color",name=cType..wai[ctNo],value=C})
|
|
wai[ctNo]=wai[ctNo]+1
|
|
end
|
|
pressed,rez=ADD(coltunegui,{"OK","Cancel"},{ok='OK',close='Cancel'})
|
|
if pressed=="Cancel" then ak() end
|
|
replcol={}
|
|
for k,v in ipairs(coltunegui) do
|
|
if v.class=="color" then
|
|
c1="\\"..v.x.."c"..v.value:gsub("#(%x%x)(%x%x)(%x%x)","&H%3%2%1&")
|
|
c2="\\"..v.x.."c"..rez[v.name]:gsub("#(%x%x)(%x%x)(%x%x)","&H%3%2%1&")
|
|
table.insert(replcol,{c1=c1,c2=c2}) end
|
|
end
|
|
end
|
|
for z=1,#sel do
|
|
i=sel[z]
|
|
progress("Processing... #"..i-line0.." ["..z.."/"..#sel.."]")
|
|
line=subs[i]
|
|
text=line.text:gsub("\\c&","\\1c&")
|
|
if res.tuneall then
|
|
text=alltune(text)
|
|
elseif text:match("c&H%x+&") then
|
|
tunegui(z)
|
|
tekst={}
|
|
ccheck={}
|
|
text=tunec(text)
|
|
end
|
|
text=text:gsub("\\1c&","\\c&")
|
|
line.text=text
|
|
subs[i]=line
|
|
end
|
|
pressed=nil
|
|
end
|
|
|
|
function tunegui(z)
|
|
wai={1,1,1,1}
|
|
chk={0,0,0,0}
|
|
lbls={{label="primary"},{label="2ndary"},{label="border"},{label="shadow"}}
|
|
for l=1,4 do lbls[l].class="label" lbls[l].x=l end
|
|
if res.tuneall then coltunegui={} else coltunegui={{class="label",label="#"..z}} end
|
|
end
|
|
|
|
function alltune(text)
|
|
segments={}
|
|
text=text:gsub("\\t%([^\\%)]-%)","")
|
|
if text:match("\\t%b()") then
|
|
for seg1,seg2 in text:gmatch("(.-)(\\t%b())") do table.insert(segments,seg1) table.insert(segments,seg2) end
|
|
table.insert(segments,text:match("^.*\\t%b()(.-)$"))
|
|
else table.insert(segments,text)
|
|
end
|
|
nt=""
|
|
for q=1,#segments do
|
|
if segments[q]:match("\\t%b()") and modetf then segments[q]=replicolour(segments[q])
|
|
elseif not segments[q]:match("\\t%b()") and modereg then segments[q]=replicolour(segments[q])
|
|
end
|
|
nt=nt..segments[q]
|
|
end
|
|
return nt
|
|
end
|
|
|
|
function replicolour(t)
|
|
for rc=1,#replcol do t=t:gsub(replcol[rc].c1,replcol[rc].c2) end
|
|
return t
|
|
end
|
|
|
|
function tunec(text)
|
|
segments={}
|
|
text=text:gsub("\\t%([^\\%)]-%)","")
|
|
if text:match("\\t%b()") then
|
|
for seg1,seg2 in text:gmatch("(.-)(\\t%b())") do table.insert(segments,seg1) table.insert(segments,seg2) end
|
|
table.insert(segments,text:match("^.*\\t%b()(.-)$"))
|
|
else table.insert(segments,text)
|
|
end
|
|
for q=1,#segments do
|
|
if segments[q]:match("\\t%b()") and modetf then segments[q]=tune(segments[q])
|
|
elseif not segments[q]:match("\\t%b()") and modereg then segments[q]=tune(segments[q])
|
|
else table.insert(tekst,segments[q]) table.insert(ccheck,0) end
|
|
end
|
|
|
|
pressed,rez=ADD(coltunegui,{"OK","Cancel"},{ok='OK',close='Cancel'})
|
|
if pressed=="Cancel" then ak() end
|
|
|
|
text=""
|
|
rezlt={1,1,1,1}
|
|
for c=1,#tekst do
|
|
nt=tekst[c]
|
|
if ccheck[c]==1 then
|
|
col=nt:match("\\[1234]c&H%x%x%x%x%x%x&")
|
|
cType,B,G,R=col:match("\\([1234])c&H(%x%x)(%x%x)(%x%x)&")
|
|
ctNo=tonumber(cType)
|
|
cor=esc(col)
|
|
crep="\\"..cType.."c"..rez[cType..rezlt[ctNo]]:gsub("#(%x%x)(%x%x)(%x%x)","&H%3%2%1&")
|
|
text=text..nt:gsub(cor,crep)
|
|
rezlt[ctNo]=rezlt[ctNo]+1
|
|
else text=text..nt
|
|
end
|
|
end
|
|
return text
|
|
end
|
|
|
|
function tune(txt)
|
|
for t,col in txt:gmatch("(.-)(\\[1234]c&H%x%x%x%x%x%x&)") do
|
|
cType,B,G,R=col:match("\\([1234])c&H(%x%x)(%x%x)(%x%x)&")
|
|
ctNo=tonumber(cType)
|
|
C="#"..R..G..B
|
|
if chk[ctNo]==0 then table.insert(coltunegui,lbls[ctNo]) chk[ctNo]=1 end
|
|
table.insert(coltunegui,{x=cType,y=wai[ctNo],class="color",name=cType..wai[ctNo],value=C})
|
|
table.insert(tekst,t..col)
|
|
table.insert(ccheck,1)
|
|
wai[ctNo]=wai[ctNo]+1
|
|
end
|
|
final=txt:match(".*\\[1234]c&H%x%x%x%x%x%x&(.-)$")
|
|
if not final then final=txt end
|
|
table.insert(tekst,final)
|
|
table.insert(ccheck,0)
|
|
return txt
|
|
end
|
|
|
|
|
|
-- Colours across line --
|
|
function gcolours(subs,sel)
|
|
local cn=tonumber(res.clrs)
|
|
local fn=cn-1
|
|
-- factors table
|
|
fakt={0}
|
|
for f=1,fn do table.insert(fakt,f/fn) end
|
|
kt=res.kol
|
|
-- colours table
|
|
local kolors={}
|
|
for c=1,cn do
|
|
gcol=res["c"..c]:gsub("#(%x%x)(%x%x)(%x%x)","&H%3%2%1&")
|
|
gcol=kt..gcol
|
|
table.insert(kolors,gcol)
|
|
end
|
|
|
|
for z,i in ipairs(sel) do
|
|
progress("Colourising line #"..i-line0.." ["..z.."/"..#sel.."]")
|
|
line=subs[i]
|
|
text=line.text
|
|
visible=nobrea(text):gsub("^ *(.-) *$","%1")
|
|
text=text:gsub("\\t(%b())",function(t) return "\\tra"..t:gsub("\\","/") end)
|
|
:gsub("\\1c","\\c") :gsub(kt.."&H%x+&","") :gsub("{}","")
|
|
tags=text:match(STAG) or ""
|
|
orig=text:gsub(STAG,""):gsub("\\N",""):gsub("^ *(.-) *$","%1")
|
|
breaks=text:gsub("%b{}",""):gsub("^ *(.-) *$","%1")
|
|
text=breaks:gsub("\\N","")
|
|
clean=text:gsub(" ","")
|
|
back=text
|
|
if clean~="" and not tags:match("\\p1") then
|
|
local c=0
|
|
repeat
|
|
text=back
|
|
len=re.find(clean,".") or {}
|
|
nt=""
|
|
for n=cn,1,-1 do
|
|
lngth=math.ceil((#len-1)*fakt[n])
|
|
kolr=kolors[n]
|
|
seg=re.sub(text,"\\S\\s*","",lngth)
|
|
if lngth==0 then seg=text end
|
|
text=text:gsub(esc(seg).."$","")
|
|
seg="{"..kolr.."}"..seg
|
|
nt=seg..nt
|
|
end
|
|
text=nt
|
|
text=tags..textmod(orig,text)
|
|
text=text:gsub("({\\[^}]-)}{(\\[^}]-})","%1%2")
|
|
:gsub(ATAG,function(tg) repeat tg,r=tg:gsub(kt.."%b&&([^}]-)("..kt.."%b&&)","%2%1") until r==0 return tg end)
|
|
:gsub("\\tra(%b())",function(t) return "\\t"..t:gsub("/","\\") end)
|
|
|
|
for breakpos in breaks:gmatch("(.-)\\N") do
|
|
BPL=breakpos:len()
|
|
if LBP then BPL=BPL+LBP+2 end
|
|
if BPL>0 then text=insertxt(text,BPL,"\\N") end
|
|
LBP=BPL or 0
|
|
end
|
|
LBP=nil
|
|
visible2=nobrea(text)
|
|
c=c+1
|
|
until visible==visible2 or c==666
|
|
txt_check(visible,visible2,i)
|
|
line.text=text
|
|
subs[i]=line
|
|
end
|
|
end
|
|
end
|
|
|
|
function insertxt(text,txtpos,thing)
|
|
pos=0
|
|
tcount=0
|
|
for tg,tx in text:gmatch("("..ATAG..")([^{]*)") do
|
|
sl=tx:len() tl=tg:len()
|
|
if sl+pos<txtpos then pos=pos+sl tcount=tcount+tl
|
|
else
|
|
cpos=txtpos-pos
|
|
fullpos=pos+tcount+tl+cpos
|
|
break
|
|
end
|
|
end
|
|
before=text:sub(0,fullpos)
|
|
after=text:sub(fullpos+1)
|
|
text=before..thing..after
|
|
return text
|
|
end
|
|
|
|
|
|
-- Shift colours --
|
|
function shift(subs,sel)
|
|
klrs=tonumber(res.clrs) -- how many colours we're dealing with
|
|
count=1 -- start line counter
|
|
local sline
|
|
if res.shit=="line" then sline=true end
|
|
local kl=res.kol
|
|
|
|
for z,i in ipairs(sel) do
|
|
progress("Colourising line #"..i-line0.." ["..z.."/"..#sel.."]")
|
|
line=subs[i]
|
|
text=line.text
|
|
text=text:gsub("\\t(%b())",function(t) return "\\tra"..t:gsub("\\","/") end)
|
|
|
|
local last
|
|
local n=0
|
|
repeat
|
|
-- get last colour
|
|
if not sline then
|
|
local b=text:gsub(kl.."%b&&","",klrs-1)
|
|
last=b:match(kl.."%b&&")
|
|
if not last then t_error("Line #"..i-line0.." does not have "..klrs.." colours of the "..kl.." type.\nAborting.",1) end
|
|
else
|
|
last=text:match(".*("..kl.."%b&&)")
|
|
if not last then t_error("Line #"..i-line0.." does not have any colours of the "..kl.." type.\nAborting.",1) end
|
|
end
|
|
local col={last}
|
|
|
|
-- this fucking line does the whole thing
|
|
text=text:gsub("(.-)("..kl.."%b&&)",function(t,c) table.insert(col,1,c) return t..col[2] end)
|
|
n=n+1
|
|
until n==count
|
|
|
|
-- line counter
|
|
if res.cont then count=count+1 end
|
|
if not sline and count>klrs then count=1 end
|
|
|
|
text=text:gsub("\\tra(%b())",function(t) return "\\t"..t:gsub("/","\\") end)
|
|
line.text=text
|
|
subs[i]=line
|
|
end
|
|
end
|
|
|
|
function shift2(subs,sel)
|
|
local k=res.kol
|
|
for z,i in ipairs(sel) do
|
|
progress("Processing line #"..i-line0.." ["..z.."/"..#sel.."]")
|
|
line=subs[i]
|
|
text=line.text
|
|
tags=text:match(STAG) or ""
|
|
inline=text:gsub(STAG,"")
|
|
local kol
|
|
if res.shit:match"1st" then kol=inline:match(k.."%b&&") inline=inline:gsub(k.."%b&&","",1)
|
|
else kol=inline:match(".*("..k.."%b&&)") end
|
|
if res.shit:match'last' then inline=inline:gsub("(.*)"..k.."%b&&","%1") end
|
|
if res.shit:match'all' then inline=inline:gsub(k.."%b&&","") end
|
|
inline=inline:gsub("{}","")
|
|
if kol then
|
|
if tags=="" then tags=wrap(kol) else tags=addtag3(kol,tags) end
|
|
text=tags..inline
|
|
line.text=text
|
|
subs[i]=line
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Match colours --
|
|
function match_col(subs,sel)
|
|
local MC
|
|
if P=="Match Colours" then _=0 MC=1
|
|
for key,val in ipairs(GUI) do
|
|
if val.name and val.name:match"match" and res[val.name] then _=_+1 end
|
|
if val.name and val.name=="invert" and res[val.name] then _=_+1 end
|
|
end
|
|
if _>1 then t_error("Multiple checkboxes for matching checked.\nResults may be unpredictable.") end
|
|
end
|
|
local RGB, HSL
|
|
lvlr=res.R lvlg=res.G lvlb=res.B
|
|
hue=res.huehue sat=res.satur lite=res.light
|
|
if lvlr~=0 or lvlg~=0 or lvlb~=0 then RGB=true end
|
|
if hue~=0 or sat~=0 or lite~=0 then HSL=true end
|
|
|
|
for z,i in ipairs(sel) do
|
|
progress("Colourising line #"..i-line0.." ["..z.."/"..#sel.."]")
|
|
line=subs[i]
|
|
text=line.text
|
|
if defaref and line.style=="Default" then sr=defaref
|
|
elseif lastref and laststyle==line.style then sr=lastref
|
|
else sr=stylechk(line.style) end
|
|
lastref=sr laststyle=line.style
|
|
stylecol=stylecolours()
|
|
text=text:gsub("\\1c","\\c")
|
|
if not text:match("^{\\") then text=text:gsub("^","{\\}") end
|
|
tags=text:match(STAG)
|
|
notftags=tags:gsub("\\t%b()","")
|
|
|
|
-- Matching
|
|
if MC then
|
|
if res.match13 then text=macchi(text,"\\c","\\3c",primary) end
|
|
if res.match31 then text=macchi(text,"\\3c","\\c",outline) end
|
|
if res.match14 then text=macchi(text,"\\c","\\4c",primary) end
|
|
if res.match34 then text=macchi(text,"\\3c","\\4c",outline) end
|
|
end
|
|
|
|
-- switch primary and border
|
|
if MC and res.match131 then
|
|
if not notftags:match("\\c&") then text=addtag3("\\c"..primary,text) end
|
|
if not notftags:match("\\3c") then text=addtag3("\\3c"..outline,text) end
|
|
text=text:gsub("\\c&","\\tempc&"):gsub("\\3c","\\c"):gsub("\\tempc","\\3c")
|
|
end
|
|
|
|
-- Invert All Colours
|
|
if MC and res.invert then
|
|
match="["
|
|
for n=1,4 do
|
|
ctg="\\"..n.."c"
|
|
ctg=ctg:gsub("1","")
|
|
if not notftags:match(ctg) and n~=2 then text=addtag3(ctg..stylecol[n],text) end
|
|
if n>1 and res['k'..n] then match=match..n end
|
|
end
|
|
match=match..']'
|
|
if res.k1 then match=match..'?' end
|
|
match=match:gsub("%[%]%?","")
|
|
text=text:gsub("(\\"..match.."c&H)(%x%x%x%x%x%x)&",function(tg,col)
|
|
invcol=""
|
|
for kol in col:gmatch("(%x%x)") do
|
|
dkol=tonumber(kol,16)
|
|
idkol=255-dkol
|
|
ikol=tohex(idkol)
|
|
invcol=invcol..ikol
|
|
end
|
|
return tg..invcol.."&"
|
|
end)
|
|
end
|
|
|
|
-- RGB / HSL
|
|
if P=="RGB/HSL" then
|
|
corols={}
|
|
if res.k1 then table.insert(corols,1) end
|
|
if res.k2 then table.insert(corols,2) end
|
|
if res.k3 then table.insert(corols,3) end
|
|
if res.k4 then table.insert(corols,4) end
|
|
for i=1,#corols do
|
|
kl="\\"..corols[i].."c"
|
|
kl=kl:gsub("1","")
|
|
if res.mktag and not notftags:match(kl) then text=addtag3(kl..stylecol[corols[i]],text) end
|
|
if RGB then text=rgbhslmod(text,kl,rgbm) end
|
|
if HSL then text=rgbhslmod(text,kl,hslm) end
|
|
end
|
|
end
|
|
|
|
text=text:gsub("\\([\\}])","%1") :gsub("\\t%([^\\%)]*%)","") :gsub("{}","")
|
|
line.text=text
|
|
subs[i]=line
|
|
end
|
|
end
|
|
|
|
function macchi(text,c1,c2,kv)
|
|
if not notftags:match(c1.."&") then text=addtag3(c1..kv,text) end
|
|
text=text:gsub(ATAG,function(ctags) ctags=ctags:gsub(c2..ACLR,""):gsub(c1.."("..ACLR..")",c1.."%1"..c2.."%1") return ctags end)
|
|
return text
|
|
end
|
|
|
|
function rgbhslmod(text,kl,ef)
|
|
local segments={}
|
|
if text:match("\\t%b()") then
|
|
for seg1,seg2 in text:gmatch("(.-)(\\t%b())") do table.insert(segments,seg1) table.insert(segments,seg2) end
|
|
table.insert(segments,text:match("^.*\\t%b()(.-)$"))
|
|
else table.insert(segments,text)
|
|
end
|
|
for q=1,#segments do
|
|
if segments[q]:match("\\t%b()") and modetf then segments[q]=ef(segments[q],kl) end
|
|
if not segments[q]:match("\\t%b()") and modereg then segments[q]=ef(segments[q],kl) end
|
|
end
|
|
nt=""
|
|
for q=1,#segments do nt=nt..segments[q] end
|
|
return nt
|
|
end
|
|
|
|
function rgbm(text,kl)
|
|
text=text:gsub(kl.."&H(%x%x)(%x%x)(%x%x)&",function(kol1,kol2,kol3)
|
|
kol1n=brightness(kol1,lvlb)
|
|
kol2n=brightness(kol2,lvlg)
|
|
kol3n=brightness(kol3,lvlr)
|
|
return kl.."&H"..kol1n..kol2n..kol3n.."&"
|
|
end)
|
|
return text
|
|
end
|
|
|
|
function hslm(text,kl)
|
|
text=text:gsub(kl.."&H(%x%x)(%x%x)(%x%x)&",function(kol1,kol2,kol3)
|
|
H1,S1,L1=RGB_to_HSL(kol3,kol2,kol1)
|
|
H1,S1,L1=RGB_to_HSL(kol3,kol2,kol1)
|
|
H=H1+hue/255
|
|
S=S1+sat/255
|
|
L=L1+lite/255
|
|
if randomise then
|
|
H2=H1-hue/255
|
|
S2=S1-sat/255
|
|
L2=L1-lite/255
|
|
H=math.random(H*1000,H2*1000)/1000
|
|
S=math.random(S*1000,S2*1000)/1000
|
|
L=math.random(L*1000,L2*1000)/1000
|
|
end
|
|
H,S,L=HSLround(H,S,L)
|
|
kol3n,kol2n,kol1n=HSL_to_RGB(H,S,L)
|
|
kol3n=tohex(round(kol3n))
|
|
kol2n=tohex(round(kol2n))
|
|
kol1n=tohex(round(kol1n))
|
|
return kl.."&H"..kol1n..kol2n..kol3n.."&"
|
|
end)
|
|
return text
|
|
end
|
|
|
|
|
|
-- GRADIENT --
|
|
function gradient(subs,sel)
|
|
styleget(subs)
|
|
if res.grtype=="RGB" then GRGB=true else GRGB=false end
|
|
if res.ast then ast="*" else ast="" end
|
|
for z,i in ipairs(sel) do
|
|
progress("Colourising line #"..i-line0.." ["..z.."/"..#sel.."]")
|
|
line=subs[i]
|
|
re_check=0
|
|
repeat
|
|
text=line.text
|
|
if text:match '\\p1' then break end
|
|
text=text:gsub("\\N (%w)","\\N%1"):gsub(" +\\N"," \\N"):gsub("{%*\\[^}]+}",""):gsub("{}","")
|
|
visible=nobrea1(text)
|
|
-- comments
|
|
local komments=''
|
|
for cm in text:gmatch("{[^\\{}]-}") do komments=komments..cm end
|
|
-- something to [try to] deal with spaces and linebreaks because dumb renderer inconsistency
|
|
breaks={}
|
|
for br in text:gmatch(" ?\\[Nh]") do
|
|
table.insert(breaks,br)
|
|
end
|
|
acc=line.effect:match("accel ?(%d+%.?%d*)") or res.acc
|
|
text=text:gsub("\\c&","\\1c&"):gsub("\\c([}\\])","\\1c%1") :gsub(" *(\\[Nh]) *","{%1}")
|
|
:gsub("\\t(%b())",function(t) return "\\tra"..t:gsub("\\","/") end)
|
|
text=tagmerge(text)
|
|
after=text:gsub(STAG,"")
|
|
nc=text:gsub(COMM,"")
|
|
if text:match(ATAG.."$") then text=text.."wtfwhywouldyoudothis" end
|
|
-- colours from style
|
|
sr=stylechk(line.style)
|
|
stylecol=stylecolours()
|
|
-- which types will be used
|
|
applycol={}
|
|
if res.k1 and after:match("\\1c") then table.insert(applycol,1) end
|
|
if res.k2 and after:match("\\2c") then table.insert(applycol,2) end
|
|
if res.k3 and after:match("\\3c") then table.insert(applycol,3) end
|
|
if res.k4 and after:match("\\4c") then table.insert(applycol,4) end
|
|
|
|
for g=1,#applycol do
|
|
ac=applycol[g]
|
|
sc=stylecol[ac]
|
|
tags=text:match(STAG) or ""
|
|
-- linebreak adjustment
|
|
if res.gradn then
|
|
startc=tags:match("\\"..ac.."c&H%x+&") or "\\"..ac.."c"..sc
|
|
endc=nc:match("(\\"..ac.."c&H%x+&)[^}]-}%S+$") or ""
|
|
text=text:gsub("([%S])%s*({\\N.-})","{"..endc.."}%1%2{"..startc.."}"):gsub("{}","")
|
|
end
|
|
-- set style colour to reset c tags
|
|
text=text:gsub("(\\"..ac.."c)([}\\])","%1"..sc.."%2")
|
|
-- back up original
|
|
orig=text
|
|
text=text:gsub("{[^\\}]-}","")
|
|
-- leave only releavant colour tags, nuke all other ones, add colour from style if missing at the start
|
|
ctext=text:gsub("\\N","") --:gsub("\\[ibusaqk]%d?([\\}])","%1") :gsub("\\[^1234][^c][^\\}]*","") :gsub("\\[^"..ac.."]c[^\\}]*","") :gsub("{%**}","")
|
|
ctext=ctext:gsub("\\[^\\}]+",function(tag) if tag:match("\\"..ac.."c%b&&") then return tag else return "" end end) :gsub("{%**}","")
|
|
if not ctext:match("^{\\") then ctext="{\\kolor}"..ctext end
|
|
if not ctext:match("^{[^}]-\\"..ac.."c") then
|
|
ctext=ctext:gsub("^({\\[^}]-)}","%1\\"..ac.."c"..sc.."}") end
|
|
-- make tables of colour tags and text after them
|
|
linecol={}
|
|
posi={}
|
|
coltext={}
|
|
pos=0
|
|
for k,t in ctext:gmatch("{[^}]-\\"..ac.."c&H(%x+)&[^}]-}([^{]+)") do
|
|
table.insert(posi,pos)
|
|
table.insert(linecol,k)
|
|
table.insert(coltext,t)
|
|
ps=re.find(t,".")
|
|
pos=#ps
|
|
end
|
|
-- text for each colour
|
|
gradtext=""
|
|
|
|
-- sequence for each colour tag / text
|
|
for c=1,#linecol-1 do
|
|
-- get RBG [and HSL if needed]
|
|
B1,G1,R1=linecol[c]:match("(%x%x)(%x%x)(%x%x)")
|
|
B2,G2,R2=linecol[c+1]:match("(%x%x)(%x%x)(%x%x)")
|
|
if not GRGB then
|
|
H1,S1,L1=RGB_to_HSL(R1,G1,B1)
|
|
H2,S2,L2=RGB_to_HSL(R2,G2,B2)
|
|
if res.hueshort then
|
|
if H2>H1 and H2-H1>0.5 then H1=H1+1 end
|
|
if H2<H1 and H1-H2>0.5 then H2=H2+1 end
|
|
end
|
|
if res.double then
|
|
if H2>H1 then H2=H2+1 else H1=H1+1 end
|
|
if H1>2 or H2>2 then H2=H2-1 H1=H1-1 end
|
|
end
|
|
end
|
|
|
|
-- letters of this sequence
|
|
textseq={}
|
|
ltrmatches=re.find(coltext[c],".")
|
|
for l=1,#ltrmatches do
|
|
table.insert(textseq,ltrmatches[l].str)
|
|
end
|
|
-- new text starting with original colour tag and first letter
|
|
ntxt="{\\"..ac.."c&H"..linecol[c].."&}"..textseq[1]
|
|
-- calculate colours for the other letters in sequence
|
|
for l=2,posi[c+1] do
|
|
if textseq[l]~=" " then
|
|
if GRGB then -- RGB
|
|
NC=acgrad(linecol[c],linecol[c+1],posi[c+1],l,acc)
|
|
else -- HSL
|
|
local acc_fac=(l-1)^acc/(posi[c+1])^acc
|
|
H=acc_fac*(H2-H1)+H1
|
|
S=acc_fac*(S2-S1)+S1
|
|
L=acc_fac*(L2-L1)+L1
|
|
R,G,B=HSL_to_RGB(H,S,L)
|
|
R=tohex(round(R))
|
|
G=tohex(round(G))
|
|
B=tohex(round(B))
|
|
NC="&H"..B..G..R.."&"
|
|
end
|
|
ncol="{"..ast.."\\"..ac.."c"..NC.."}"
|
|
-- colour + letter
|
|
ntxt=ntxt..ncol..textseq[l]
|
|
else
|
|
-- spaces (no tags)
|
|
ntxt=ntxt..textseq[l]
|
|
end
|
|
end
|
|
gradtext=gradtext..ntxt
|
|
end
|
|
-- add final tag + text
|
|
gradtext=gradtext.."{\\"..ac.."c&H"..
|
|
linecol[#linecol].."&}"..
|
|
coltext[#coltext]
|
|
text=tags..gradtext
|
|
-- merge with original
|
|
text=textmod(orig,text)
|
|
end
|
|
text=text:gsub(ATAG,function(tg) return colkill(tg) end)
|
|
text=text:gsub("\\tra(%b())",function(t) return "\\t"..t:gsub("/","\\") end)
|
|
:gsub("wtfwhywouldyoudothis","")
|
|
repeat text,r=text:gsub("{([^}]-)(\\[Nh])([^}]-)}","%2{%1%3}") until r==0
|
|
text=text:gsub("{%**}",""):gsub("(%S)(\\[Nh])","%1 %2")
|
|
:gsub("([^{])%*\\","%1\\")
|
|
local b=0
|
|
text=text:gsub(" \\[Nh]",function() b=b+1 return breaks[b] end)..komments
|
|
visible2=nobrea1(text)
|
|
if visible~=visible2 then re_check=re_check+1 end
|
|
until visible==visible2 or re_check==256
|
|
txt_check(visible,visible2,i)
|
|
line.text=text
|
|
subs[i]=line
|
|
end
|
|
end
|
|
|
|
|
|
-- Reverse Colours --
|
|
function rvrsgrad(subs,sel)
|
|
for z,i in ipairs(sel) do
|
|
progress("Colourising line #"..i-line0.." ["..z.."/"..#sel.."]")
|
|
line=subs[i]
|
|
text=line.text
|
|
text=text:gsub("\\t(%b())",function(t) return "\\tra"..t:gsub("\\","/") end) :gsub("\\c&","\\1c&")
|
|
after=text:gsub(STAG,"")
|
|
applycol={}
|
|
if res.k1 and after:match("\\1c") then table.insert(applycol,1) end
|
|
if res.k2 and after:match("\\2c") then table.insert(applycol,2) end
|
|
if res.k3 and after:match("\\3c") then table.insert(applycol,3) end
|
|
if res.k4 and after:match("\\4c") then table.insert(applycol,4) end
|
|
|
|
for g=1,#applycol do
|
|
ac=applycol[g]
|
|
tagtab={}
|
|
coltab={}
|
|
for tt,cc in text:gmatch("(.-)(\\"..ac.."c&H%x+&)") do table.insert(tagtab,tt..cc) table.insert(coltab,cc) end
|
|
END=text:match("^.*\\"..ac.."c&H%x+&(.-)$")
|
|
for t=1,#tagtab do o=#tagtab-t+1
|
|
tagtab[t]=tagtab[t]:gsub("\\"..ac.."c&H%x+&",coltab[o])
|
|
end
|
|
nt=END
|
|
for a=#tagtab,1,-1 do nt=tagtab[a]..nt end
|
|
text=nt
|
|
end
|
|
|
|
text=text:gsub("\\tra(%b())",function(t) return "\\t"..t:gsub("/","\\") end) :gsub("\\1c&","\\c&")
|
|
line.text=text
|
|
subs[i]=line
|
|
end
|
|
end
|
|
|
|
function stylecolours()
|
|
stylecol={} notf=text:gsub("\\t%b()","")
|
|
table.insert(stylecol,(sr.color1:gsub("H%x%x","H"))) primary=notf:match("^{[^}]-\\c(&H%x+&)") or stylecol[1]
|
|
table.insert(stylecol,(sr.color2:gsub("H%x%x","H"))) secondary=notf:match("^{[^}]-\\3c(&H%x+&)") or stylecol[2]
|
|
table.insert(stylecol,(sr.color3:gsub("H%x%x","H"))) outline=notf:match("^{[^}]-\\3c(&H%x+&)") or stylecol[3]
|
|
table.insert(stylecol,(sr.color4:gsub("H%x%x","H"))) shadow=notf:match("^{[^}]-\\c(&H%x+&)")or stylecol[4]
|
|
return stylecol
|
|
end
|
|
|
|
function acgrad(C1,C2,total,l,acc)
|
|
local acc_fac=(l-1)^acc/(total)^acc
|
|
B1,G1,R1=C1:match("(%x%x)(%x%x)(%x%x)")
|
|
B2,G2,R2=C2:match("(%x%x)(%x%x)(%x%x)")
|
|
A1=C1:match("(%x%x)") R1=R1 or A1
|
|
A2=C2:match("(%x%x)") R2=R2 or A2
|
|
nR1=(tonumber(R1,16)) nR2=(tonumber(R2,16))
|
|
R=acc_fac*(nR2-nR1)+nR1
|
|
R=tohex(round(R))
|
|
CC="&H"..R.."&"
|
|
if B1 then
|
|
nG1=(tonumber(G1,16)) nG2=(tonumber(G2,16))
|
|
nB1=(tonumber(B1,16)) nB2=(tonumber(B2,16))
|
|
G=acc_fac*(nG2-nG1)+nG1
|
|
B=acc_fac*(nB2-nB1)+nB1
|
|
G=tohex(round(G))
|
|
B=tohex(round(B))
|
|
CC="&H"..B..G..R.."&"
|
|
end
|
|
return CC
|
|
end
|
|
|
|
-- reamnimatools ---------------------------------------------
|
|
function esc(str) str=str:gsub("[%%%(%)%[%]%.%-%+%*%?%^%$]","%%%1") return str end
|
|
function round(num) num=math.floor(num+0.5) return num end
|
|
function tagmerge(t) repeat t,r=t:gsub("({\\[^}]-)}{(\\[^}]-})","%1%2") until r==0 return t end
|
|
function wrap(str) return "{"..str.."}" end
|
|
function nobra(t) return t:gsub("%b{}","") end
|
|
function nobrea(t) return t:gsub("%b{}",""):gsub("\\N","") end
|
|
function nobrea1(t) return t:gsub("%b{}",""):gsub(" *\\N *"," ") end
|
|
function logg(m) m=tf(m) or "nil" aegisub.log("\n "..m) end
|
|
function logg2(m)
|
|
local lt=type(m)
|
|
aegisub.log("\n >> "..lt)
|
|
if lt=='table' then
|
|
aegisub.log(" (#"..#m..")")
|
|
if not m[1] then
|
|
for k,v in pairs(m) do
|
|
if type(v)=='table' then vvv='[table]' elseif type(v)=='number' then vvv=v..' (n)' else vvv=v end
|
|
aegisub.log("\n "..k..': '..vvv)
|
|
end
|
|
elseif type(m[1])=='table' then aegisub.log("\n nested table")
|
|
else aegisub.log("\n {"..table.concat(m,', ').."}") end
|
|
else
|
|
m=tf(m) or "nil" aegisub.log("\n "..m)
|
|
end
|
|
end
|
|
function loggtab(m) m=tf(m) or "nil" aegisub.log("\n {"..table.concat(m,';').."}") end
|
|
function progress(msg) if aegisub.progress.is_cancelled() then ak() end aegisub.progress.title(msg) end
|
|
function t_error(message,cancel) ADD({{class="label",label=message}},{"OK"},{close='OK'}) if cancel then ak() 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 addtag3(tg,txt)
|
|
no_tf=txt:gsub("\\t%b()","")
|
|
tgt=tg:match("(\\%d?%a+)[%d%-&]") if not tgt then t_error("Adding tag '"..tg.."' failed.") end
|
|
if no_tf:match("^({[^}]-)"..tgt.."[%d%-&]") then txt=txt:gsub("^({[^}]-)"..tgt.."[%d%-&][^\\}]*","%1"..tg)
|
|
elseif not txt:match("^{\\") then txt="{"..tg.."}"..txt
|
|
elseif txt:match("^{[^}]-\\t") then txt=txt:gsub("^({[^}]-)\\t","%1"..tg.."\\t")
|
|
else txt=txt:gsub("^({\\[^}]-)}","%1"..tg.."}") end
|
|
return txt
|
|
end
|
|
|
|
-- save inline tags
|
|
function inline_pos(t)
|
|
inTags={}
|
|
tl=t:len()
|
|
if tl==0 then return {} end
|
|
p=0
|
|
t1=''
|
|
repeat
|
|
seg=t:match("^(%b{})") -- try to match tags/comments
|
|
if seg then
|
|
table.insert(inTags,{n=p,t=seg})
|
|
else
|
|
seg=t:match("^([^{]+)") -- or match text
|
|
if not seg then t_error("Error: There appears to be a problem with the brackets here...\n"..t1..t,1) end
|
|
SL=re.find(seg,".")
|
|
p=p+#SL -- position of next '{' [or end]
|
|
end
|
|
t1=t1..seg
|
|
t=t:gsub("^"..esc(seg),"")
|
|
tl=t:len()
|
|
until tl==0
|
|
return inTags
|
|
end
|
|
|
|
-- rebuild inline tags
|
|
function inline_ret(t,tab)
|
|
tl=t:len()
|
|
nt=''
|
|
kill='_Z#W_' -- this is supposed to never match
|
|
for k,v in ipairs(tab) do
|
|
N=tonumber(v.n)
|
|
if N==0 then nt=nt..v.t
|
|
else
|
|
m='.'
|
|
-- match how many chars at the start
|
|
m=m:rep(N)
|
|
RS=re.find(t,m)
|
|
seg=RS[1].str
|
|
seg=re.sub(seg,'^'..kill,'')
|
|
nt=nt..seg..v.t
|
|
kill=m -- how many matched in the last round
|
|
end
|
|
end
|
|
-- the rest
|
|
seg=re.sub(t,'^'..kill,'')
|
|
nt=nt..seg
|
|
return nt
|
|
end
|
|
|
|
function retextmod(orig,text)
|
|
local v1,v2,c,t2
|
|
v1=nobrea(orig)
|
|
c=0
|
|
repeat
|
|
t2=textmod(orig,text)
|
|
v2=nobrea(text)
|
|
c=c+1
|
|
until v1==v2 or c==666
|
|
if v1~=v2 then logg("Something went wrong with the text...") logg(v1) logg(v2) end
|
|
return t2
|
|
end
|
|
|
|
function textmod(orig,text)
|
|
if text=="" then return orig end
|
|
tk={}
|
|
tg={}
|
|
text=text:gsub("{\\\\k0}","")
|
|
text=tagmerge(text)
|
|
vis=nobra(text)
|
|
ltrmatches=re.find(vis,".")
|
|
if not ltrmatches then logg("text: "..text..'\nvisible: '..vis)
|
|
logg("If you're seeing this, something really weird is happening with the re module.\nTry this again or rescan Autoload.")
|
|
end
|
|
for l=1,#ltrmatches do
|
|
table.insert(tk,ltrmatches[l].str)
|
|
end
|
|
stags=text:match(STAG) or ""
|
|
text=text:gsub(STAG,"") :gsub("{[^\\}]-}","")
|
|
orig=orig:gsub("{([^\\}]+)}",function(c) return wrap("\\\\"..c.."|||") end)
|
|
count=0
|
|
for seq in orig:gmatch("[^{]-{%*?\\[^}]-}") do
|
|
chars,as,tak=seq:match("([^{]-){(%*?)(\\[^}]-)}")
|
|
pos=re.find(chars,".")
|
|
if pos==nil then ps=0+count else ps=#pos+count end
|
|
tgl={p=ps,t=tak,a=as}
|
|
table.insert(tg,tgl)
|
|
count=ps
|
|
end
|
|
count=0
|
|
for seq in text:gmatch("[^{]-{%*?\\[^}]-}") do
|
|
chars,as,tak=seq:match("([^{]-){(%*?)(\\[^}]-)}")
|
|
pos=re.find(chars,".")
|
|
if pos==nil then ps=0+count else ps=#pos+count end
|
|
tgl={p=ps,t=tak,a=as}
|
|
table.insert(tg,tgl)
|
|
count=ps
|
|
end
|
|
newline=""
|
|
for i=1,#tk do
|
|
newline=newline..tk[i]
|
|
newt=""
|
|
for n,t in ipairs(tg) do
|
|
if t.p==i then newt=newt..t.a..t.t end
|
|
end
|
|
if newt~="" then newline=newline.."{"..as..newt.."}" end
|
|
end
|
|
newtext=stags..newline:gsub("(|||)(\\\\)","%1}{%2"):gsub("({[^}]-)\\\\([^\\}]-)|||","{%2}%1")
|
|
text=newtext:gsub("{}","")
|
|
return text
|
|
end
|
|
|
|
|
|
function duplikill(tagz)
|
|
local tags1={"blur","be","bord","shad","xbord","xshad","ybord","yshad","fs","fsp","fscx","fscy","frz","frx","fry","fax","fay"}
|
|
local tags2={"c","2c","3c","4c","1a","2a","3a","4a","alpha"}
|
|
tagz=tagz:gsub("\\t%b()",function(t) return t:gsub("\\","|") end)
|
|
for i=1,#tags1 do
|
|
tag=tags1[i]
|
|
repeat tagz,c=tagz:gsub("|"..tag.."[%d%.%-]+([^}]-)(\\"..tag.."[%d%.%-]+)","%1%2") until c==0
|
|
repeat tagz,c=tagz:gsub("\\"..tag.."[%d%.%-]+([^}]-)(\\"..tag.."[%d%.%-]+)","%2%1") until c==0
|
|
end
|
|
tagz=tagz:gsub("\\1c&","\\c&")
|
|
for i=1,#tags2 do
|
|
tag=tags2[i]
|
|
repeat tagz,c=tagz:gsub("|"..tag.."&H%x+&([^}]-)(\\"..tag.."&H%x+&)","%1%2") until c==0
|
|
repeat tagz,c=tagz:gsub("\\"..tag.."&H%x+&([^}]-)(\\"..tag.."&H%x+&)","%2%1") until c==0
|
|
end
|
|
repeat tagz,c=tagz:gsub("\\fn[^\\}]+([^}]-)(\\fn[^\\}]+)","%2%1") until c==0
|
|
repeat tagz,c=tagz:gsub("(\\[ibusq])%d(.-)(%1%d)","%2%3") until c==0
|
|
repeat tagz,c=tagz:gsub("(\\an)%d(.-)(%1%d)","%3%2") until c==0
|
|
tagz=tagz:gsub("(|i?clip%(%A-%))(.-)(\\i?clip%(%A-%))","%2%3")
|
|
:gsub("(\\i?clip%b())(.-)(\\i?clip%b())",function(a,b,c)
|
|
if a:match("m") and c:match("m") or not a:match("m") and not c:match("m") then return b..c else return a..b..c end end)
|
|
tagz=tagz:gsub("|","\\"):gsub("\\t%([^\\%)]-%)","")
|
|
return tagz
|
|
end
|
|
|
|
function colkill(tagz)
|
|
tagz=tagz:gsub("\\1c&","\\c&")
|
|
local tags2={"c","2c","3c","4c"}
|
|
for i=1,#tags2 do
|
|
tag=tags2[i]
|
|
tagz=tagz:gsub("\\"..tag.."&H%x+&([^}]-)(\\"..tag.."&H%x+&)","%2%1")
|
|
end
|
|
return tagz
|
|
end
|
|
|
|
function RGB_to_HSL(Red,Green,Blue)
|
|
R=(tonumber(Red,16)/255)
|
|
G=(tonumber(Green,16)/255)
|
|
B=(tonumber(Blue,16)/255)
|
|
|
|
Min=math.min(R,G,B)
|
|
Max=math.max(R,G,B)
|
|
del_Max=Max-Min
|
|
|
|
L=(Max+Min)/2
|
|
|
|
if del_Max==0 then H=0 S=0
|
|
else
|
|
if L<0.5 then S=del_Max/(Max+Min)
|
|
else S=del_Max/(2-Max-Min)
|
|
end
|
|
|
|
del_R=(((Max-R)/6)+(del_Max/2))/del_Max
|
|
del_G=(((Max-G)/6)+(del_Max/2))/del_Max
|
|
del_B=(((Max-B)/6)+(del_Max/2))/del_Max
|
|
|
|
if R==Max then H=del_B-del_G
|
|
elseif G==Max then H=(1/3)+del_R-del_B
|
|
elseif B==Max then H=(2/3)+del_G-del_R
|
|
end
|
|
|
|
if H<0 then H=H+1 end
|
|
if H>1 then H=H-1 end
|
|
end
|
|
return H,S,L
|
|
end
|
|
|
|
function HSL_to_RGB(H,S,L)
|
|
if S==0 then
|
|
R=L*255
|
|
G=L*255
|
|
B=L*255
|
|
else
|
|
if L<0.5 then var_2=L*(1+S)
|
|
else var_2=(L+S)-(S*L)
|
|
end
|
|
var_1=2*L-var_2
|
|
R=255*Hue_to_RGB(var_1,var_2,H+(1/3))
|
|
G=255*Hue_to_RGB(var_1,var_2,H)
|
|
B=255*Hue_to_RGB(var_1,var_2,H-(1/3))
|
|
end
|
|
return R,G,B
|
|
end
|
|
|
|
function Hue_to_RGB(v1,v2,vH)
|
|
if vH<0 then vH=vH+1 end
|
|
if vH>1 then vH=vH-1 end
|
|
if (6*vH)<1 then return(v1+(v2-v1)*6*vH) end
|
|
if (2*vH)<1 then return(v2) end
|
|
if (3*vH)<2 then return(v1+(v2-v1)*((2/3)-vH)*6) end
|
|
return(v1)
|
|
end
|
|
|
|
function HSLround(H,S,L)
|
|
if H>1 then H=H-1 end
|
|
if H<0 then H=H+1 end
|
|
if randomise and S>1 then S=1-S end
|
|
if S>1 then S=1 end
|
|
if randomise then S=math.abs(S) end
|
|
if S<0 then S=0 end
|
|
if randomise and L>1 then L=1-L end
|
|
if L>1 then L=1 end
|
|
if randomise then L=math.abs(L) end
|
|
if L<0 then L=0 end
|
|
return H,S,L
|
|
end
|
|
|
|
function brightness(klr,lvl)
|
|
klr=tonumber(klr,16)
|
|
if randomise then
|
|
rAn=math.random(klr-lvl,klr+lvl)
|
|
klr=round(rAn)
|
|
if klr<0 then klr=math.abs(klr) end
|
|
if klr>255 then klr=255-(klr-255) end
|
|
else
|
|
klr=klr+lvl
|
|
end
|
|
if klr<0 then klr=0 end
|
|
if klr<10 then klr="0"..klr else klr=tohex(klr) end
|
|
return klr
|
|
end
|
|
|
|
function tohex(num)
|
|
n1=math.floor(num/16)
|
|
n2=math.floor(num%16)
|
|
num=tohex1(n1)..tohex1(n2)
|
|
return num
|
|
end
|
|
|
|
function tohex1(num)
|
|
HEX={"1","2","3","4","5","6","7","8","9","A","B","C","D","E"}
|
|
if num<1 then num="0" elseif num>14 then num="F" else num=HEX[num] end
|
|
return num
|
|
end
|
|
|
|
function styleget(subs)
|
|
styles={}
|
|
for i=1,#subs do
|
|
if subs[i].class=="style" then
|
|
table.insert(styles,subs[i])
|
|
end
|
|
if subs[i].class=="dialogue" then break end
|
|
end
|
|
end
|
|
|
|
function stylechk(sn)
|
|
for i=1,#styles do
|
|
if sn==styles[i].name then
|
|
sr=styles[i]
|
|
if styles[i].name=="Default" then defaref=styles[i] end
|
|
break
|
|
end
|
|
end
|
|
if sr==nil then t_error("Style '"..sn.."' doesn't exist.",1) end
|
|
return sr
|
|
end
|
|
|
|
function txt_check(t1,t2,i)
|
|
if t1~=t2 then
|
|
local bad
|
|
for s=1,#badsel do
|
|
if badsel[s]==i then bad=1 end
|
|
end
|
|
if bad then
|
|
logg("Line #"..i-line0..": Operation failed, probably because of malformed tags. Undo (Ctrl+Z) and fix the line before trying again.\n")
|
|
else
|
|
logg("Line #"..i-line0..": It appears that characters have been lost or added. \n If the problem isn't obvious from the two lines below, it's probably a failure of the re module.\n Undo (Ctrl+Z) and try again (Repeat Last might work). If the problem persists, rescan Autoload Dir.\n If you keep getting the SAME strange results, then it may be a bug in Colourise.\n>> "..t1.."\n--> "..t2.."\n")
|
|
end
|
|
end
|
|
end
|
|
|
|
function re_test(letrz,visible)
|
|
local count=0
|
|
repeat
|
|
local nt=''
|
|
for l=1,#letrz do
|
|
local ltr=letrz[l].str
|
|
nt=nt..ltr
|
|
end
|
|
count=count+1
|
|
if nt~=visible then letrz=re.find(visible,".") or {} end
|
|
until nt==visible or count==100
|
|
return letrz
|
|
end
|
|
|
|
function validateCol(subs,sel)
|
|
local err
|
|
badsel={}
|
|
for z,i in ipairs(sel) do
|
|
local line=subs[i]
|
|
tx=line.text
|
|
for c in tx:gmatch("\\[1234]?c[^l\\})]+") do
|
|
if not c:match("c&H%x%x%x%x%x%x&") then logg("Line #"..i-line0..": "..c) err=1 table.insert(badsel,i) end
|
|
end
|
|
end
|
|
if err==1 then t_error("Some malformed colour tags have been found in selected lines.\nThis means the values don't match the standard format of\n&&HFFFFFF&&. Some things are likely to break.\nSee the log for a list of errors found.") end
|
|
end
|
|
|
|
function repetition()
|
|
if lastres and res.rept then res=lastres end
|
|
end
|
|
|
|
function saveconfig()
|
|
colconf="Colourise Configutation\n\n"
|
|
for key,val in ipairs(GUI) do
|
|
if val.class=="checkbox" and val.name~="save" then colconf=colconf..val.name..":"..tf(res[val.name]).."\n" end
|
|
if val.class=="dropdown" and val.name~=": Help Menu :" or val.class=="color" then colconf=colconf..val.name..":"..res[val.name].."\n" end
|
|
end
|
|
colourconfig=ADP("?user").."\\colourise.conf"
|
|
file=io.open(colourconfig,"w")
|
|
file:write(colconf)
|
|
file:close()
|
|
ADD({{class="label",label="Config Saved to:\n"..colourconfig}},{"OK"},{close='OK'})
|
|
end
|
|
|
|
function loadconfig()
|
|
colourconfig=ADP("?user").."\\colourise.conf"
|
|
file=io.open(colourconfig)
|
|
if file~=nil then
|
|
konf=file:read("*all")
|
|
io.close(file)
|
|
for key,val in ipairs(GUI) do
|
|
if val.class=="checkbox" or val.class=="dropdown" or val.class=="color" then
|
|
if konf:match(val.name) and val.name~="help" then val.value=detf(konf:match(val.name..":(.-)\n")) end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function grad_rgb(subs,sel)
|
|
cuts(subs)
|
|
validateCol(subs,sel)
|
|
res={grtype="RGB",acc=1,k1=true,k3=true}
|
|
gradient(subs,sel)
|
|
return sel
|
|
end
|
|
|
|
function grad_hsl(subs,sel)
|
|
cuts(subs)
|
|
validateCol(subs,sel)
|
|
res={grtype="HSL",acc=1,k1=true,k3=true,hueshort=true}
|
|
gradient(subs,sel)
|
|
return sel
|
|
end
|
|
|
|
if haveDepCtrl then
|
|
depRec:registerMacros({
|
|
{script_name,script_description,colourise},
|
|
{": Non-GUI macros :/Colourise: Gradient by Character, RGB","GBC RGB",grad_rgb},
|
|
{": Non-GUI macros :/Colourise: Gradient by Character, HSL","GBC HSL",grad_hsl},
|
|
},false)
|
|
else
|
|
aegisub.register_macro(script_name,script_description,colourise)
|
|
aegisub.register_macro(": Non-GUI macros :/Colourise: Gradient by Character, RGB","GBC RGB",grad_rgb)
|
|
aegisub.register_macro(": Non-GUI macros :/Colourise: Gradient by Character, HSL","GBC HSL",grad_hsl)
|
|
end |