Replacing all text after SearchFor in TextEdit

As it’s my first post, an introduction: I’m 55, live in Cheshire England, have just enough knowledge of BASIC and PHP to be dangerous and I’m embarking on my first real attempt to use AppleScript (having tiddled about with trivial tasks in the past). I also wrote a book about programming the BBC Microcomputer (so I didn’t need to tell you my age!) I’m an entrepreneur with a degree in Electronics. I’m a Technical Author. If you want to know more and have an hour to spare, see http://www.marketingtips.uk.com/aboutme.html

The Project

It’s actually a very simple project but The TextEdit “dictionary” is worse than useless, my “Applescript for Dummies” is so old that TextEdit isn’t mentioned and I really just need to get it done so I can get on with some real work. (Applescript is just too much fun. It distracts me for too many hours!)

I have two Javascripts (call them “text strings”) to insert into many many web pages so I need to automate this task. (Although there are many, I’ll only do one or two a day so the finding and selecting of web page files is not a problem).

The first string must be inserted just before
The second string must replace everything after “<body …>” (including the “>”).

So far I’ve managed to write a script to open the “Open” dialog box and load the HTML web page in TextEdit and to put its contents into a variable. Where do I go from here, please?

(I have done a forum search which produced some interesting and relevant results that have convinced me it’s possible. But this is a one-off for me. I really don’t want to spend time learning everything there is to know about AppleScript - yet.)

Martin

Here is my initial attempt to figure it out!

tell application "TextEdit"
	set visible of the front window to false
	say "locate the file named page 2"
	--speak the words
	choose file "page2"
	--open a file browser window
	open the result
	--open the selected file in TextEdit
	set visible of the front window to false
	--hide the document window
	set page_2 to (the text of document 1)
	--fill the variable page_2 with the contents of the open document
	say "locate the file named page 1"
	--speak the words
	choose file "page1"
	--open a file browser window
	open the result
	--open the selected file in TextEdit
	tell text of document 1
		say "OK so far"
		set (every word where it is "body") to page_2
		--change "body" to the contents of the variable page_2
		set (every word where it is ">") to "**"
		--change every instance of ">" to an asterisk
		count (every word where it is "hello")
		say the (result)
		say "instances of that word."
	end tell
end tell

Model: G4 tower 2x1GHz
AppleScript: 1.10.7
Browser: Safari 419.3
Operating System: Mac OS X (10.4)

Hi Martin,

Welcome. You really picked a hard app to script for your starter. Instead of scripting TextEdit you could just use AppleScript to work with text from your text document and overwrite it or use a simpler, but more powerful scriptable text editor like Tex-Edit Plus. But, here’s an example of how you might insert or delete text in TextEdit. It’s a bit complicated because you are limited in what you can do.


set string1 to "string1"
set string2 to "string2"
set ss1 to "</head>"
set ss2 to "<body"
set ss3 to ">"
tell application "TextEdit"
	activate
	set t to text of front document
	set o to offset of ss1 in t
	if o is 0 then error "String \"" & ss1 & "\" not found." -- error checking example
	-- insert text before the character
	make new text at before character o of front document with data string1
	-- get the modified text
	set t to text of front document
	set o1 to offset of ss2 in t
	set temp_text to text o1 thru -1 of t
	set o2 to offset of ss3 in temp_text
	set o to o1 + o2 - 1 -- offset of closing angle bracket in whole text
	-- overwrite (delete text after closing bracket)
	set text of front document to text 1 thru o of t
	-- insert text at end
	make new text at after character o of front document with data string2
end tell

It take quite a long time also. Maybe you should switch to just working with the text.

gl,

Hello Martin,

if your Javascripts are just plain text, there is probably no need to use TextEdit.
I guess, AppleScript’s read/write capabilities are sufficient.
A good way to do “search and replace” is using AppleScript’s text item delimiters
It would be easier to have a few example lines of the code and its replacement.

OK, I don’t need to use TextEdit - I didn’t know that AppleScript could handle text itself. I’m not sure how to post code other than Applescript but here goes. This is an example of an HTML web page:

<HTML>
<!--This file created 25/2/07 12:50 PM by Claris Home Page version 3.0-->
<HEAD>
   <TITLE>Glodark web site of miscellaneous information</TITLE>
   <META NAME=GENERATOR CONTENT="Claris Home Page 3.0">
   <X-CLARIS-WINDOW TOP=322 BOTTOM=870 LEFT=175 RIGHT=985>
   <X-CLARIS-TAGVIEW MODE=minimal>
