Need script to convert time in seconds to h:m:s:cs timestamp

Help with writing and running scripts

Need script to convert time in seconds to h:m:s:cs timestamp

Postby Zababa » Fri Jan 25, 2008 10:13 am

It would be really nice if you could write me a script. I am not good at programming and don't know java.

I have plenty of text files like the attached one (view here, UTF-8 ).

The point of interest for the script is all the lines containing a value of seconds (a number with one decimal digit). The lines can be found easily because they all begin with "\ELANBegin" or "\ELANEnd". Here is an excerpt:

\ref NA071112-01_E.092
\cfn
\ELANBegin 268.1
\ELANEnd 271.2
\PAUSE 0.8
\ELANParticipant A


What the script shall do is to convert the highlighted number which represents seconds to a timestamp of the format hh:mm:ss:cs (i.e. hours:minutes:seconds:centiseconds)

for 268.1 the result would be 00:04:28:10
for 271.2 it would be 00:04:31:20

This result has to appear in round brackets after the decimal number. For the excerpt, the result would be

\ref NA071112-01_E.092
\cfn
\ELANBegin 268.1 (00:04:28:10)
\ELANEnd 271.2 (00:04:31:20)
\PAUSE 0.8
\ELANParticipant A
Attachments
na071112-01_e_in_progress.zip
encoded in UTF-8
(12.59 KiB) Downloaded 216 times
User avatar
Zababa
Basic User
Basic User
 
Posts: 23
Joined: Wed Oct 03, 2007 11:00 pm
Location: Leipzig

Re: Need script to convert time in seconds to h:m:s:cs times

Postby Zababa » Sun Jan 27, 2008 12:41 am

