Re: Pascal scripts

post_date=2008-01-10
post_user=pixbr

Some subtitles come with a transition interval of 35mm (usually occurs after fix overlaping subtitles). Using the writing Nice Transitions by Tengo, I remade my own version that changes transitions from 35mm to 1mm.

// Cola Legendas - By Pix (adaptado do script Nice Transitions aka. NiceTrans by Tengo)
//
// Reduz as transicoes entre linhas de 35ms para 1ms (somente neste caso!)
//
// Criado por Pix em 07/01/2008

program ColaLegendas;

var
  CorGap      : Integer;
  BadGap      : Integer;
  i           : Integer;
  Count       : Integer;
  InitialTime : Integer;
  FinalTime   : Integer;
  Gap         : Integer;

begin
  BadGap     := 35;
  CorGap     := 34;

  Count := GetSubtitleCount;
  if Count < 2 then exit;

  for i := 0 to Count-2 do
  begin
    FinalTime   := GetSubtitleFinalTime(i);
    InitialTime := GetSubtitleInitialTime(i+1);

    Gap := InitialTime - FinalTime;

    if Gap = BadGap then
    begin
      InitialTime := InitialTime - CorGap;
      SetSubtitleInitialTime(i+1, InitialTime);
    end;
  end;
end.

Share

Re: Pascal scripts

post_date=2008-02-10
post_user=Buzcatcher

Greetings,
Here come two scripts that I wrote some time ago.
They add a simplistic way to check the spotting, or display Time ; evaluated in number of characters shown per second, for each line/subitle.
The first create a text file report and simply save it on the C drive, per default. Change as you see fit, perhaps even adding a input box in the script to ask where to save.
The second does the same CPS/checks, but it does two things :
- first, it pops up a message box stating an overall and simple estimation (number of subtitles which goes overboard the "industry standard" of 25CPS(*)
- then it adds, in the translation file, the exact cps for each line of which the original file goes over the cps limit. If there's already text in the translation file, it doesn't erase it, but at this info as a new line. If the translation file doesn't exist, subtitle workshop creates it on its own. So, no worries here.
(*) :  in other word over 40ms per character. This is usually considered as a maximum speed at which viewers can read the subtitles without too much discomfort, thought it's a bit fast, especiallyfor short to medium lenght subtitles (less than 40 characters, let's say). Anyway, feel free to change this max value as you see fit in the script, for exemple 17 to 23 c/ps are considered good values to polish the synchronisation)

//
//
// Made by Buzcatcher

program ShowCPS;

// ---------------------------------------------

const
  cpsreport = 'C:\cps_report.txt';
  CRLF = ''#13''#10;
  Rsep = ' | ';

var
  i, n, p : Integer;
  duration, sublength, cps : Integer;
  subtxt, report : String;
  Ms : TmemoryStream;