<meta name="keywords" content="miscellaneous information"><meta name="description" content="Glodark wonderful information web site"><META name="robots" content="all"><META name="copyright" content=Glodark><META name="publisher" content=Glodark><META name="author" content=Glodark><META name="revisit-after" content="60 days">
</HEAD>
<BODY BGCOLOR="#CCFFFF">
<P><!-- miscellaneous information bf--></P>

<CENTER> 

<P><FONT COLOR="#FF0000"><TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 WIDTH=575>
   <TR>
      <TD COLSPAN=6>
         <H1><CENTER><FONT COLOR="#FF0000">GLODARK</FONT></CENTER></H1>
      </TD>
   </TR>
   <TR BGCOLOR="#EEEEEE">
      <TD COLSPAN=6>
         <P> </P> etc. etc. etc.

The following Javascript (text) has to be inserted immediately before the tag:

<!--/NOEDIT--><script language=javascript src=DropPopOver.js></script><script language=javascript>
var ie=document.all
var dom = document.getElementById
var ns4 = document.layers
var bouncelimit = 32
var direction = "up"
function initbox(){
if (!dom&&!ie&&!ns4)
return
crossobj=(dom)?document.getElementById("dropin").style : ie? document.all.dropin : document.dropin
scroll_top=(ie)? document.body.scrollTop : window.pageYOffset
crossobj.top = scroll_top - 250
crossobj.visibility=(dom||ie)? "visible" : "show"
dropstart = setInterval("dropin()", 50)
}
function dropin(){
scroll_top=(ie)? document.body.scrollTop : window.pageYOffset
if (parseInt(crossobj.top)<100+scroll_top)
crossobj.top = parseInt(crossobj.top) + 40
else{
clearInterval (dropstart)
bouncestart = setInterval("bouncein()", 50)
}
}
function bouncein(){
crossobj.top = parseInt(crossobj.top) - bouncelimit
if (bouncelimit<0)
bouncelimit+=8
bouncelimit = bouncelimit * -1
if (bouncelimit==0){
clearInterval (bouncestart)
}
}
function dismissbox(){
if (window.bouncestart) clearInterval(bouncestart)
crossobj.visibility = "hidden"
}
</script><!--/NOEDIT-->

And a similar Javascript has to replace the “>” in the line but note that this line could contain anything after “BODY” so you have to search for that first “>” after “<BODY” (not case sensitive).

I hope that’s clear.

Note: if this is a real imposition, I’m happy to pay someone to write a working script for me (if I can afford it!)

Hi Michael,

try this

set repText to "replacetext" -- only for testing: the text to replace after BODY 
set desktopPath to path to desktop as Unicode text

-- I copied your code snippets and saved them as plain text files
set html to read file (desktopPath & "html.txt")
set java to read file (desktopPath & "java.txt")

-- insert the javascript before </HEAD>
set {TID, text item delimiters} to {text item delimiters, "</HEAD>"}
set {i1, i2} to text items of html
set html to java & i2
set text item delimiters to TID
set html to i1 & html

-- replace the string after <BODY (inclusive >) with repText
set text item delimiters to "<BODY "
set {i1, i2} to text items of html
set text item delimiters to TID
set html to i1 & "<BODY " & repText & text ((offset of ">" in i2) + 1) thru -1 of i2 --*)

-- save the file as htmltest.txt on desktop
set ff to open for access file (desktopPath & "htmltest.txt") with write permission
write html to ff
close access ff

--*) if you want to omit the line break at the end of the BODY line
-- write ...((offset of ">" in i2) + 2) thru -1 of i2

set html to read file (desktopPath & "html.txt")

Sorry, it fell at the first hurdle. Can’t find the file.

Can we use something like:

choose file "html.txt"

To find the file manually then assign its contents to a variable?

yes, of course, replace the two lines with

set html to choose file with prompt "choose the html file" without invisibles
set java to choose file with prompt "choose the javascript file" without invisibles

OK, I ended up with this. It seems to work! I need to test it a bit more. I’ll be back.
(I tried your choose file method but I couldn’t get it to put the text into the variables).

set desktopPath to path to desktop as Unicode text
say "select file java one"
choose file "java1.txt"
set repText to read result
-- the text to replace after BODY 
choose file "html.txt"
set html to read result
say "select file java two"
choose file "java2.txt"
set java2 to read result
-- insert the javascript before </HEAD>
set {TID, text item delimiters} to {text item delimiters, "</HEAD>"}
set {i1, i2} to text items of html
set html to java2 & i2
set text item delimiters to TID
set html to i1 & html

-- replace the string after <BODY (inclusive >) with repText
set text item delimiters to "<BODY "
set {i1, i2} to text items of html
set text item delimiters to TID
set html to i1 & "<BODY " & repText & text ((offset of ">" in i2) + 1) thru -1 of i2 --*)

