Sign in to follow this  
Followers 0
leuce

Change data in variables during loop

10 posts in this topic

#1 ·  Posted (edited)

[Multiposted to the Yahoogroup and the Forum]

G'day everyone

I wrote a script that works... once. There are two variables ($varS1 and $varT1) in the script. I'd like to script to repeat itself over and over, each time using new data in the variables.

At present I can do it in a very ugly way... I simply paste multiple instances of the script in a single file to make up a looooooooong script, and manually change the variable numbers for each iteratoin ($varS2 and $varT2, $varS3 and $varT3, etc). O, and I add the variables' contents all at the top of the script.

The script is here:

http://www.leuce.com/tempfile/FH4CAT.au3

and http://www.leuce.com/tempfile/FH4CAT.zip

The script contains detailed explanations and comments.

Ideally, I would like the script to grab data from a separate file (tab delimited, possibly), but I would be satisfied if I can find a way to make the loop and let the loop use data from already-named variable contents's from within the script.

Please can anyone tell me how to do this, or give me some pointers?

Thanks in advance

Samuel Murray

Edited by leuce

Share this post


Link to post
Share on other sites



Sorry, don't understand what you want us to do. Didn't see any loops in your code. Could you perhaps write some pseudo code that would better explain your intentions? Do you want the script to loop and search for a different word each time?


"So man has sown the wind and reaped the world. Perhaps in the next few hours there will no remembrance of the past and no hope for the future that might have been." & _"All the works of man will be consumed in the great fire after which he was created." & _"And if there is a future for man, insensitive as he is, proud and defiant in his pursuit of power, let him resolve to live it lovingly, for he knows well how to do so." & _"Then he may say once more, 'Truly the light is sweet, and what a pleasant thing it is for the eyes to see the sun.'" - The Day the Earth Caught Fire

Share this post


Link to post
Share on other sites

Didn't see any loops in your code.

The second part of the script (as indicated in the download file) must run over and over and over. I haven't written the loop code yet because I don't know how to tell the script that it should use a new set of variables every time it reruns that section of the script.

Do you want the script to loop and search for a different word each time?

Yes.

Basically, I have made a list of phrases which occur in the FreeHand document (these are the source text phrases). I want to replace each phrase in that list some some other phrase (with the translation of the phrase, the target text, in other words). I have already done the translations (in a text editor). I want the script to loop and search for a different phrase each time, and replace it with its corresponding translation.

The reason I want to be able to specify an external file with the list of phrases, is that it would enable me to give the script to other, less computer literate translators with the briefest of instructions on how to format the phrase list.

Does this make sense? Here's another explanation of what the script should do:

Waits for Macromedia to become active

Activates Find/Replace dialog

Find "This is a house".

Replace with "Dit is 'n huis."

Find "The house is old."

Replace with "Die huis is oud."

Find "I like the house."

Replace with "Ek hou van die huis."

...etc

But I don't want to type in the find and replace text manually. I want the script to grab it from an external text file, which contains:

This is a house = Dit is 'n huis.

The house is old. = Die huis is oud.

I like the house. = Ek hou van die huis.

...etc

But if it can't be an external file, then I'll be happy with data or variables (?) being declared at the top or bottom of the script itself, possibly like this:

$varS1 = "This is a house"

$varT1 = "Dit is 'n huis."

$varS2 = "The house is old."

$varT2 = "Die huis is oud."

$varS3 = "I like the house."

$varT3 = "Ek hou van die huis."

...etc

But I want to use a looping script, not a loooooooong script in which I have repeatedly copied the part that does the finding and replacing.

Does this make sense?

Thanks in advance

Samuel

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

Like the comments in the code below indicate, the text file contains the lines of text that you want to use in your script - however, different editors use different ways of marking the end of a line of text...

You might have to change this line:

$FileTextARRAY = StringSplit($FileText, @CRLF, 1)

to use

@CR

or

@LF

instead of

@CRLF

;test.txt contains text like this:
; This is line 1
; This is line 2
; This is line 3

;open the file for reading
$file1 = FileOpen("test.txt", 0)

; Check if file opened for reading OK
If $file1 = -1 Then
    MsgBox(0, "Error", "Unable to open file.")
    Exit
EndIf

;read the entire file into one variable
$FileText = FileRead("test.txt", FileGetSize("test.txt"))
;$FileText now contains text like this:
; This is line 1
; This is line 2
; This is line 3

;put the file contents into an array
$FileTextARRAY = StringSplit($FileText, @CRLF, 1)
;$FileTextARRAY now contains text like this:
; $FileTextARRAY[0] = 3 <<< the size of the array
; $FileTextARRAY[1] = This is line 1
; $FileTextARRAY[2] = This is line 2
; $FileTextARRAY[3] = This is line 3

;use the file contents in a loop
For $i = 1 To $FileTextARRAY[0]
  ;put your code here
  ;when you are ready to use the array above:
    MsgBox(0,"",$FileTextARRAY[$i])
  ;put the rest of your code here