begin
  Ms := TmemoryStream.Create;
  n := GetSubtitleCount-1;

  for i := 0 to n do
  begin
    subtxt := GetSubtitleText(i);
    sublength := length(subtxt);
    
    p := pos(''#13''#10, subtxt);
    if (p>0) then
      sublength := sublength - 2;
               
    duration := GetSubtitleFinalTime(i) - GetSubtitleInitialTime(i);
    cps := round((sublength * 1000)/ duration);
    
  report := IntToStr(i+1) + Rsep + IntToStr(sublength) + ' Characters' + Rsep + IntToStr(duration) + ' duration(ms)' + Rsep + '==> ' + IntToStr(cps) + ' Char/sec.'
  if (cps > 25) then
    report := report + Rsep + 'SPOTTING TOO FAST'
  report := report + CRLF
  
  
  Ms.Write(report, length(report));
  
  try
        Ms.SaveToFile(cpsreport);
    except
        MsgBox('Couldn''t write to file!', '&Ok', '', '', $20);
    end;

  end;
  Ms.Free;
  MsgBox('Report saved in C:\cps_report.txt', '&Ok', '', '', $20);
end.

the second script :


// --= CPS Comment (in translation) =--
// Add info about the Readability Rythm
// of the original sub (Characters per second)
// as a comment [...] in the Translation.
// ------------------------------------
// Made by Buzcatcher - feb.2007
// [url]http://subtitle-spotting.blogspot.com/[/url]

program CPScomment;

// -------------------------------------

const
//FYI: 25cps = 40ms spotting for each char ; 20cps=50ms/char. etc.
  CPSlimit = 25;  //Change as you see fit.
  CRLF = ''#13''#10;

var
  i, j, n, pln, p1, p2 : Integer;
  duration, sublength, cps : Integer;
  subtxt, subtrans, report : String;

begin
  if not IsTranslatedloaded then
    exit;

  n := GetSubtitleCount-1;

  for i := 0 to n do
  begin
    subtxt := GetSubtitleText(i);
    sublength := length(subtxt);
    duration := GetSubtitleFinalTime(i) - GetSubtitleInitialTime(i);
    
    //pure stripped text length doesn't count the CRLF in 2 line subs
    pln := pos(''#13''#10, subtxt);
    if (pln>0) then
      sublength := sublength - 2;
    
    cps := round((sublength * 1000)/ duration);   //spotting spead.
    
    if (cps > CPSlimit) then
    begin
      // To update rather than double the cps info.
      subtrans := GetSubtitleTrans(i);
      p1 := pos('[*', subtrans);
      p2 := pos('*]', subtrans);
      while ((p1>0) and (p2>0)) do
         begin
           subtrans := copy(subtrans, p2+2, length(subtrans)-p2);
           p1 := pos('[*', subtrans);
           p2 := pos('*]', subtrans);
         end;
      SetSubtitleTrans(i, subtrans);
    
      //Adding [*xx C/sec*] in the translation text.
      report := '[*' + IntToStr(cps) + ' Car/s*]';
      subtrans := report + GetSubtitleTrans(i);
      SetSubtitleTrans(i, subtrans);
      j := j + 1;
    end;
 
  end;

  MsgBox(IntToStr(j) + ' Subtitles over ' + IntToStr(CPSlimit) + ' char/sec' + CRLF + 'Noted in Translation File', '&Ok', '', '', $20);
end.

Share

Re: Pascal scripts

post_date=2008-03-20
post_user=URUWorks

program SaveToFlashCC;

// -----------------------------------------------------------------------------

const 
  subfilename = 'SubFlashCC.xml';
  CRLF = ''#13''#10;

var
  n, i, init, final, dur: Integer;
  t: String;
  ms: TMemoryStream;
    
function IntToTime(t: Integer): String;
var 
  h, m, s: Integer;
  sh, sm, ss, sz: String;
begin   
  h := Trunc(((t/1000)/60)/60);
  t := t - h*1000*60*60;
  m := Trunc((t/1000)/60);
  t := t - m*1000*60;
  s := Trunc(t/1000);
  t := t - s*1000;

  if h < 10 then sh := '0' + IntToStr(h)
  else sh := IntToStr(h);

  if m < 10 then sm := '0' + IntToStr(m)
  else sm := IntToStr(m);

  if s < 10 then ss := '0' + IntToStr(s)
  else ss := IntToStr(s);

  if t < 10 then sz := '0' + IntToStr(t)
  else if t > 99 then sz := Copy(IntToStr(t), 1, 2)
  else sz := IntToStr(t);

  Result := sh + ':' + sm + ':' + ss + ':' + sz;  
end;

begin
  ms := TMemoryStream.Create;
  try
    // Header
    t := '<?xml version="1.0" encoding="UTF-8"?>' + CRLF +
         '<tt xml:lang="en" xmlns="http://www.w3.org/2006/04/ttaf1"  xmlns:tts="http://www.w3.org/2006/04/ttaf1#styling">' + CRLF +
         ' <head>' + CRLF +
         '  <styling>' + CRLF +
         '   <style id="1" tts:textAlign="right"/>' + CRLF +
         '   <style id="2" tts:color="transparent"/>' + CRLF +
         '   <style id="3" style="2" tts:backgroundColor="white"/>' + CRLF +
         '   <style id="4" style="2 3" tts:fontSize="20"/>' + CRLF +
         '  </styling>' + CRLF +
         ' </head>' + CRLF +
         ' <body>' + CRLF +
         '  <div xml:lang="en">' + CRLF;
    ms.Write(t, Length(t));
    // Body
    n := GetSubtitleCount;
    for i := 1 to n do
    begin
      init  := GetSubtitleInitialTime(i-1);   
      final := GetSubtitleFinalTime(i-1);
      dur   := final - init;

      t := '   <p begin="' + IntToTime(init) + '" dur="' + IntToTime(dur) + '">' + GetSubtitleText(i-1) + '</p>' + CRLF;
      ms.Write(t, Length(t));
    end;
    // Footer
    t := '  </div>' + CRLF +
         ' </body>' + CRLF +
         '</tt>';
    ms.Write(t, Length(t));
    // Save!
    try
        ms.SaveToFile(subfilename);
    except
        MsgBox('Couldn''t write to file!', '&Ok', '', '', $20);
    end;
  finally
    ms.Free;
    MsgBox('Done!', '&Ok', '', '', $20);
  end;
end.

Share

Re: Pascal scripts

post_date=2010-01-22
post_user=YJR

Hey everyone.  I just wrote up a script that solved a problem I had with the inability of the WDTV to support SSA/ASS fonts and I just wanted to share that with everyone.

Basically the WDTV displays only one line of subs at a time so often when there is karaoke or multiple conversations, the subs cut each other out and makes it incomprehensible.  This is because it seems to convert to SRT on the fly but it doesn't solve the timing overlap problem.  This semi-automatically fixes the problem by combining separate subs when their times overlap.

It works satisfactorily for the files that I've tried it on.  I'm a medical student and I have no time to optimize it more or debug it more (although it seems relatively free of bugs) so I'm just throwing this out there in case it is useful to anyone else.  This was also my first time doing anything in Pascal so forgive me for any oddities in the code.

The first script is KaraokeTag:

// Based on AddDottedLine. Add dotted line. Made by Bedazzle.

program KarokeTag;

// ---------------------------------------------

const 
 symboltoadd = '*';

var
 n: Integer;
 i: Integer;

 txt:  String;
begin
 n := GetSubtitleCount;

 for i := 0 to n-1 do
 begin
    if IsSubtitleSelected(i) then
    begin
     txt := symboltoadd + GetSubtitleText(i);
     SetSubtitleText(i, txt);
    end;
 end;
end.

This is totally copied from the script by Bedazzle.  I just changed it to add a star and also to only add it to selected subs.  The purpose of this is for you to tag your problem subs for later processing by other scripts.

After taging the problem subs.  Use sort to get everything ranked by time.  Then run the next script.

The second script is SRTfix:

// Fix subtitle time overlap in SRT.  Made by YJR
// Written for SubtitleWorkshop by YJR
// To be used with KarokeTag and KaraokeFix

program SRTfix;

// -------------------------------------

var
 i: Integer;
 n_max: Integer;
 
 start1: Integer;
 end1: Integer;
 start2: Integer;
 end2: Integer;
 
 Edited: Boolean;

 txt1: String;
 txt2: String;
 txtout: String;

begin
Edited := true;
while Edited do
begin
 Edited := false;
 n_max := GetSubtitleCount;
 for i := 0 to n_max-2 do
 begin
  start1 := GetSubtitleInitialTime(i);
  end1 := GetSubtitleFinalTime(i);
  txt1 := GetSubtitleText(i);
  start2 := GetSubtitleInitialTime(i+1);
  end2 := GetSubtitleFinalTime(i+1);
  txt2 := GetSubtitleText(i+1);  
  
  if ((end1 > start2) and (end2 > start1)) then
  begin //make sure that they're overlaping
  if (start1 = start2) then
  begin
    if (end1 = end2) then
    begin //Simply combine them
        DeleteSubtitle(i);
        DeleteSubtitle(i);  //Deleting changes numbering so this is actually i+1
        txtout := txt1 + '|' + txt2;
        InsertSubtitle(i,start1,end1,txtout,'');
        Edited := true;
    end;
    if (end1 < end2) then
    begin //Fragment off the trailing portion that is not overlapping
        DeleteSubtitle(i);
        DeleteSubtitle(i);
        InsertSubtitle(i,end1+1,end2,txt2,'');
        InsertSubtitle(i,start2,end1,txt2,'');
        InsertSubtitle(i,start1,end1,txt1,'');
        Edited := true;
    end;   
    if (end1 > end2) then
    begin //Fragment off the trailing portion that is not overlapping
        DeleteSubtitle(i);
        DeleteSubtitle(i);
        InsertSubtitle(i,end2+1,end1,txt1,'');
        InsertSubtitle(i,start2,end2,txt2,'');
        InsertSubtitle(i,start1,end2,txt1,'');
        Edited := true;
    end;   
  end;
  
  if (start1 < start2) then
  begin //Fragment off the leading portion
    DeleteSubtitle(i);
    DeleteSubtitle(i);
    InsertSubtitle(i,start2,end2,txt2,'')
    InsertSubtitle(i,start2,end1,txt1,'')
    InsertSubtitle(i,start1,start2-1,txt1,'')
    Edited := true;
  end;
    if (start1 > start2) then
  begin //Fragment off the leading portion
    DeleteSubtitle(i);
    DeleteSubtitle(i);
    InsertSubtitle(i,start1,end1,txt1,'')
    InsertSubtitle(i,start1,end2,txt2,'')
    InsertSubtitle(i,start2,start1-1,txt2,'')
    Edited := true;
  end;
 end;
 end;
 end;
end.

What this does is it combines subtitles whenever they overlap.  So for instance if the SSA specify that X is displayed from 2 to 5, and Y is displayed from 3 to 6, it'll display X from 2 to 3, XY from 3 to 5, and Y from 5 to 6.  It treats the marked subs by karaoke tags normally.

By now it should be clear that even if the conversations are displayed in this way and everything can be seen, the background text might bounce around as the foreground text is turned on and off.  Additionally, the background and foreground texts might randomly be switched in some instances.  This is why we previously labeled our problem subs with an asterisk and the next script solves these problems.

The last script is KaraokeFix:

program KaraokeFix;

// Fix Karaoke using the tags generated by KaraokeTag
// Written for SubtitleWorkshop by YJR

const 
 symboltoadd = '*';
 
var
 i: Integer;
 n_max: Integer;
 start1: Integer;
 end1: Integer;
 
 splitlocation: Integer;
 strlength: Integer;
 
 txtin: String;
 txt1: String;
 txt2: String;

 input: String;
 output: String;
 ni: Integer;
 
 begin
 n_max := GetSubtitleCount;
 for i := 0 to n_max-1 do
 begin
    txtin := GetSubtitleText(i);
    strlength := length(txtin);
    splitlocation := Pos('|',txtin);
    if splitlocation <> 0 then
    begin
        txt1 := Copy(txtin,1,splitlocation-1);
        txt2 := Copy(txtin,splitlocation+1,strlength-splitlocation);
        if txt1[1] = '*' then
        begin
            txt1 := Copy(txt1,2,length(txt1)-1);
            SetSubtitleText(i,txt1 + '|' + txt2);    
        end;
        if txt2[1] = '*' then
        begin
            txt2 := Copy(txt2,2,length(txt2)-1);
            SetSubtitleText(i,txt2 + '|' + txt1);
        end;
    end;
    if ((splitlocation = 0) and (txtin[1] = '*')) then
    begin
        SetSubtitleText(i,Copy(txtin,2,length(txtin)-1)+ '|*');
    end;
 end;
 end.

What this does is if it finds a line with an asterisk, it'll bring it to the top of the line for the subs.  This ensures that karoke stays on top.  It also places a spaceholding asterisk below marked lines that are sitting by themselves so that the position of the text is maintained as foreground speech continues so its not bouncing around all the time.

So far i've tried this with a few anime and they all seem to work fine.  I hope this helps someone enjoy their WDTV a lot more like it helped me.

Share

Re: Pascal scripts

post_date=2010-03-30
post_user=bubu

Hello,
I'm new here, I'd like to share a script I just wrote, based on Example.pas (though maybe Subtitle Workshop already offers this feature).

For each subtitle but the last, the scripts eventually trims its final time if it overlaps the initial time of the following subtitle.

(Equal values means that the two subtitles would overlap by 1 msec.)

Based on Example.pas, the script asks if confirmation is required for any trim operation (default yes).
In this case it outputs to MsgBox the number and text of the two subtitles.
Of course, it would be best if the script could select the subtitle, while also showing the following one, is this possible?

Output to MsgBox is formatted by mean of line feed characters chr(10).
Maybe in order to have OS independent code I should call some function which according to the OS writes a line terminated by LF or CR+LF to a string.
But maybe any Pascal implementation would produce the CR+LF effect when given LF (as it seems to be happening here) and there's no need to worry about it.
BTW: does Subtitle Workshop also exist for operative systems other than Windows?
Anyway, there is a commented out code line which makes no use of line feed characters (harder to read text in MsgBox).

Improvements to this script are of course more than welcome (if there isn't already some better script or the feature itself isn't already provided by Subtitle Workshop, which is quite probably the case).

// Trim_overlap_time.pas


program Trim_overlap_time;

// -----------------------------------------------------------------------------

const MB_ICONQUESTION = $00000020;

// -----------------------------------------------------------------------------

var
  // We declarate the variables that are going to be our controls
  Form : TForm;
  Pnl  : TPanel;
  Chk  : TCheckBox;
  Btn1 : TButton;
  Btn2 : TButton;

// -----------------------------------------------------------------------------

procedure Btn1Click(Sender: TObject);
var
  i               : Integer;
  loopEnd         : Integer;
  thisFinalTime    : Integer;
  nextInitialTime : Integer;
begin
  loopEnd := GetSubtitleCount-2;
  for i := 0 to loopEnd do
  begin
    thisFinalTime := GetSubtitleFinalTime(i);
    nextInitialTime := GetSubtitleInitialTime(i+1);
    if thisFinalTime >= nextInitialTime then
    begin
      if Chk.Checked then
      begin
     // with no line feed
     // case MsgBox('[ subtitle ' + IntToStr(i+1) + ':  ' + IntToStr(GetSubtitleInitialTime(i)) + '-' + IntToStr(thisFinalTime) + ' msec  "' + GetSubtitleText(i) + '" ] [ subtitle ' + IntToStr(i+2) + ':  ' + IntToStr(nextInitialTime) + '-' + IntToStr(GetSubtitleFinalTime(i+1)) + ' msec  "' + GetSubtitleText(i+1) + '" ]   Do you want to trim subtitle ' + IntToStr(i+1) + '?', '&Yes', '&No', '&Cancel', MB_ICONQUESTION) of

     // with line feeds but no square brackets
     // case MsgBox('subtitle ' + IntToStr(i+1) + ':  ' + IntToStr(GetSubtitleInitialTime(i)) + '-' + IntToStr(thisFinalTime) + ' msec  "' + GetSubtitleText(i) + '"'+chr(10)+'subtitle ' + IntToStr(i+2) + ':  ' + IntToStr(nextInitialTime) + '-' + IntToStr(GetSubtitleFinalTime(i+1)) + ' msec  "' + GetSubtitleText(i+1) + '"'+chr(10)+'Do you want to trim subtitle ' + IntToStr(i+1) + '?', '&Yes', '&No', '&Cancel', MB_ICONQUESTION) of

     // my favourite so far (it would be nice to be able to select subtitle i while showing subtitle i+1).
        case MsgBox('[ subtitle ' + IntToStr(i+1) + ':  ' + IntToStr(GetSubtitleInitialTime(i)) + '-' + IntToStr(thisFinalTime) + ' msec  "' + GetSubtitleText(i) + '" ]'+chr(10)+'[ subtitle ' + IntToStr(i+2) + ':  ' + IntToStr(nextInitialTime) + '-' + IntToStr(GetSubtitleFinalTime(i+1)) + ' msec  "' + GetSubtitleText(i+1) + '" ]'+chr(10)+'Do you want to trim subtitle ' + IntToStr(i+1) + '?', '&Yes', '&No', '&Cancel', MB_ICONQUESTION) of

          1: SetSubtitleFinalTime(i, nextInitialTime-1);
          2: ;
          3: Exit;
        end;
      end else
      begin
          SetSubtitleFinalTime(i, nextInitialTime-1);
      end;
    end;
  end;
end;

// -----------------------------------------------------------------------------


begin
  // Enable working area if no file is loaded
  // if IsOriginalLoaded = False then EnableWorkArea; // no need for this, not going to add any new subtitles to an empty work area.

  // if MsgBox('HERE WE ARE, DEBUGGING. DO YOU WANT TO CONTINUE?', '&Yes', '&Cancel', '', MB_ICONQUESTION) = 2 then Exit;

  Form := TForm.Create(Application);
  try

    Form.Font.Name   := 'Tahoma';
    Form.Font.Size   := 8;
    Form.Caption     := 'Check for overlapping subtitle timings';
    Form.BorderStyle := bsDialog;
    Form.BorderIcons := [];
    Form.Position    := poScreenCenter;
    Form.Width       := 240; // 206 in Example.pas
    Form.Height      := 107;

    // Create panel, to make the form look nicer
    Pnl        := TPanel.Create(Application);
    Pnl.Left   := 8;     // 8
    Pnl.Top    := 8;     // 8
    Pnl.Height := 35;
    Pnl.Width  := 219;   // 185
    Pnl.Parent := Form;

    // Create the "Show confirmation" checkbox
    Chk            := TCheckBox.Create(Application);
    Chk.Parent     := Pnl;
    Chk.ParentFont := True;
    Chk.Top        := 8;
    Chk.Left       := 8;
    Chk.Height     := 17;
    Chk.Width      := 169;
    Chk.Caption    := 'Confirm each trim operation';

    Chk.Checked    := True; // default confirm each operation

    // Create Ok button
    Btn1             := TButton.Create(Application);
    Btn1.Parent      := Form;
    Btn1.Default     := True;
    Btn1.Caption     := '&Ok';
    Btn1.ModalResult := mrOk;
    Btn1.OnClick     := @Btn1Click;
    Btn1.Top         := 50;
    Btn1.Left        := 8;
    Btn1.Width       := 105; // 88
    Btn1.Height      := 25;
    Btn1.Font.Style  := Btn1.Font.Style + [fsBold];

    // Create Cancel button
    Btn2             := TButton.Create(Application);
    Btn2.Parent      := Form;
    Btn2.Caption     := '&Cancel';
    Btn2.ModalResult := mrCancel;
    Btn2.Top         := 50;
    Btn2.Left        := 121; // 104
    Btn2.Width       := 105; // 88
    Btn2.Height      := 25;

    // Show the form, as modal, so that you can't use Subtitle Workshop while
    // the form is loaded.
    Form.ShowModal;


  finally
    // Free everything from memory
    Chk.Free;
    Pnl.Free;
    Btn1.Free;
    Btn2.Free;
    Form.Free;
  end;

end.

Share

Re: Pascal scripts

post_date=2010-04-02
post_user=bubu

Because of an error in a .srt file (subtitle with duration zero), I was getting a runtime error ("divide by Zero at 0.393") from one of the scripts by Buzcatcher, the one with program ShowCPS, here's a patch:

    duration := GetSubtitleFinalTime(i) - GetSubtitleInitialTime(i);
    if duration = 0
      then cps := 9999
      else cps := round((sublength * 1000)/ duration);

Share

Re: Pascal scripts

post_date=2010-09-17
post_user=steris

Frequently, when I am synchronizing a subtitle, I find easier to mark the end of each line of conversation, much easier then trying to guess the begining.
But, after marking all the final times, Subtitle Workhop does not have an easy way to set the initial time of each line to the end of the previous (as Ctrl+Shift+E, for example, which extends the lenght of the line to the begining of the next).
You have to do it by hand. So, I wrote a small Pascal Script to do this.
It extends the lenght of each selected line to the end of the previous line, leaving a gap of 1 ms.
Hope this is usefull to others, as it was for me.
Thank you.
Steris (Brazil)

// Estende tempo de inicio das linhas selecionadas
// ate o fim das anteriores.
// Made by SteriS.
program Estende_Inicio;
// ---------------------------------------------

const
  CRLF = ''#13''#10;

var
  n, i: Integer;
  final: Integer;
  ThisInitialTime: Integer;
  PrevFinalTime: Integer;
  txt: String;
begin
  if IsOriginalLoaded = False then EnableWorkArea;
  n := GetSubtitleCount;
  for i := 0 to n-1 do
    begin
      if (IsSubtitleSelected(i) = true) then
        begin
          ThisInitialTime := GetSubtitleInitialTime(i);
          PrevFinalTime := GetSubtitleFinalTime(i-1);
          SetSubtitleInitialTime(i, PrevFinalTime+1);
        end;
    end;
end.

Share

Re: Pascal scripts

post_date=2011-03-19
post_user=perelli

(*
 Split subtitles (only in translation) by priv_sec, vermi
 v3
 
 Loosely based on:
   Join and Delete subtitles (only from translation) by Bedazzle.
 What it does:
   Splits selected translations by line breaks, shifts remainder down (adding new lines if necessary).
 Example:
    Before:
        Line1: aaa|bbb|ccc (selected)
        Line2: ddd
        Line3: eee|fff|ggg (selected)
    After:
        Line1: aaa
        Line2: bbb
        Line3: ccc
        Line4: ddd
        Line5: eee
        Line6: fff
        Line7: ggg
*)
program SplitSubs;

//-----------------------------------------------------------------------------

var
    n: Integer;
    o: Integer;
    i: Integer;
    k: Integer;
    p: Integer;
    s: Integer;
    txt3: string;
    txtc: string;
    txtd: string;

begin
    if not IsTranslatedloaded then
        exit;

    i := GetSubtitleCount-1;
    while i >= 0 do
    begin
        if (IsSubtitleSelected(i)=true) then
        begin
            txtd := GetSubtitleTrans(i);
            while 1=1 do
            begin
                p := pos(''#13''#10,txtd);
                if (p<=0) then
                    break;
                p := p-1 // thx vermi!
                txt3 := copy(txtd, p+3, (length(txtd)-p)); // thx vermi!            
                txtd := copy(txtd, 0, p);
                SetSubtitleTrans(i+s,txtd); 
                txtd := txt3;
                o := GetSubtitleCount;
                s := s+1;
                for k := i+s to o do
                    if k<>o then
                    begin
                        txtc := txt3;
                        txt3 := GetSubtitleTrans(k);
                        SetSubtitleTrans(k,txtc);
                    end //if k<>n
                    else
                        if (txt3<>'- Untranslated subtitle -') then
                            if (txt3<>'') then
                                InsertSubtitle(k,GetSubtitleFinalTime(GetSubtitleCount-1)+1000, GetSubtitleFinalTime(GetSubtitleCount-1)+2000, '',txt3);
            end; // while 1
        end; // if IsSubtitleSelected
        i := i-1;
        s := 0;
    end; // while
end. // script

Share

Re: Pascal scripts

post_date=2011-03-23
post_user=perelli

// Insert subtitle (only in translation). Made by Bedazzle.
// Mod by priv_sec.

program InsertTransaSubs;

// -----------------------------------------------------------------------------

var
  n: Integer;
  i: Integer;
  j: Integer;

  txt: String;
  txt2: String;

begin
  n := GetSubtitleCount;
  for i := 0 to n-1 do
  begin
     txt := '';
     if (IsSubtitleSelected(i) = true) then
     begin
        for j := i+1 to n do
        begin
            if j<>n then
            begin
            txt2 := GetSubtitleTrans(j);
            SetSubtitleTrans(j,txt);
            txt := txt2;
            end //  if j<>n
            else
                if (txt<>'- Untranslated subtitle -') then
                    if (txt<>'') then
                        InsertSubtitle(j,GetSubtitleFinalTime(GetSubtitleCount-1)+1000, GetSubtitleFinalTime(GetSubtitleCount-1)+2000, '',txt);
        end; // for
        break;
     end; // if IsSubtitleSelected
  end; // for
end. // script

Share

Re: Pascal scripts

post_date=2011-05-04
post_user=Bedazzle

1. Plain text file can be loaded into Sw easily - just select "Plain text" in "Files of type".
2. Save is a little tricky, but can be done via custom Pascal script (read in SW manual), something like

// SaveToText. Made by Bedazzle.

program SaveToText;

// ---------------------------------------------
const crlf = ''#13''#10;

var
  n          : integer;
  i          : integer;
  txt1, txt2 : string;
  fname      : string;
  stream     : TFileStream;
  z          : string;

// ---------------------------------------------

function ReplaceCRLF(t: string; rep: string): string;
var p: integer;
begin
  n := pos(crlf, t);

  t := '#' + t + '^';
  
  result := t;
end;

// ---------------------------------------------
// main program
// ---------------------------------------------
begin
  n := GetSubtitleCount;

  fname := 'c:\boo.txt';

  stream := TFileStream.Create(fname, fmCreate);
  try
    for i := 0 to n-1 do
    begin
      txt1 := GetSubtitleText(i);
      txt2 := ReplaceCRLF(txt1, '|');
      stream.WriteBuffer(txt2, length(txt2));
      stream.WriteBuffer(crlf, 2);
    end;
  finally
    stream.Free;
  end;
end.

Share

Re: Pascal scripts

post_date=2011-05-19
post_user=perelli

(*
 Delete multiple subtitles (only from translation) by priv_sec
 v2
 
 Loosely based on:
   Delete subtitle (only from translation) by Bedazzle.
 What it does:
   Deletes selected translations, shifts remainder up.
 Example:
    Before:
        Line1: aaa (selected)
        Line2: bbb (selected)
        Line3: ccc
        Line4: ddd (selected)
        Line5: eee
    After:
        Line1: ccc
        Line2: eee
*)
program ShiftSubsMulti;

// -----------------------------------------------------------------------------

var
    i: Integer;
    k: Integer;
    
begin
    i := GetSubtitleCount-1;
    while i >= 0 do
        begin
        if (IsSubtitleSelected(i)=true) then
            for k := i to GetSubtitleCount-1 do
                begin
                SetSubtitleTrans(k,GetSubtitleTrans(k+1))
                end; // end of for, end of if
        i := i-1;
        end; // end of while
end. // end of script

Share

Re: Pascal scripts

post_date=2011-05-19
post_user=perelli

(*
 Split all subtitles (by line breaks, only in translation) by priv_sec, vermi
 
 Loosely based on:
   Join and Delete subtitles (only from translation) by Bedazzle.
 What it does:
   Splits translations by line breaks, shifts remainder down (adding new lines if necessary).
 Example:
    Before:
        Line1: aaa|bbb|ccc
        Line2: ddd
        Line3: eee|fff|ggg
    After:
        Line1: aaa
        Line2: bbb
        Line3: ccc
        Line4: ddd
        Line5: eee
        Line6: fff
        Line7: ggg
*)
program SplitAllSubs;

//-----------------------------------------------------------------------------

var
 n: Integer;
 o: Integer;
 i: Integer;
 k: Integer;
 p: Integer;
 s: Integer;
 txt3: string;
 txtc: string;
 txtd: string;

begin
 if not IsTranslatedloaded then
    exit;

 for i := 0 to n do 
    begin
        n := GetSubtitleCount-1;
        s := 0;
        txtd := GetSubtitleTrans(i);
        while 1=1 do
            begin
                p := pos(''#13''#10,txtd);
                if (p<=0) then
                    break;
                p := p-1; // thx vermi!
                txt3 := copy(txtd, p+3, (length(txtd)-p)); // thx vermi!
                SetSubtitleTrans(i+s,copy(txtd, 0, p)); 
                txtd := txt3;
                o := GetSubtitleCount;
                s := s+1;
                for k := i+s to o do
                    if k<>o then
                    begin
                        txtc := txt3;
                        txt3 := GetSubtitleTrans(k);
                        SetSubtitleTrans(k,txtc);
                    end //if k<>n
                    else
                        if (txt3<>'- Untranslated subtitle -') then
                            if (txt3<>'') then
                                InsertSubtitle(k,GetSubtitleFinalTime(GetSubtitleCount-1)+1000,GetSubtitleFinalTime(GetSubtitleCount-1)+2000, '',txt3);
            end; // while
    end; // for
end. // script

Share

Re: Pascal scripts

post_date=2011-05-21
post_user=perelli

(*
 Join and Delete multiple subtitles (only from translation) by priv_sec
 
 Based on:
   Join and Delete subtitles (only from translation) by Bedazzle, anonymous
 What it does:
   Appends selected translations to the first selected translation, shifts remainder up.
 Example:
    Before:
        Line1: aaa 
        Line2: bbb (selected)
        Line3: ccc
        Line4: ddd (selected)
        Line5: eee (selected)
    After:
        Line1: aaa 
        Line2: bbb|ddd|eee
        Line3: ccc
        
 Notes:
   Ignores selections when the first line is included.
*)
program JoinAndDeleteSubsMulti;

// -----------------------------------------------------------------------------

var
i: Integer;
c: Integer;
k: Integer;
txt1: string;
sLines: Array[1..10000] of Integer;


begin
    if not IsTranslatedloaded then
        exit;

    c := 0;
    for i := 1 to GetSubtitleCount-1 do
        if (IsSubtitleSelected(i)=true) then
        begin
            if (txt1 <> '') then // selected translations
                txt1 := txt1 + ''#13''#10 + GetSubtitleTrans(i)
            else 
                txt1 := GetSubtitleTrans(i)
            c := c+1;
            sLines[c] := i; // selected lines' numbers
        end; // end of if (IsSubtitleSelected(i)=true)
        
        if (c = 1) then // only one line selected
        begin
            sLines[2] := sLines[1]+1;
            txt1 := txt1 + ''#13''#10 + GetSubtitleTrans(sLines[2])
        end; // end of if (c = 1)
        
    if (sLines[1] > 0) then // copy joined translations to the first selected line 
        SetSubtitleTrans(sLines[1],txt1)
    
    c := 0;
    for  i := 2 to GetSubtitleCount-1 do // remove selected translations
    begin
        if (sLines[i]-c > 0) then
        begin
            for k := sLines[i]-c to GetSubtitleCount-1 do
            begin
                txt1 := GetSubtitleTrans(k+1);
                SetSubtitleTrans(k, txt1);
            end; // end for    
            c := c+1;
        end; // end if (sLines[i] > 0)
    end; // end for
end. // end of script

Share

Re: Pascal scripts

post_date=2011-05-25
post_user=perelli

(*
 Join and Delete multiple subtitles (only from translation) by priv_sec
 v2
 
 Based on:
   Join and Delete subtitles (only from translation) by Bedazzle, anonymous
 What it does:
   Appends translatiuons following selected translations to selected translations, shifts remainder up.
 Example:
    Before:
        Line1: aaa 
        Line2: bbb (selected)
        Line3: ccc
        Line4: ddd (selected)
        Line5: eee (selected)
    After:
        Line1: aaa
        Line2: bbb|ccc
        Line3: ddd|eee
*)
program JoinAndDeleteSubsMultiMod;

// -----------------------------------------------------------------------------

var
i: Integer;
c: Integer;
k: Integer;
txt1: string;
sLines: Array[1..10000] of Integer;


begin
    if not IsTranslatedloaded then
        exit;

    for i := 1 to 10000 do
        sLines[i]  := 10001;
        
    c := 0;
    for i := 0 to GetSubtitleCount-1 do
        if (IsSubtitleSelected(i)=true) then
        begin
            c := c+1;
            sLines[c] := i; // selected lines' numbers
        end; // end of if (IsSubtitleSelected(i)=true)
        
    i := GetSubtitleCount-1
    while i >= 1 do
    begin
        if (sLines[i] < 10001) then
        begin
            if ((GetSubtitleTrans(sLines[i]+1) <> '') AND (GetSubtitleTrans(sLines[i]+1) <> '- Untranslated subtitle -')) then
                SetSubtitleTrans(sLines[i], GetSubtitleTrans(sLines[i]) + ''#13''#10 + GetSubtitleTrans(sLines[i]+1));
            for k := sLines[i]+1 to GetSubtitleCount-1 do
            begin
                txt1 := GetSubtitleTrans(k+1);
                SetSubtitleTrans(k, txt1);
            end; // end for    
        end; // end if (sLines[i] > 0)
        i := i-1;
    end; // end while
end. // end of script

Share

Re: Pascal scripts

post_date=2011-05-31
post_user=perelli

(*
 Split all subtitles (by line breaks, only in translation) by priv_sec, vermi
 v4
 
 Loosely based on:
   Join and Delete subtitles (only from translation) by Bedazzle.
 What it does:
   Splits translations by line breaks, shifts remainder down (adding new lines if necessary).
 Example:
    Before:
        Line1: aaa|-bbb|-ccc
        Line2: ddd
        Line3: eee|- fff|ggg
    After:
        Line1: aaa
        Line2: bbb
        Line3: ccc
        Line4: ddd
        Line5: eee
        Line6: fff
        Line7: ggg
*)
program SplitAllSubs;

//-----------------------------------------------------------------------------

var
 n: Integer;
 o: Integer;
 i: Integer;
 k: Integer;
 p: Integer;
 s: Integer;
 txt3: string;
 txtc: string;
 txtd: string;

begin
 if not IsTranslatedloaded then
    exit;

 for i := 0 to n do 
    begin
        n := GetSubtitleCount-1;
        s := 0;
        txtd := GetSubtitleTrans(i);
        while 1=1 do
            begin
                p := pos(''#13''#10,txtd);
                if (p<=0) then
                    break;
                p := p-1; // thx vermi!
                txt3 := copy(txtd, p+3, (length(txtd)-p)); // thx vermi!            
                txtd := copy(txtd, 0, p);
                p := pos('- ',txt3)
                if (p = 1) then
                    txt3 := copy(txt3, 3, length(txt3)-2)
                p := pos('-',txt3)
                if (p = 1) then
                    txt3 := copy(txt3, 2, length(txt3)-1)            
                p := pos('- ',txtd)
                if (p = 1) then
                    txtd := copy(txtd, 3, length(txtd)-2)
                p := pos('-',txtd)
                if (p = 1) then
                    txtd := copy(txtd, 2, length(txtd)-1)
                SetSubtitleTrans(i+s,txtd); 
                txtd := txt3;
                o := GetSubtitleCount;
                s := s+1;
                for k := i+s to o do
                    if k<>o then
                    begin
                        txtc := txt3;
                        txt3 := GetSubtitleTrans(k);
                        SetSubtitleTrans(k,txtc);
                    end //if k<>n
                    else
                        if (txt3<>'- Untranslated subtitle -') then
                            if (txt3<>'') then
                                InsertSubtitle(k,GetSubtitleFinalTime(GetSubtitleCount-1)+1000,GetSubtitleFinalTime(GetSubtitleCount-1)+2000, '',txt3);
            end; // while
    end; // for
end. // script

Share

Re: Pascal scripts

post_date=2011-05-31
post_user=perelli

(*
 Split subtitles (only in translation) by priv_sec, vermi
 v4
 
 Loosely based on:
   Join and Delete subtitles (only from translation) by Bedazzle.
 What it does:
   Splits selected translations by line breaks, shifts remainder down (adding new lines if necessary).
 Example:
    Before:
        Line1: aaa|-bbb|- ccc (selected)
        Line2: ddd
        Line3: eee|fff|-ggg (selected)
    After:
        Line1: aaa
        Line2: bbb
        Line3: ccc
        Line4: ddd
        Line5: eee
        Line6: fff
        Line7: ggg
*)
program SplitSubs;

//-----------------------------------------------------------------------------

var
    n: Integer;
    o: Integer;
    i: Integer;
    k: Integer;
    p: Integer;
    s: Integer;
    txt3: string;
    txtc: string;
    txtd: string;

begin
    if not IsTranslatedloaded then
        exit;

    i := GetSubtitleCount-1;
    while i >= 0 do
    begin
        if (IsSubtitleSelected(i)=true) then
        begin
            txtd := GetSubtitleTrans(i);
            while 1=1 do
            begin
                p := pos(''#13''#10,txtd);
                if (p<=0) then
                    break;
                p := p-1 // thx vermi!
                txt3 := copy(txtd, p+3, (length(txtd)-p)); // thx vermi!            
                txtd := copy(txtd, 0, p);
                p := pos('- ',txt3)
                if (p = 1) then
                    txt3 := copy(txt3, 3, length(txt3)-2)
                p := pos('-',txt3)
                if (p = 1) then
                    txt3 := copy(txt3, 2, length(txt3)-1)            
                p := pos('- ',txtd)
                if (p = 1) then
                    txtd := copy(txtd, 3, length(txtd)-2)
                p := pos('-',txtd)
                if (p = 1) then
                    txtd := copy(txtd, 2, length(txtd)-1)
                SetSubtitleTrans(i+s,txtd); 
                txtd := txt3;
                o := GetSubtitleCount;
                s := s+1;
                for k := i+s to o do
                    if k<>o then
                    begin
                        txtc := txt3;
                        txt3 := GetSubtitleTrans(k);
                        SetSubtitleTrans(k,txtc);
                    end //if k<>n
                    else
                        if (txt3<>'- Untranslated subtitle -') then
                            if (txt3<>'') then
                                InsertSubtitle(k,GetSubtitleFinalTime(GetSubtitleCount-1)+1000,GetSubtitleFinalTime(GetSubtitleCount-1)+2000, '',txt3);
            end; // while 1
        end; // if IsSubtitleSelected
        i := i-1;
        s := 0;
    end; // while
end. // script

Share

Re: Pascal scripts

post_date=2011-05-31
post_user=perelli

(*
 Join and Delete multiple subtitles (only from translation) by priv_sec
 v3
 
 Based on:
   Join and Delete subtitles (only from translation) by Bedazzle, anonymous
 What it does:
   Appends translatiuons following selected translations to selected translations, shifts remainder up.
 Example:
    Before:
        Line1: aaa 
        Line2: bbb (selected)
        Line3: ccc
        Line4: ddd (selected)
        Line5: eee (selected)
        Line6: fff
    After:
        Line1: aaa
        Line2: - bbb|- ccc
        Line3: - ddd|- eee|- fff
*)
program JoinAndDeleteSubsMultiModDash;

// -----------------------------------------------------------------------------

var
i: Integer;
c: Integer;
k: Integer;
p: Integer;
txt1: string;
sLines: Array[1..10000] of Integer;


begin
    if not IsTranslatedloaded then
        exit;

    for i := 1 to 10000 do
        sLines[i]  := 10001;
        
    c := 0;
    for i := 0 to GetSubtitleCount-1 do
        if (IsSubtitleSelected(i)=true) then
        begin
            c := c+1;
            sLines[c] := i; // selected lines' numbers
        end; // end of if (IsSubtitleSelected(i)=true)
        
    i := GetSubtitleCount-1
    while i >= 1 do
    begin
        if (sLines[i] < 10001) then
        begin
            if ((GetSubtitleTrans(sLines[i]+1) <> '') AND (GetSubtitleTrans(sLines[i]+1) <> '- Untranslated subtitle -')) then
            begin
                txt1 := GetSubtitleTrans(sLines[i]);
                p := pos('-',txt1);
                if (p <> 1) then
                        txt1 := '- ' + txt1 
                SetSubtitleTrans(sLines[i], txt1)
                txt1 := GetSubtitleTrans(sLines[i]+1);
                p := pos('-',txt1);
                if (p <> 1) then
                        txt1 := '- ' + txt1 
                SetSubtitleTrans(sLines[i], GetSubtitleTrans(sLines[i]) + ''#13''#10 + txt1);
            end;
            for k := sLines[i]+1 to GetSubtitleCount-1 do
            begin
                txt1 := GetSubtitleTrans(k+1);
                SetSubtitleTrans(k, txt1);
            end; // end for    
        end; // end if (sLines[i] > 0)
        i := i-1;
    end; // end while
end. // end of script

Share

Re: Pascal scripts

// Add spaces after punctuation marks - ! ? ; . , 
// Made by Bedazzle, 2011.09.25

program AddSpacesAfterPunctuation;

// ---------------------------------------------
const
  CRLF = ''#13''#10;

var
  n, i : Integer;
  txt : String;

// ---------------------------------------------

function ReplaceAll(t, s, r : String): String;
var
  p : Integer;
begin
  Result := '';
  p := pos(s, t);
  while p > 0 do
  begin
    Result := Result + copy(t, 1, p-1) + r;
    t := copy(t, p+length(s), length(t)-p-length(s)+1);
    p := pos(s, t);
  end;
  Result := Result + t;
end;

// ---------------------------------------------

function TrimLines(t : String): String;
var
  p : Integer;
begin
  Result := '';
  p := pos(CRLF, t);
  while p > 0 do
  begin
    Result := Result + trim(copy(t, 1, p-1)) + CRLF;
    t := copy(t, p+length(CRLF), length(t)-p-length(CRLF)+1);
    p := pos(CRLF, t);
  end;
  Result := Result + trim(t);
end;

// ---------------------------------------------

begin
  n := GetSubtitleCount;

  for i := 0 to n-1 do
  begin
    txt := GetSubtitleText(i);

    txt := ReplaceAll(txt, '?', '? ');
    txt := ReplaceAll(txt, '!', '! ');
    txt := ReplaceAll(txt, ',', ', ');
    txt := ReplaceAll(txt, '.', '. ');
    txt := ReplaceAll(txt, ';', '; ');
    txt := ReplaceAll(txt, '. . . ', '... ');
    txt := ReplaceAll(txt, '  ', ' ');
    txt := TrimLines(txt);

    SetSubtitleText(i, txt);
  end;
end.

Share

Re: Pascal scripts

// --= CPS Comment (in translation) =--
// Add info about the Readability Rythm
// of the original sub (Characters per second)
// as a comment [...] in the Translation.
// ------------------------------------
// Made by Buzcatcher - feb.2007
// [url]http://subtitle-spotting.blogspot.com/[/url]
// improved by Bedazzle 2011.09.29

program CPScomment;

// -------------------------------------

const
  //FYI: 25cps = 40ms spotting for each char ; 20cps=50ms/char. etc.
  CPSlimit = 25;  //Change as you see fit.
  CRLF = ''#13''#10;
  
var
  i, j, n, p1, p2 : Integer;
  duration, sublength, cps : Integer;
  subtxt, subtrans : String;

// -------------------------------------

function CountCRLF(s : String): Integer;
var
  p : Integer;
begin
  Result := 0;
  p := pos(CRLF, s);
  while p > 0 do
  begin
    s := copy(s, p+length(CRLF), length(s)-p-length(CRLF)+1) ;
    p := pos(CRLF, s);
    Result := Result + 1;
  end;
end;
  
// -------------------------------------

begin
  if not IsTranslatedloaded then
    exit;

  n := GetSubtitleCount-1;
  j := 0;

  for i := 0 to n do
  begin
    subtrans := GetSubtitleTrans(i);
    subtxt := GetSubtitleText(i);

    // remove old CPS info if needed
    p1 := pos('[*', subtrans);
    p2 := pos('*]', subtrans);
    while ((p1>0) and (p2>0) and (p2>p1)) do
    begin
      subtrans := copy(subtrans, p2+2, length(subtrans)-p2);
      p1 := pos('[*', subtrans);
      p2 := pos('*]', subtrans);
    end;

    duration := GetSubtitleFinalTime(i) - GetSubtitleInitialTime(i);
    
    // text length without CRLF in multiline subs
    sublength := length(subtxt) - CountCRLF(subtxt)*length(CRLF);

    cps := round((sublength * 1000)/ duration);   //spotting speed.
    
    //Adding [*xx C/sec*] in the translation text.
    if (cps > CPSlimit) then
    begin
      subtrans := '[*' + IntToStr(cps) + ' Char/s*]' + subtrans;
      j := j+1;
    end;

    SetSubtitleTrans(i, subtrans);
  end;

  MsgBox(IntToStr(j) + ' Subtitles over ' + IntToStr(CPSlimit) + ' char/sec' + CRLF + 'Noted in Translation File', '&Ok', '', '', 0);
end.

Share

Re: Pascal scripts

post_date=2011-10-28
post_user=perelli

// Delete unnecessery spaces after dashes
// Made by Bedazzle, perelli, 2011.10.28

program DeleteSpacesAfterDashes;

// ---------------------------------------------
const
  CRLF = ''#13''#10;

var
  n, i : Integer;
  txt : String;

// ---------------------------------------------

function ReplaceAll(t, s, r : String): String;
var
  p : Integer;
begin
  Result := '';
  p := pos(s, t);
  while p > 0 do
  begin
    Result := Result + copy(t, 1, p-1) + r;
    t := copy(t, p+length(s), length(t)-p-length(s)+1);
    p := pos(s, t);
  end;
  Result := Result + t;
end;

// ---------------------------------------------

function TrimLines(t : String): String;
var
  p : Integer;
begin
  Result := '';
  p := pos(CRLF, t);
  while p > 0 do
  begin
    Result := Result + trim(copy(t, 1, p-1)) + CRLF;
    t := copy(t, p+length(CRLF), length(t)-p-length(CRLF)+1);
    p := pos(CRLF, t);
  end;
  Result := Result + trim(t);
end;

// ---------------------------------------------

begin
  n := GetSubtitleCount;

  for i := 0 to n-1 do
  begin
    txt := GetSubtitleText(i);

    txt := ReplaceAll(txt, '- ', '-');
    
    txt := TrimLines(txt);

    SetSubtitleText(i, txt);
  end;
end.

Share

Re: Pascal scripts

Bedazzle wrote:
// If there is no dot at end of subtitle, add one.
// Made by Bedazzle. 2012.07.15

program DotAtEnd;

// ---------------------------------------------

const 
    SYMBOLTOADD = '.';
    
var
    n: Integer;
    i: Integer;
    txt:  String;
    ExcludeChars: Set of Char; 
begin
    ExcludeChars := ['.', '?', '!', ',', ':', ';', '…'];

    n := GetSubtitleCount;

    if n > 0 then
        for i := 0 to n-1 do
        begin
            txt := GetSubtitleText(i);

            if not (txt[Length(txt)] in ExcludeChars) then
            begin
                txt := txt + SYMBOLTOADD;
                SetSubtitleText(i, txt);
            end;
        end;
end.


Bedazzle, this is great!!! Simple, but VERY useful!! I was wondering if you could maybe have one to solve this:
Many times, you have subtitles where you only have the FINAL ? or ! for sentences. If you are doing Spanish subtitles, like me, is it possible to have a Pascal script that will detect where those initial ¿ and ¡ should be added, and that will add them automatically? THAT would be really great...

Share