-- save the file as htmltest.txt on desktop
set ff to open for access file (desktopPath & "htmltest.txt") with write permission
write html to ff
close access ff

sorry, I forgot the read command
this works

set html to read (choose file with prompt "choose the html file" without invisibles)
set java to read (choose file with prompt "choose the javascript file" without invisibles)

Excellent, thanks! Can I embed the Javascript texts. In other words can I set a variable to each of them without having to read in the files? It won’t mess up the line breaks in the Javascript will it?

So the final result will be:


set desktopPath to path to desktop as Unicode text
-- the text to replace after BODY 
set html to read (choose file with prompt "choose the html file" without invisibles)
set java2 to "lots of lines
of javascript text
here"
set repText to "lots of lines
of javascript text
here"
-- insert the javascript before </HEAD>
set {TID, text item delimiters} to {text item delimiters, "</HEAD>"}
set {i1, i2} to text items of html
set html to java2 & i2
set text item delimiters to TID
set html to i1 & html

-- replace the string after <BODY (inclusive >) with repText
set text item delimiters to "<BODY "
set {i1, i2} to text items of html
set text item delimiters to TID
set html to i1 & "<BODY " & repText & text ((offset of ">" in i2) + 1) thru -1 of i2 --*)

-- save the file as htmltest.txt on desktop
set ff to open for access file (desktopPath & "htmltest.txt") with write permission
write html to ff
close access ff

Oh, another question: does it matter if the HTML filename has an “html” extension?

(Stefan, ich bedanke mich Ihnen! Wie darf ich Ihnen bezahlen?)

yes, I used the files only for example.
btw, you can add a line break to a string with

"teststring" & ASCII character 10

you’re welcome :slight_smile:

A bit of a tangent, but…

If you find yourself doing this sort of thing alot, and are already doing web work, you might want to look into BBEdit anyway. Since it has GREP searches built-in and can search-and-replace in entire directories of files, it excels at this sort of thing…without the scripting.

I’ve done similar tasks to what you just described on web sites large and small…quite a bit when I was heavy into web design. Was a great way to make sweeping changes to a site when the client didn’t have PHP or databse-driven functionality.

Not saying an AppleScript won’t work, mind you, just proposing a different type of solution,.

I did try BBEdit-Lite but it didn’t seem to have an AppleScript library.

Anyway, Stefan’s script works a treat and I can almost understand it. :wink:

I don’t have a need for further scripting right now, although I am very interested in manipulating text in documents.
I’m accustomed to handling $trings with “InterBase” language on the BBC Microcomputer. Applescript is a whole new world and seems very user-unfriendly by comparison. I need to get to grips with user text entry. In my day that would be “GET$”. Lord knows how Applescript does it!

Martin

Hi Martin,

It’s more than one word but it fits into one line :slight_smile:

set Get_Dollar to text returned of (display dialog "Please enter text:" default answer "Hello World")

Actually, I was proposing not scripting, since it only takes a few dialog boxes within BBEdit itself to make the functionality work, especially if you understand GREP. :wink:

(I know, I know, sacrilege!)

Also, BBEdit (dunno about the Lite version) is entirely scriptable, one of the most scriptable apps I know of (so is MailSmith for anyone who cares, made by the same company). Also rare among Mac apps these days, BBEdit is Recordable too–an invaluable tool for figuring out how to script an application.

So of course, you could Record BBEdit doing what you want, then write a script with that framework.

Besides, I’m a bit of a purist, I figure any Mac web developer really needs BBEdit in the toolkit anyway. :wink:

Even since I stopped heavy web development I find BBEdit an invaluable text manipulation tool in any case.

Okay, okay, off my soapbox…

:stuck_out_tongue:

What I’m actually doing is making a “pop-up” (actually a “Hover Advert”) for my various web sites to get people to sign up to my mailing list. There’s lots of Windoze programmes to do this but not a single one for OSX.

Now that it’s working, I’m thinking that I ought to offer it for maybe $5 a shot to other Mac users who, like me, want a hover ad but don’t know Javascript nor have time/skill to learn it.

If I’m going to do this, I need to refine it a little. For a start, I need to let them select a colour for the background. At the moment this is inserted into the HTML file as bgcolor=“#FFFF00

Is it possible, at the end of Stefan’s script, to bring up a color swatch and get the user to select a colour which is then used to replace the “#FFFF00” in the HTML file?

This would be rather neat but if it’s impossible/ difficult I guess I’ll settle for Stefan’s suggestion:

set Get_Dollar to text returned of (display dialog "Please enter color:" default answer "FFFF00")

I feel guilty about asking for help now that I’ve decided to “go commercial” but I’m happy to pay for any assistance. (FWIW I already donated $10 to this forum before started this thread - so I do believe in paying my way).

