Wednesday, July 30, 2014

#1 2005-06-09 12:30:39 am

LobsterMan
Member
From: the center of the world
Registered: 2005-06-08
Posts: 77
Website

Find & Replace

I made this little script to find & replace anything in a string of text, the values passed to the handler are 1. what to find 2. what to replace it with 3. the text

Applescript:

set thefile to "Hi my mame is joe!"
findAndReplace("joe", "Mike", thefile)

on findAndReplace(tofind, toreplace, TheString)
   set ditd to text item delimiters
   set res to missing value
   set text item delimiters to tofind
   repeat with tis in text items of TheString
       if res is missing value then
           set res to tis
       else
           set res to res & toreplace & tis
       end if
   end repeat
   set text item delimiters to ditd
   return res
end findAndReplace


"I am not suffering from insanity, I'm enjoying every minute of it!"

Offline

 

#2 2005-06-09 06:12:04 am

Nigel Garvey
Moderator
From: Warwickshire, England
Registered: 2002-11-19
Posts: 3499

Re: Find & Replace

Hi, LobsterMan.

You don't need a repeat. You can simply "glue the bits back together" with another delimiter.

Applescript:

set thefile to "Hi my mame is joe!" as Unicode text
findAndReplace("joe", "Mike", thefile)

on findAndReplace(tofind, toreplace, TheString)
   set ditd to text item delimiters
   set text item delimiters to tofind
   set textItems to text items of TheString
   set text item delimiters to toreplace
   if (class of TheString is string) then
       set res to textItems as string
   else -- if (class of TheString is Unicode text) then
       set res to textItems as Unicode text
   end if
   set text item delimiters to ditd
   return res
end findAndReplace


NG

Offline

 

#3 2005-06-09 08:39:23 am

LobsterMan
Member
From: the center of the world
Registered: 2005-06-08
Posts: 77
Website

Re: Find & Replace

wow, nice. but why do you need the if unicode, can't you just write

Applescript:

set res to textItems

and applescript will try and set it to the right type ?


"I am not suffering from insanity, I'm enjoying every minute of it!"

Offline

 

#4 2005-06-09 01:05:49 pm

Nigel Garvey
Moderator
From: Warwickshire, England
Registered: 2002-11-19
Posts: 3499

Re: Find & Replace

AppleScript does get it right when it creates the list of text items. Each text item is the same class ('string' or 'Unicode text') as the original string or Unicode text from which it was derived. But we have to use either 'as string' or 'as Unicode text' to coerce the list back to a continuous text, and have to use the right one for the class of result we want.


NG

Offline

 

#5 2005-06-11 05:18:09 pm

kai
Member
From: Brighton, UK
Registered: 2005-05-28
Posts: 912

Re: Find & Replace

In the spirit of compromise, perhaps both points could be accommodated... wink

Applescript:

to switchText from t to r instead of s
   set d to text item delimiters
   set text item delimiters to s
   set t to t's text items
   set text item delimiters to r
   tell t to set t to item 1 & ({""} & rest)
   set text item delimiters to d
   t
end switchText

set theText to "Hi - my name is Joe!" as Unicode text
switchText from theText to "Mike" instead of "Joe"


kai

Offline

 

#6 2005-06-12 04:42:40 am

Nigel Garvey
Moderator
From: Warwickshire, England
Registered: 2002-11-19
Posts: 3499

Re: Find & Replace

kai wrote:

to switchText from t to r instead of s
  set d to text item delimiters
  set text item delimiters to s
  set t to t's text items
  set text item delimiters to r
  tell t to set t to item 1 & ({""} & rest)
  set text item delimiters to d
  t
end switchText

Fiendishly clever, Moriarty!  yikes  It's fast, preserves Unicode-only characters, and gives the correct result when 't' doesn't actually contain 's'. I'll use 'beginning' rather than 'item 1', to save an extra millionth of a second or so, but otherwise that's going to be my standard usage from now on. (Unless you think of something else in the meantime, of course!)

Now if there were just some way to preserve text styles....  roll


NG

Offline

 

#7 2005-06-12 05:26:46 am