Next
...hope this helps...

Edited code

Edited by herewasplato

[size="1"][font="Arial"].[u].[/u][/font][/size]

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

...hope this helps...

It certainly helped by making me aware of things I didn't know, and by making me fiddle for a few hours more (not solving the problem, but certainly giving my brain some exercise).

Seriously, here's the situation:

==

When I try your suggestion as-is, I get this error message:

$FileTextARRAY1 = StringSplit($FileText1, @CRLF, 1)

$FileTextARRAY1 = ^ ERROR

Error: Incorrect number of parameters in function call.

According to my AutoIt help files, StringSplit should have only two parameters, being the string and the delimiter. What did you have in mind with the "1" at the end there?

If I remove the "1" (make it only two parameters, as per the help files), the script does only one loop, and during that loop it replaces only the first character of the source file with the first character of the target file. It is as if the script thinks that there are no delimiters in the array, and that every character is a full delimited segment.

I've been doing all sorts of things with the script in an attempt to (a) get it to delimit the array correctly (at the @CRLF's) and (:lmao: to run the For...Next loop the required number of times. And yes, I'm 100% sure of the @CRLF (but I did test it with @CR and @LF, just to make sure).

This is what I have at the moment... did I add your suggested code correctly?

==

; QUICK AND DIRTY CAT TOOL FOR MACROMEDIA FREEHAND 11

$file1 = FileOpen("source.txt", 0)

$file2 = FileOpen("target.txt", 0)

If $file1 = -1 Then

MsgBox(0, "Error", "Unable to open file.")

Exit

EndIf

If $file2 = -1 Then

MsgBox(0, "Error", "Unable to open file.")

Exit

EndIf

$FileText1 = FileRead($file1, FileGetSize($file1))

$FileText2 = FileRead($file2, FileGetSize($file2))

$FileTextARRAY1 = StringSplit($FileText1, @CRLF)

$FileTextARRAY2 = StringSplit($FileText2, @CRLF)

WinWaitActive("Macromedia")

Send("^+F")

For $i = 1 To $FileTextARRAY1[0]

ControlSend("Find Text", "", "Edit1", $FileTextARRAY1[$i])

ControlSend("Find Text", "", "Edit3", $FileTextARRAY2[$i])

ControlClick("Find Text", "", "Button4")

; This If...Then...Else...EndIf deals with unexpected messages from the

; Find/Replace menu

If ControlFocus ("Macromedia FreeHand MX", "not found", "Button2") Then

ControlClick("Macromedia FreeHand MX", "not found", "Button2")

Send("{TAB 2}")

Else

Send("{TAB 2}")

ControlClick("Find Text", "", "Button6")

ControlClick("Macromedia FreeHand MX", "Finished", "Button2")

Send("{TAB 2}")

EndIf

Next

MsgBox(4096, "Done", "The script is done, mate", 10)

==

According to the helpfile, FileGetSize grabs the size of the file in bytes, but FileRead requires the size of the file in characters. For ASCII text, byte = character, but just in case the problem lay there, I made two little loops that calculated the file size in characters, and passed it as a variable FileRead:

$charcount1 = 1

While 1

$chars = FileRead($file1, 1)

$charcount1 = $charcount1 + 1

If @error = -1 Then ExitLoop

Wend

$FileText1 = FileRead($file1, $charcount2)

But that didn't solve the problem either.

==

To summarise, then, my problems are (a) the script loops only once and (;) the script seems to delimits the text file on a per-character basis instead of using the declared delimiter.

The fact that the script loops only once tells me that the script doesn't interpret

$FileTextARRAY1 = StringSplit($FileText1, @CRLF)

correctly. I can't figure out why, though :-( Or, perhaps that's not even the real problem...

Edited by leuce

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

StringSplit ( "string", "delimiters" [, flag ] )

"string" = The string to evaluate.

"delimiters" = One or more characters to use as delimiters.

flag = If flag is 1, then the entire delimiter string is needed to mark the split.

try this code:

$varARRAY = StringSplit("Sun,Mon;Tue,Wed/Thu,Fri,Sat", ",/;",0)

For $i = 1 to $varARRAY[0]
    MsgBox(0,"",$varARRAY[$i])
Next
then change the 0 to a 1 in the StringSplit line

that will make it look for ,/; all at once (all together) to make a split.

Sorry for the bum steer in that other post.

Try this code - then add your code back in.

...and yes, you put it in the correct spot...

$file1 = FileOpen("source.txt", 0)
$file2 = FileOpen("target.txt", 0)

If $file1 = -1 Then
MsgBox(0, "Error", "Unable to open file.")
Exit
EndIf

If $file2 = -1 Then
MsgBox(0, "Error", "Unable to open file.")
Exit
EndIf

$FileText1 = FileRead("source.txt", FileGetSize("source.txt"))
MsgBox(0,"$FileText1",$FileText1)
$FileText2 = FileRead("target.txt", FileGetSize("target.txt"))
MsgBox(0,"$FileText2",$FileText2)

$FileTextARRAY1 = StringSplit($FileText1, @CRLF,1)
$FileTextARRAY2 = StringSplit($FileText2, @CRLF,1)

For $i = 1 To $FileTextARRAY1[0]
MsgBox(0,"$FileTextARRAY1[" & $i & "]",$FileTextARRAY1[$i])
MsgBox(0,"$FileTextARRAY2[" & $i & "]",$FileTextARRAY2[$i])
Next
at least I had time to test this code :-)