What think you? Was denken sie darauf? Qu’y pensez-vous ? ¿Qué piensa usted en ello? :slight_smile:

Oh, you can see the “hover ad” working at any of my three satcure sites. satcure.com .net .co.uk

Martin

Edit: sorry, Calvin, I did read your post! Agree in principle. I have many “tools” like “SubEthaEdit”, “Can Opener” and BBEdit Lite but I never needed the full version.

A color swatch would be nice but maybe I should crawl before I walk. Can you complete the color code insertion in this, please?

set desktopPath to path to desktop as Unicode text
say "choose file file one"
set repText to read (choose file with prompt "Choose file1" without invisibles)
-- the text to replace after <BODY...... 
say "choose file file two"
set java2 to read (choose file with prompt "Choose file2" without invisibles)
say "choose web page file"
set html to read (choose file with prompt "Choose web page file" without invisibles)
-- insert the javascript before </HEAD>
set {TID, text item delimiters} to {text item delimiters, "</HEAD>"}
set {i1, i2} to text items of html
set html to java2 & i2
set text item delimiters to TID
set html to i1 & html

-- replace the string after <BODY (inclusive >) with repText
set text item delimiters to "<BODY "
set {i1, i2} to text items of html
set text item delimiters to TID
set html to i1 & "<BODY " & repText & text ((offset of ">" in i2) + 1) thru -1 of i2 --*)
--Ask for the colour code
set Get_Dollar to text returned of (display dialog "Please enter color:" default answer "FFFF00")
-- insert the color code
set (every word where it is "#HJFRKC") to "#" & Get_Dollar
-- I don't think that is quite right!
-- save the file as newpage.htm on desktop
set ff to open for access file (desktopPath & "newpage.htm") with write permission
write html to ff
close access ff
say "saving file htmltest to your desk top"

Hi Martin,

Unfortunately the syntax of AppleScript is quite different from Interbase :wink:
AppleScript has a built-in option to choose a color.
I changed the script, to pick the color and replace the two ‘FONT COLOR=“#FF0000”’ terms
with the chosen color but not the BGCOLOR term.

set desktopPath to path to desktop as Unicode text
say "choose file file one"
set repText to read (choose file with prompt "Choose file1" without invisibles)
-- the text to replace after <BODY...... 
say "choose file file two"
set java2 to read (choose file with prompt "Choose file2" without invisibles)
say "choose web page file"
set html to read (choose file with prompt "Choose web page file" without invisibles)
-- insert the javascript before </HEAD>
set {TID, text item delimiters} to {text item delimiters, "</HEAD>"}
set {i1, i2} to text items of html
set html to java2 & i2
set text item delimiters to TID
set html to i1 & html

-- replace the string after <BODY (inclusive >) with repText
set text item delimiters to "<BODY "
set {i1, i2} to text items of html
set text item delimiters to TID
set html to i1 & "<BODY " & repText & text ((offset of ">" in i2) + 1) thru -1 of i2 --*)
set colorList to choose color
set htmlColor to ""
repeat with i in colorList
	set htmlColor to htmlColor & text -2 thru -1 of ("0" & (do shell script "perl -e 'printf(\"%X\", " & i div 256 & ")'"))
end repeat
set {TID, text item delimiters} to {text item delimiters, "\"#"}
set j to text items of html
set text item delimiters to TID
set html to item 1 of j
repeat with i from 2 to ((count j) - 1)
	set html to html & "\"#" & (htmlColor as string) & text (offset of quote in (item i of j)) thru -1 of item i of j
end repeat
set html to html & "\"#" & last item of j
set ff to open for access file (desktopPath & "newpage.htm") with write permission
write html to ff
close access ff
say "saving file htmltest to your desk top"

Notes: the technique to search and replace in AppleScript is to split the text by a given search string (the text item delimiter)
into a list of items, change the text item delimiter to the replace string an concatenate the text items again.
In the color panel, use the web palette, the calculation of the value is not “waterproof”

Thanks, Stefan, but I don’t understand how you are replacing HJFRKC in the line:

This is contained in the JS code that is inserted into the HTML page.

(I made up the “HJFRKC”. It could be anything but I wanted to minimize the risk of replacing a real color that was specified in the HTML page for something else, such as the page background color.)

Edit: I tried your script and it changes the PAGE background color! I just want to change the TABLE color, please. :slight_smile:
I apologize if I explained it badly. Vielleicht soll ich auf deutsch schreiben. :wink:

set {TID, text item delimiters} to {text item delimiters, "HJFRKC"}

BTW I think the color swatch is brilliant! You make it seem so easy. I thought it would take pages of code.