How can I Applescript a "Find and Replace With"?

How can I Applescript a “Find and Replace With”?

I find myself importing a majority articles from the same small set of websites, and then repeatly deleting the exact same text from each page, such as

"Advertisement

Advertisement"

I’d like to be able to have a sequence of scripted search and replaces to run on the text from each particular site. I did manage to do this in plain text by grabbing all the text in a DTP rich-text, doing a search and replace within Applescript (using the SATimage OSAX) and then replacing the text with my modified version, but this strips out all formatting and images. Less than ideal!

So it would be very helpful if this could be done on the currently selected document(s) by calling DTP’s own Find and Replace With feature from Applescript.

Double Bonus Points for allowing regular expressions. Consider this a feature request if it’s not already possible.

Assuming the document is visible in the frontmost window, then this script replaces “Test” with “Success” (whole words only).


tell application "DEVONthink Pro"
	set findString to "Test"
	set replacementString to "Success"
	tell text of think window 1
		set every word where it is findString to replacementString
	end tell
end tell

Thanks, but I’m after string-based subtitution by script rather than word subtitution.

You’re probably going to need the UNIX app , which can be called from an AppleScript using do shell script. It uses regular expressions, which means that anything you can imagine can be searched for and replaced.

regexp.info/

Enjoy.

This seems to work for me, at least most of the time. The problem is that apple needs to make it so that do shell script actually fully quotes out all characters and can support something like a true unix input stream. As it stands, everything goes through an icky shell parser that means that you have to hide the vertical bar (pipe) and the single quote (at the very least) from do shell script. I sometimes wish devonthink would just build this in, and allow a perl command to be executed within its applescript context. This is how Nisuswriter deals with the whole issue of scripting regexp replacements from applescript. But improbably, apple still hasn’t made it very easy to draw on shell commands from applescript, and so you have to do the handling before sending it off to the shell.

I say that all because though this subroutine has worked pretty well for me, I can easily imagine that there are shell operators that I haven’t screened out yet. If you find any, please post them here, and we’ll try to make the routine better.

cheers,

erico



on perlreplace(inputstring, targetstring, replacementstring)
	
	set inputstring to my replace_chars(inputstring, (ASCII character 194), "<br>")
	set inputstring to my replace_chars(inputstring, "|", "+vertical-bar+")
	set inputstring to my replace_chars(inputstring, "'", "‘")
	set shellscript to "/usr/bin/perl -e '$rpl=q|" & replacementstring & "|;$trgt=q|" & targetstring & "|;$thisvar=q|" & inputstring & "|;$thisvar=~s|$trgt|" & replacementstring & "|gi; print $thisvar;'" ---log shellscript
	try
		set theResult to (do shell script shellscript)
		
		set inputstring to my replace_chars(inputstring, "+vertical-bar+", "|")
	on error
		set theResult to inputstring
	end try
	return theResult
end perlreplace


on replace_chars(this_text, search_string, replacement_string)
	set AppleScript's text item delimiters to the search_string
	set the item_list to every text item of this_text
	set AppleScript's text item delimiters to the replacement_string
	set this_text to the item_list as string
	set AppleScript's text item delimiters to ""
	return this_text
end replace_chars

You could use “quoted form of myString” to make strings compatible to shell scripts.

Christian,

maybe you understand these things better than I, but I have to admit that I find the question of passing data to the shell a darned confusing area. What I want to do, I am quite sure, is to be able to simply declare a variable from applescript that will be inherited in the “do script shell.” Even better would be the ability to simply pipe an applescript variable directly to and back out of a bsd command line. But apple doesn’t allow either of those.

It would also be nice if dtpro had a regex facility built in :stuck_out_tongue:

But I think in this case “quoted form of string” won’t work, because quoted form of string is a form meant to survive to the shell as a command delivered to the shell. It can’t stand itself to be put inside quotes, at least not single quotes. The problem is that in order to issue a perl command one needs to put the text of the command within single quotes, and if one embeds a quoted form of the string it uses single quotes too. So you have to get fancy and find another way around the problem, using the Perl inline commands. Or at least that is the way it seems to me. Maybe somebody else has been able to pass a quoted string to a perl -e command and have it not choke the shell? I haven’t…

erico

p.s. I’ll start a new thread with a better example of how above subroutine works