I tried to write the script myself. (My very first JavaScript. I used parts of Mofi's script here.)

The preliminary result is this:

Code: Select all
// Define working environment.
UltraEdit.insertMode();
UltraEdit.columnModeOff();
UltraEdit.activeDocument.hexOff();
UltraEdit.ueReOn();

// Make sure last line of the file has a line termination.
UltraEdit.document[1].bottom();
if (UltraEdit.document[1].isColNumGt(1)) UltraEdit.document[1].insertLine();
UltraEdit.document[1].top();

// Define needed variables.
var decSec;  // Seconds in decimal format
var cs // centiseconds
var s // seconds
var m // minutes
var h // hours
var regExpFind = "[0-9]+[.][0-9]"; //will search a decimal number.

// Define the needed search and replace properties.
UltraEdit.document[1].findReplace.matchWord=false;
UltraEdit.document[1].findReplace.replaceAll=false;
UltraEdit.document[1].findReplace.searchDown=true;
UltraEdit.document[1].findReplace.matchCase=false;
UltraEdit.document[1].findReplace.preserveCase=false;
UltraEdit.document[1].findReplace.regExp=true;
UltraEdit.document[1].findReplace.replaceInAllOpen=false;
UltraEdit.document[1].findReplace.selectText=false;


// look for values of seconds till the end of file is reached
while (!UltraEdit.document[1].isEof())
{
// Find number in lines beginning with "\ELANBegin" or "ELANEnd"
   UltraEdit.document[1].findReplace.find("\ELAN[BE]");
   if (UltraEdit.document[1].isFound())
   {
      UltraEdit.document[1].key("HOME");
      UltraEdit.document[1].findReplace.find(regExpFind);

      // Read value
         decSec = Number(UltraEdit.document[1].selection);

      // Calculate centiseconds
         cs = (decSec % 1) * 100
         cs = cs.toFixed(0);

      // Calculate seconds
         s = (decSec - (cs / 100)) % 60;

      // Calculate minutes
         m = ((decSec - cs/100 - s) / 60) % 60;

      // Calculate hours
         h = ((decSec - cs/100 - s - m*60) / 3600) % 24

      // Convert values into text with leading zero
         if (cs < 10) {cs="0" + String(cs);} else {cs=String(cs);}
         if (s < 10) {s="0" + String(s);} else {s=String(s);}
         if (m < 10) {m="0" + String(m);} else {m=String(m);}
         if (h < 10) {h="0" + String(h);} else {h=String(h);}

      // write the timestamp at the end of the current line
         UltraEdit.document[1].key("END");
         UltraEdit.document[1].write(" (" + h + ":" + m + ":" + s + ":" + cs +")");
         UltraEdit.document[1].key("DOWN ARROW");
         UltraEdit.document[1].key("HOME");
      }
      else {UltraEdit.document[1].key("DOWN ARROW");}

}


But I got angry, because it only works with ASCII encoded files. My source files are in UTF-8. When I let run the script on a UTF-8 file, instead of number in the timestamp I get (NaN:NaN:NaN:NaN) and the while loop won't never end.

Does this mean that UE has problems reading the selection of an UTF-8 file as a number and save it to a variable?

Why does the while loop never end?
User avatar
Zababa
Basic User
Basic User
 
Posts: 23
Joined: Wed Oct 03, 2007 11:00 pm
Location: Leipzig

Re: Need script to convert time in seconds to h:m:s:cs times

Postby Zababa » Sun Jan 27, 2008 2:13 am

Until now I have found a dirty roundabout which I don't like at all. And which still has some bugs.

This script finds the number in the UTF-8 file, copies it to a new ASCII file, selects it there and read the value from the ASCII file.

But still I can't get out of the while loop )-: why?

Code: Select all
// Define working environment.
UltraEdit.insertMode();
UltraEdit.columnModeOff();
UltraEdit.activeDocument.hexOff();
UltraEdit.ueReOn();

// Make sure last line of the file has a line termination.
UltraEdit.document[1].bottom();
if (UltraEdit.document[1].isColNumGt(1)) UltraEdit.document[1].insertLine();
UltraEdit.document[1].top();

// Define needed variables.
var decSec;  // Seconds in decimal format
var cs // centiseconds
var s // seconds
var m // minutes
var h // hours
var regExpFind = "[0-9]+[.][0-9]"; //will search a decimal number.

// Define the needed search and replace properties.
UltraEdit.document[1].findReplace.matchWord=false;
UltraEdit.document[1].findReplace.replaceAll=false;
UltraEdit.document[1].findReplace.searchDown=true;
UltraEdit.document[1].findReplace.matchCase=false;
UltraEdit.document[1].findReplace.preserveCase=false;
UltraEdit.document[1].findReplace.regExp=true;
UltraEdit.document[1].findReplace.replaceInAllOpen=false;
UltraEdit.document[1].findReplace.selectText=false;


// help with unicode. copy values to a separate ASCII file
UltraEdit.newFile();

// look for values of seconds till the end of file is reached
while (!UltraEdit.document[1].isEof()) {

// Find number in lines beginning with "\ELAN"
   UltraEdit.document[1].findReplace.find("\ELAN[BE]");
   if (UltraEdit.document[1].isFound())
   {
      UltraEdit.document[1].key("HOME");
      UltraEdit.document[1].findReplace.find(regExpFind);

      // Read value
        UltraEdit.selectClipboard(0);
         UltraEdit.document[1].copy(0);
         UltraEdit.document[2].paste(0);
         UltraEdit.document[2].selectAll();
         decSec = Number(UltraEdit.document[2].selection);

      // Calculate centiseconds
         cs = (decSec % 1) * 100
         cs = cs.toFixed(0);

      // Calculate seconds
         s = (decSec - (cs / 100)) % 60;

      // Calculate minutes
         m = ((decSec - cs/100 - s) / 60) % 60;

      // Calculate hours
         h = ((decSec - cs/100 - s - m*60) / 3600) % 24

      // Convert values into text wit leading zero
         if (cs < 10) {cs="0" + String(cs);} else {cs=String(cs);}
         if (s < 10) {s="0" + String(s);} else {s=String(s);}
         if (m < 10) {m="0" + String(m);} else {m=String(m);}
         if (h < 10) {h="0" + String(h);} else {h=String(h);}

      // write the timestamp at the end of the current line
         UltraEdit.document[1].key("END");
         UltraEdit.document[1].write(" (" + h + ":" + m + ":" + s + ":" + cs +")");
         UltraEdit.document[1].key("DOWN ARROW");
         UltraEdit.document[1].key("HOME");
      }
      else {UltraEdit.document[1].key("DOWN ARROW");}

}


Why can't UE read the number from UTF-8 file? AFAIK numbers are encoded exactly the same way like in ASCII.
User avatar
Zababa
Basic User
Basic User
 
Posts: 23
Joined: Wed Oct 03, 2007 11:00 pm
Location: Leipzig

Re: Need script to convert time in seconds to h:m:s:cs times

Postby Mofi » Sun Jan 27, 2008 10:51 am

You have done a quite good job for your first JavaScript. Some hints:

  • Every backslash in a JavaScript string must be escaped with an additional backslash.
  • When running a macro or script a search never continues from other end of the file. Therefore if a string of interest is not found anymore this is the ideal condition to break a loop. The end of file condition is only good when the script by need moves the cursor in the file and it really reaches the end of the file.
    In your last script the end of file should be also reached but that could take a long time because you have moved the cursor down only by 1 line whenever the search string was not found anymore.
I have made some further improvements. The script can be executed now independent on the number of open files.
The function getActiveDocumentIndex was copied from topic Get Active Document's Index.

Code: Select all
// Define working environment.
UltraEdit.insertMode();
UltraEdit.columnModeOff();
UltraEdit.activeDocument.hexOff();
UltraEdit.ueReOn();
UltraEdit.activeDocument.top();

// Define needed variables.
var decSec;  // Seconds in decimal format
var cs;      // centiseconds
var s;       // seconds
var m;       // minutes
var h;       // hours
var regExpFind = "[0-9]+[.][0-9]"; //will search a decimal number.

/* Find the tab index of the active document */
function getActiveDocumentIndex () {
   var tabindex = -1; /* start value */

   for (var i = 0; i < UltraEdit.document.length; i++)
   {
      if (UltraEdit.activeDocument.path==UltraEdit.document[i].path) {
         tabindex = i;
         break;
      }
   }
   return tabindex;
}

// Use user clipboard 9 during script execution.
UltraEdit.selectClipboard(9);
// Help with unicode. Copy values to a separate ASCII file.
var ActiveFile = getActiveDocumentIndex();
UltraEdit.newFile();
var TempFile = UltraEdit.document.length - 1;
UltraEdit.document[TempFile].unicodeToASCII();
UltraEdit.document[ActiveFile].setActive();

// Define the needed search and replace properties.
UltraEdit.activeDocument.findReplace.matchWord=false;
UltraEdit.activeDocument.findReplace.replaceAll=false;
UltraEdit.activeDocument.findReplace.searchDown=true;
UltraEdit.activeDocument.findReplace.matchCase=false;
UltraEdit.activeDocument.findReplace.preserveCase=false;
UltraEdit.activeDocument.findReplace.regExp=true;
UltraEdit.activeDocument.findReplace.replaceInAllOpen=false;
UltraEdit.activeDocument.findReplace.selectText=false;

// Look for values of seconds till not seconds are found anymore.
while (1) {

// Find number in lines beginning with "\ELAN"
   UltraEdit.activeDocument.findReplace.find("\\ELAN[BE]");
   if (UltraEdit.activeDocument.isNotFound()) break;

   UltraEdit.activeDocument.findReplace.find(regExpFind);

// Read value
   UltraEdit.activeDocument.copy();
   UltraEdit.document[TempFile].paste();
   UltraEdit.document[TempFile].selectAll();
   decSec = Number(UltraEdit.document[TempFile].selection);
   UltraEdit.document[TempFile].deleteText();

// Calculate centiseconds
   cs = (decSec % 1) * 100
   cs = cs.toFixed();

// Calculate seconds
   s = (decSec - (cs / 100)) % 60;

// Calculate minutes
   m = ((decSec - cs/100 - s) / 60) % 60;

// Calculate hours
   h = ((decSec - cs/100 - s - m*60) / 3600) % 24

// Convert values into text wit leading zero
   if (cs < 10) {cs="0" + String(cs);} else {cs=String(cs);}
   if (s < 10) {s="0" + String(s);} else {s=String(s);}
   if (m < 10) {m="0" + String(m);} else {m=String(m);}
   if (h < 10) {h="0" + String(h);} else {h=String(h);}

// write the timestamp at the end of the current line
   UltraEdit.activeDocument.key("END");
   UltraEdit.activeDocument.write(" (" + h + ":" + m + ":" + s + ":" + cs +")");
}

// Restore default working environment.
UltraEdit.clearClipboard();
UltraEdit.selectClipboard(0);
UltraEdit.closeFile(UltraEdit.document[TempFile].path,2);
UltraEdit.activeDocument.top();


Zababa wrote:Why can't UE read the number from UTF-8 file? AFAIK numbers are encoded exactly the same way like in ASCII.


Because UTF-8 is also a type of Unicode for editing the file must be temporarily converted to UTF-16 LE. This conversion from UTF-8 to UTF-16 LE on file open and back to UTF-8 on file save is done automatically in the background. But that means also that for example 123 is internally while running a script encoded as 31 00 32 00 33 00. A workaround would be to disable the UTF-8 detection before opening the UTF-8 file and running the script to open the UTF-8 file in ASCII/ANSI mode.
User avatar
Mofi
Grand Master
Grand Master
 
Posts: 4055
Joined: Thu Jul 29, 2004 11:00 pm
Location: Vienna

Re: Need script to convert time in seconds to h:m:s:cs times

Postby Zababa » Sun Jan 27, 2008 12:02 pm

Thank you, Mofi. Through this and your help I learned a lot about scripting. It is not that bad and complicated as I thought, after all.

Now I just look forward to a time when the computing will agree to adopt UTF-32 as a world-wide encoding standard.
User avatar
Zababa
Basic User
Basic User
 
Posts: 23
Joined: Wed Oct 03, 2007 11:00 pm
Location: Leipzig


Return to Scripts