LobsterMan
Member
From: the center of the world
Registered: 2005-06-08
Posts: 77
Website

Re: Find & Replace

wow! nice. i have zero experience with writing commands like that, so i don't know if its possible, but can the syntax make more sense, like

Applescript:

to switchText in t with r replacing s

or is this kind of thing not possible?

Last edited by LobsterMan (2005-06-12 05:27:58 am)


"I am not suffering from insanity, I'm enjoying every minute of it!"

Offline

 

#8 2005-06-12 07:17:37 am

Vincent
Member
From: Germany
Registered: 2004-04-06
Posts: 205

Re: Find & Replace

LobsterMan wrote:

wow! nice. i have zero experience with writing commands like that, so i don't know if its possible, but can the syntax make more sense, like

Applescript:

to switchText in t with r replacing s

or is this kind of thing not possible?

If you want to do replacements that way you will need osaxen! (Satimage's osax does it this way!)

Offline

 

#9 2005-06-12 07:24:33 am

Nigel Garvey
Moderator
From: Warwickshire, England
Registered: 2002-11-19
Posts: 3499

Re: Find & Replace

LobsterMan wrote:

wow! nice. i have zero experience with writing commands like that, so i don't know if its possible, but can the syntax make more sense, like

»»»»»»»»»»»»»»»»»
to switchText in t with r replacing s
»»»»»»»»»»»»»»»»»

or is this kind of thing not possible?

It's not possible, I'm afraid. A handler defined and called that way is said to have "labeled" (sic) parameters. (The 'switchText(t, r, s)' arrangement is called "positional" parameters.) "Labeled parameter" handlers must have at least one parameter, with one the following labels: about, above, against, apart from, around, aside from, at, below, beneath, beside, between, by, for, from, instead of, into, on, onto, out of, over, since, thru (or through), under. There can also be a parameter labelled either 'in' or 'of', but this must be the first in the list and there must be at least one other parameter, with one of the other labels. There's also a 'given' label, which must go at the end if used, and which has particular usages, one of which allows the use of 'with' or 'without' in the handler call. (See the AppleScript Language Guide, p.290 -> )

These are the only labels allowed, so you have to balance intelligibility against usefulness when deciding whether or not to use this kind of handler. Apart from 'in', 'of', and 'given', the labels are just labels and don't have any particular meanings themselves. You can use whichever ones you like and arrange them in any order. However, it's usually quite difficult to think up a combination that makes perfect sense in English.

"Labeled" parameters in a handler call don't have to be in the same order as in the handler definition. So while the first line of kai's definition is:

  to switchText from t to r instead of s

... he could, if he'd been feeling particularly eccentric, have arranged the call like this:

  switchText instead of "Joe" from theText to "Mike"

... or in any other combination, and the variables in the handler would still have been correctly assigned.


NG

Offline

 

#10 2005-06-12 07:43:36 pm

kai
Member
From: Brighton, UK
Registered: 2005-05-28
Posts: 912

Re: Find & Replace

Nigel Garvey wrote:

Fiendishly clever, Moriarty!  yikes  It's fast, preserves Unicode-only characters, and gives the correct result when 't' doesn't actually contain 's'. I'll use 'beginning' rather than 'item 1', to save an extra millionth of a second or so, but otherwise that's going to be my standard usage from now on. (Unless you think of something else in the meantime, of course!)

Thanks, Nigel. I like your idea of using 'beginning', too (so consider it nicked) - and no, don't think there's any danger of my thinking of anything else (not at this time of night, anyway)... wink

Incidentally, I must be missing the point about 't' containing 's' (but then I have loads of experience in the point-missing department). Could you enlarge, perhaps?

Now if there were just some way to preserve text styles....  roll

That's what I like so much about you, Mr G. You just never know when to stop, do you? tongue

LobsterMan wrote:

can the syntax make more sense, like:

to switchText in t with r replacing s

I won't echo Nigel's excellent explanation - but you might prefer something like this (incorporating, just for the record, the "Garvey tweak"):

Applescript:

to switchText of t from s to r
   set d to text item delimiters
   set text item delimiters to s
   set t to t's text items
   set text item delimiters to r
   tell t to set t to beginning & ({""} & rest)
   set text item delimiters to d
   t
end switchText

set theText to "Hi Mike, my name is Joe!" as Unicode text
switchText of theText from "Joe" to "Mike"
--> "Hi Mike, my name is Mike!"

Nigel Garvey wrote:

... he could, if he'd been feeling particularly eccentric, have arranged the call like this:

  switchText instead of "Joe" from theText to "Mike"

Let's leave my eccentricities out of this, shall we? Anyway, I much prefer:

  switchText to "Mike" from theText instead of "Joe" smile


kai

Offline

 

#11 2005-06-13 07:52:20 am

Nigel Garvey
Moderator
From: Warwickshire, England
Registered: 2002-11-19
Posts: 3499

Re: Find & Replace

Kai wrote:

Incidentally, I must be missing the point about 't' containing 's' (but then I have loads of experience in the point-missing department). Could you enlarge, perhaps?

It's nothing really. The point was actually about 't' not containing 's' - ie. what happens when you do something like this?:

Applescript:

set theText to "Hi - my name is Joe!" as Unicode text
switchText from theText to "Mike" instead of "fish"

It looked at first sight as though your handler might trip up on that, but in fact it doesn't.  smile  (Unlike my other attempt at a speed improvement.  sad)

to switchText of t from s to r

Ah yes. I was trying to remember the other label. The 'to' label isn't mentioned in ASLG's discussion of "Subroutines With Labeled Parameters", but it works (and in fact appears in a few examples in ASLG's "Script Objects" chapter).


NG

Offline

 

#12 2005-06-13 08:51:08 am

kai
Member
From: Brighton, UK
Registered: 2005-05-28
Posts: 912

Re: Find & Replace

Nigel Garvey wrote:

The point was actually about 't' not containing 's' - ie. what happens when you do something like this?:

Applescript:

set theText to "Hi - my name is Joe!" as Unicode text
switchText from theText to "Mike" instead of "fish"

It looked at first sight as though your handler might trip up on that, but in fact it doesn't.  smile

Ah - right. (Even though I'd tested for that, you still made me jumpy! yikes)

(Unlike my other attempt at a speed improvement.  sad)

I think I may have tried that one, too... lol

to switchText of t from s to r

Ah yes. I was trying to remember the other label. The 'to' label isn't mentioned in ASLG's discussion of "Subroutines With Labeled Parameters"...

Good thing we don't believe everything we read, right? wink


kai

Offline

 

#13 2005-06-21 05:21:32 am

Manderby
Member
Registered: 2005-06-21
Posts: 6

Re: Find & Replace

Hi everyone,

sorry to reincarnate an old thread which has obviously been discussed over and over. But I was searching for a solution of my problem and all the time I came to the example given in this thread with Mike an Joe.

My demands are simple: Replace and Find. I want to create a script that exchanges automatically all german umlaut-characters into html-code in a xcode-document. The example looked very nice but how do I get the document's text?

Nothing seemes to work. I tried several things:

Applescript:

tell application "Xcode"
   activate
   findAndReplace("ä", "ä", window 1)
   findAndReplace("ä", "ä", document of window 1)
   findAndReplace("ä", "ä", text of window 1)
   findAndReplace("ä", "ä", text document of window 1)
   findAndReplace("ä", "ä", text of document of window 1)
   findAndReplace("ä", "ä", text of text document)
   findAndReplace("ä", "ä", text document)
   findAndReplace("ä", "ä", text)
end tell

So, there are three things I want to ask:
1. How to make my code work?
2. Where will the result be placed? Will it automatically be placed within the document again or do I need to restore it as with something like

Applescript:

set text of document to findAndReplace("ä", "ä", text of text document)

3. Where are the existing AppleScripts of XCode stored so in the future, I can see for myself?

Thanks in advance!


Filed under: xcode

Offline

 

#14 2005-06-21 05:59:29 am

Macrajeev
Member
Registered: 2005-06-06
Posts: 228

Re: Find & Replace

Hi Everyone,

I am very new for applescript. I want to develop a script to find and replace in a InDesign document.

Is it possible to do it. See I want to replace "rajeev" with "kumar" and so on.

Please help me and if the root program is sufficient for me then please tell me how can I use it.
regards,
Rajeev

Offline

 

#15 2005-06-21 11:46:49 am

LobsterMan
Member
From: the center of the world
Registered: 2005-06-08
Posts: 77
Website

Re: Find & Replace

what happens when you try using one of the above scripts? what happens? can you give us a code example?


"I am not suffering from insanity, I'm enjoying every minute of it!"

Offline

 

#16 2005-06-21 11:54:10 am

Manderby
Member
Registered: 2005-06-21
Posts: 6

Re: Find & Replace

When I'm using one of the examples above, I get an error in the scripteditor: It is something like(translated into english)

"XCode receyved an error. Impossible to continue: findAndReplace"

As example, I have a file with the following content (This is german):

"Würde dieses Script funktionieren, dann hätte ich keine Fehlermeldung erhalten."

I want to run this script to get the following:

"Würde dieses Script funktionieren, dann hätte ich keine Fehlermeldung erhalten."

Offline

 

#17 2005-06-21 12:34:28 pm

jonn8
Member
From: New York
Registered: 2003-05-01
Posts: 1765
Website

Re: Find & Replace

You can use whatever routine you want for the search and replace, and this is how you target the content of the currently edited window:

Applescript:

tell application "Xcode"
   tell first responder of window 1
       set content to my snr((get content), "ä", "ä")
   end tell
end tell

on snr(the_string, search_string, replace_string)
   tell (a reference to my text item delimiters)
       set {old_tid, contents} to {contents, search_string}
       set {the_string, contents} to {the_string's text items, replace_string}
       set {the_string, contents} to {the_string as Unicode text, old_tid}
   end tell
   return the_string
end snr

Jon


Filed under: xcode

Offline

 

#18 2005-06-21 12:52:32 pm

Manderby
Member
Registered: 2005-06-21
Posts: 6

Re: Find & Replace

Great! Thank you so much!

This is a completely new field for me. Very nice of you to help me so much. I still don't understand every step of your implementation, but it works.

I will try to understand your code so that I do not need to disturb you in this forum again. wink

Greetings.

Offline

 

#19 2005-06-21 10:35:47 pm

kai
Member
From: Brighton, UK
Registered: 2005-05-28
Posts: 912

Re: Find & Replace

Manderby wrote:

When I'm using one of the examples above, I get an error in the scripteditor: It is something like(translated into english)

"XCode receyved an error. Impossible to continue: findAndReplace"

There are a few issues involved here, and a brief explanation might help...

The various handlers discussed in this thread all modify a string within AppleScript. However, for such a script to have any practical use, we really need to do something like this:

(1) bring in the text, from either a file or an application

(2) modify the text in AppleScript, using an appropriate routine/handler

(3) return the modified text to the file or application, replacing the original*.

(* Or create a 'copy' of the file/document to contain the modifications.)


Depending on the situation or application involved, the method of 'importing' and 'exporting' text may vary - but the general principles remain the same.

If there are several changes to be made to the text, it's usually faster and more convenient to get the original text, perform all the required changes in AppleScript - and then return the finally modified text - rather than repeating the get/modify/return operations. (There may be exceptions with very large gobs of text - but that's probably worth a separate discussion.)

Multiple search/replace operations could be handled using a couple of lists (obviously of equal length), one containing the search strings - the other, the replace strings. The examples below should give some idea of how all this might be put together.

Note: all the script examples that follow should include these properties and handlers:
(In an effort to reduce the length of this message, they have not been repeated in each example.)

property searchList : {"ä", "Ä", "ë", "Ë", "ï", "Ï", "ö", "Ö", "ü", "Ü", "ÿ"}
property replaceList : {"&auml", "&Auml", "&euml", "&Euml", "&iuml", "&Iuml", "&ouml", "&Ouml", "&uuml", "&Uuml", "&yuml"}

to switchText of t from s to r
    set text item delimiters to s
    set t to t's text items
    set text item delimiters to r
    tell t to set t to beginning & ({""} & rest)
    t
end switchText

to convertText(t)
    set d to text item delimiters
    considering case
        repeat with n from 1 to count searchList
            set t to switchText of t from my searchList's item n to my replaceList's item n
        end repeat
    end considering
    set text item delimiters to d
    t
end convertText

Editing note: The 'considering case' block above was added to deal with certain Unicode text issues in Tiger (raised by Nigel Garvey later in this thread).

Converting a text file:

To change a text file directly, we might do something like this (make sure you test on file copies - not originals):

Applescript:

(* insert above script properties & handlers here *)

(* stage 1: import old text *)
set currFile to choose file
set openFile to open for access currFile with write permission
set oldText to read openFile

(* stage 2: convert text *)
set newText to convertText(oldText)

(* stage 3: export new text *)
set eof openFile to 0 (* delete old text *)
write newText to openFile
close access openFile

Converting text in an application document/window:

To do something similar in, say, a TextEdit document, we could modify the script to something like this:

Applescript:

(* insert above script properties & handlers here *)

(* stage 1: import old text *)
tell application "TextEdit" to set oldText to document 1's text

(* stage 2: convert text *)
set newText to convertText(oldText)

(* stage 3: export new text *)
tell application "TextEdit" to set document 1's text to newText

However, it's quite common to get and set application objects within a single application tell block. So what happens if we try the following construct instead?

Applescript:

(* insert above script properties & handlers here *)

tell application "TextEdit"
   
   (* stage 1: import old text *)
   set oldText to document 1's text
   
   (* stage 2: convert text *)
   set newText to convertText(oldText)
   
   (* stage 3: export new text *)
   set document 1's text to newText
   
end tell

--> "TextEdit got an error: Can't continue convertText."

This is the same sort of error (number -1708) that Manderby reported earlier from XCode. Such errors occur when an AppleEvent is not handled by any handler, and so the script cannot continue. Some confusion can result when the reasons (and remedies) are not known or understood. So what's causing the problem here?

Simply this: if we need to call a subroutine from within a tell statement, we must use the reserved words 'of me' (or 'my'). This indicates that the subroutine is part of the script - and not a command that should be executed by the object of the tell statement (in this case, TextEdit).

In the above example, TextEdit just doesn't know what to do with the 'convertText(oldText)' statement - so it throws up its hands in confusion, and the event is not handled. To avoid an error, we need to change the line:

set newText to convertText(oldText)

to:

set newText to convertText(oldText) of me

-- or:

set newText to my convertText(oldText)

-- or even (by temporarily switching the object of the tell statement back to the script):

tell me to set newText to convertText(oldText)

Of course, once we're clear in our thinking about the different stages and objects, we could (if required) abbreviate the tell statement to a single line:

Applescript:

(* insert above script properties & handlers here *)

tell application "TextEdit" to tell document 1 to set its text to my convertText(its text)

As mentioned earlier, the precise syntax may vary from one application to the next - but you could probably do something similar with Xcode:

Applescript:

(* insert above script properties & handlers here *)

tell application "Xcode" to tell first responder of window 1 to set content to my convertText(get content)

Sorry about the length of this - but I hope it helps to clear up one or two things... smile

Last edited by kai (2005-07-05 09:05:45 pm)


kai

Filed under: xcode, TextEdit

Offline

 

#20 2005-06-26 07:04:54 am

Manderby
Member
Registered: 2005-06-21
Posts: 6

Re: Find & Replace

Hello kai,

sorry for the long responding time. This is amazing. Big thank you.

I haven't had the time to try your examples out but I will. I think that I can learn a lot about AppleScript by your post. The idea of switching context within a script is new to me but as soon as I got this idea it's clear why to use a "of me"-Statement. I also think that changing the text as a whole within the script rather than copying back the results each time a replacement has been done will improve the speed of the script.

I already encountered some Problems with the capital umlauts ÄÖÜ instead of äöü but I think I can solve this problem with your examples.

Again. Thanks for your help to the master of AppleScript smile

Greetings.

Offline

 

#21 2005-06-26 03:01:16 pm

Nigel Garvey
Moderator
From: Warwickshire, England
Registered: 2002-11-19
Posts: 3499

Re: Find & Replace

Manderby wrote:

I already encountered some Problems with the capital umlauts Ä…Ü instead of äöü but I think I can solve this problem with your examples.

I discovered last night, while tracking down an elusive bug in something I was doing, that text item delimiters are now (in Tiger) governed by 'considering' and 'ignoring' states - at least, when the main text is Unicode text. In other words, they're case-insensitive unless you specify otherwise. This doesn't seem to be the case with plain text, where TID's still behave exclusively case-sensitively on my machine.

The 'offset' command is similarly ruled by 'considering' and 'ignoring', but regardless of the text type.

Applescript:

considering case
   set newText to convertText(oldText)
end considering


NG

Offline

 

#22 2005-06-26 04:14:39 pm

jonn8
Member
From: New York
Registered: 2003-05-01
Posts: 1765
Website

Re: Find & Replace

I get the same behavior on my 10.4.1 machine:

Applescript:

set the_string to "A String" as Unicode text
set search_string to "a" as Unicode text
set replace_string to "b" as Unicode text
set the_string to my snr(the_string, search_string, replace_string)
-->"b String"

set the_string to "A String" as string
set search_string to "a" as string
set replace_string to "b" as string
set the_string to my snr(the_string, search_string, replace_string)
-->"A String"

on snr(the_string, search_string, replace_string)
   tell (a reference to my text item delimiters)
       set {old_tid, contents} to {contents, search_string}
       set {the_string, contents} to {the_string's text items, replace_string}
       set {the_string, contents} to {the_string as Unicode text, old_tid}
   end tell
   return the_string
end snr

I consider this a bug.

Jon

Offline

 

#23 2005-06-27 03:17:18 am

Nigel Garvey
Moderator
From: Warwickshire, England
Registered: 2002-11-19
Posts: 3499

Re: Find & Replace

Thanks for the confirmation, Jon. I agree about it being a bug - even if it might turn out to be intentional.

The talk is that the various forms of class 'string' are now either deprecated or not recommended, which may explain why no-one's bothered to update TID handling in their respect. But a lot of scripts are going to break now that delimiters are case-insensitive by default; and with a large number of existing scripters still unconsciously assuming that TIDs are sensitive to everything, and with Script Editor still compiling text as strings, there's a potential for a lot of head-banging as people try to sort out the problems!


NG

Offline

 

#24 2005-07-02 05:19:25 pm

Manderby
Member
Registered: 2005-06-21
Posts: 6

Re: Find & Replace

Speaking of bugs...

When I have a file which is saved (no dot in the red close-button) and I run this script and there are some changes, the program does not recognizes this as a change (no dot) and ergo does not shows a "save before close Window"-Message as soon as I close the window.

I found this after changing about 200 old files. Now I know that I can do the work again, beacause I didn't save files that didn't show the change-dot.

sad

PS: Maybe this error is new on Tiger.

Offline

 

#25 2005-07-02 06:55:43 pm

kai
Member
From: Brighton, UK
Registered: 2005-05-28
Posts: 912

Re: Find & Replace

Manderby wrote:

Speaking of bugs...

When I have a file which is saved (no dot in the red close-button) and I run this script and there are some changes, the program does not recognizes this as a change (no dot) and ergo does not shows a "save before close Window"-Message as soon as I close the window.

I found this after changing about 200 old files. Now I know that I can do the work again, beacause I didn't save files that didn't show the change-dot.

sad

PS: Maybe this error is new on Tiger.

I'm afraid that behaviour's been around for a while, Manderby. However, it's possible to persuade some apps that a document has actually been changed - even though it may still not show a changed dot in its red 'close' button.

With TextEdit, for example, try something like this:

Applescript:

tell application "TextEdit" to tell document 1
   set its text to "new text" (* or make other changes *)
   set modified to true
   close
end tell


kai

Filed under: TextEdit

Offline

 

Board footer

Powered by FluxBB

[ Generated in 0.058 seconds, 10 queries executed ]

RSS (new topics) RSS (active topics)