as for FileRead and FileGetSize - should work as coded above...

Edited by herewasplato

[size="1"][font="Arial"].[u].[/u][/font][/size]

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

StringSplit ( "string", "delimiters" [, flag ] )

"string" = The string to evaluate.

"delimiters" = One or more characters to use as delimiters.

flag = If flag is 1, then the entire delimiter string is needed to mark the split.

I apologise... I just downloaded the very latest version of AutoIt and... your original suggestion works perfectly :-). This would appear to be one of the differences between some of the first versions of version 3 and the latest version.

The script seems to work, but I have to use {TAB}s instead of ControlClicks because the previous Find text and Replace text remains in the Find and Replace fields, thus causing the script to append the new segment to the old instead of replacing the old with the new. By tabbing instead of controlclicking, I "force" the FreeHand program to highlight the old contents of the field before pasting the new contents in it.

I'll look for it in the helpfiles, but perhaps you know the answer for me already: can I tell AutoIt to either (a) highlight the content of the control (if it is a text field) before sending, or (B) to replace the content of the control (if it is a text field) with the currently sent content? If so, then I can tweak my script to be sliiiightly faster (which would save a few seconds or possibly a minute or so when using it on bigger FreeHand files).

Edited by leuce

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

The script seems to work, but...

There are always, always complications, heh-heh.

1. The first complication has to do with the fact that a FreeHand file is basically a bunch of text boxes with text in them. Although one can do a Find/Replace globally on all text boxes, you have to do so while the focus is not on any single text box but on the document as a whole. Once you've done a single Find/Replace operation, the focus remains on the last accessed text box. I fixed this by adding a MouseClick off-canvas, so that the focus changes from the last text box back to the whole document.

2. The second complication is a bit more serious. To fix it, I would need to sort the source and target strings according to the length of the source strings (the longest must be at the top). The reason for this, is as follows:

You have no control over how FreeHand extracts the text. Now, suppose you have four lines of text in source.txt, namely:

Visit soon,

for this

offer will not be repeated.

Call us for this special offer.

The script will first replace all occurances of "Visit soon" with its translation, and then it will replace all occurances of "for this" with its translation, and by the time it gets to the fourth line, it will not find the text "Call us for this special offer" because the "for this" has already been changed to something else.

I can think of two ways to lick this problem (both involve the same script, though):

2.1 Let the translator sort the source.txt by line length before he starts with the translation. This would make it unnecessary to figure out how to sort the target.txt lines to match their corresponding lines in the source.txt (they will not necessarily be as long or short). The downside of this method is that all context is lost and the translator translates each phrase in isolation, which may lead to incorrect translations.

2.2 Let the translator first do the translation, and then create a tab delimited CSV file in the format SOUCE[tab]TARGET. Then sort by line length (longest lines at the top), and then convert the CSV file into two files (by using MS Excel or OOo Calc, for example), or using any CAT tool that does advanced CSV2TXT.

I need, therefore, a script that will sort the contents of source.txt (or test.txt) by line length (character count should do it, I think), with the longest lines at the top. Is this a simple thing to do? I already have a program that does it... but it is a .NET tool written for me by a kind programmer, and .NET is a very large download :-).

Once I've "prefected" everything to a degree where I think the script is useful, I'll publish the procedures here.

Can I tell AutoIt to either (a) highlight the content of the control (if it is a text field) before sending...?

This question is no longer a priority because I have found that the speed of the script depend almost entirely on the length of the text to be Find/Replace'd... so a few seconds extra on long file isn't going to do much difference. Find/Replacing 100 lines of text, file size 2 KB, takes about 4 minutes to complete at the moment (1.7 GHz machine with 400 MB RAM), which is quite sufficient. Thanks anyway. Edited by leuce

Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

Thanks... I'll definitely take a look. However, since the user has to use Excel or Calc anyway (unless I make some big changes to the operation of the script), I thought that the user might as well use the spreadsheet to do the sort. And it is dead simple. The formula is =LEN(A1) (where A1 is a cell).

The script is as good as I can get it without further testing (and I have requested FreeHand files from people on other forums/mailing lists), so here it is if anyone is interested (you must read the instructions, though).

http://www.leuce.com/tempfile/TM4FH.zip

Edited by leuce

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0