Finding & replacing text with Applescript

574 views
Skip to first unread message

Duncan Thorne

unread,
May 24, 2021, 8:13:36 PM5/24/21
to BBEdit Talk
I'm pretty clueless with Applescript so please bear with me. I want to copy text from a Safari table, paste it into a new BBEdit window and do some text manipulation, mostly finding and replacing.
I managed this with the old Tex-Edit Plus (not TextEdit) which is unfortunately 32-bit. With T-E+ I would paste the text from the clipboard with the commands make "new window", "paste", "select window 1" and then use a "replace window 1 looking for..." command.
When I try recording something in BBE I get the line
replace "[original text]" using "[replacement text]" searching in text 1 of text document "untitled text ##" ...
— i.e. a named doc as opposed to simply the front doc. Not a surprise, but what do I replace "untitled text ##" with?

Christopher Stone

unread,
May 24, 2021, 10:37:21 PM5/24/21
to BBEdit-Talk
On 05/24/2021, at 19:11, Duncan Thorne <dunc...@gmail.com> wrote:
I'm pretty clueless with Applescript so please bear with me. I want to copy text from a Safari table, paste it into a new BBEdit window and do some text manipulation, mostly finding and replacing.


Hey Duncan,

This task is pretty simple if you know how, and a real head-scratcher if you don't.

It's great to be able to record AppleScript, but it often produces semi-useless results – unless you savvy AppleScript enough to be able to rewrite the recording and pick out the good bits.

I almost never use it, BUT it sometimes comes in really handy when I just can't figure out the syntax for something.

Appended is a script that will:

- Copy the selected text in Safari.
- Create a new BBEdit document with said text.
- Reset the size and position of the new document.
- Do one regex-based find/replace on the document.
    - You can add more replace statements as needed.

Enjoy.

--
Best Regards,
Chris

--------------------------------------------------------
# Auth: Christopher Stone
# dCre: 2021/05/24 21:24
# dMod: 2021/05/24 21:29
# Appl: BBEdit
# Task: Copy Safari Table to New BBEdit Document and Find-Replace.
# Libs: None
# Osax: None
# Tags: @Applescript, @Script, @BBEdit, @Table, @RegEx, @Massage, @Data
--------------------------------------------------------

set jsCmdStr to "

(() => {
return window.getSelection().toString()
})();

"
set tableContent to doJavaScriptInSafari(jsCmdStr)

tell application "BBEdit"


activate


make new text document with properties {text:tableContent}


# Resize and reposition the new document.
# {x1, y1, x2, y2} Upper-Left-Corner, Lower-Right-Corner.
set bounds of front window to {0, 45, 1314, 1196}


tell front text window's text
replace "Carbon|Helium" using "••••••" options {search mode:grep, case sensitive:false, starting at top:true}
end tell


end tell

--------------------------------------------------------
--» HANDLERS
--------------------------------------------------------
on doJavaScriptInSafari(jsCmdStr)
try
tell application "Safari" to do JavaScript jsCmdStr in front document
on error e
error "Error in handler doJavaScriptInSafari() of library NLb!" & return & return & e
end try
end doJavaScriptInSafari
--------------------------------------------------------

Rich Siegel

unread,
May 24, 2021, 10:44:50 PM5/24/21
to BBEdit-Talk
On 24 May 2021, at 22:37, Christopher Stone wrote:

> On 05/24/2021, at 19:11, Duncan Thorne <dunc...@gmail.com
> <mailto:dunc...@gmail.com>> wrote:
>> I'm pretty clueless with Applescript so please bear with me. I want
>> to copy text from a Safari table, paste it into a new BBEdit window
>> and do some text manipulation, mostly finding and replacing.
>
>
> Hey Duncan,
>
> This task is pretty simple if you know how, and a real head-scratcher
> if you don't.
>
> It's great to be able to record AppleScript, but it often produces
> semi-useless results – unless you savvy AppleScript enough to be
> able to rewrite the recording and pick out the good bits.
>
> I almost never use it, BUT it sometimes comes in really handy when I
> just can't figure out the syntax for something.
>
> Appended is a script that will:
>
> - Copy the selected text in Safari.
> - Create a new BBEdit document with said text.
> - Reset the size and position of the new document.
> - Do one regex-based find/replace on the document.
> - You can add more replace statements as needed.

This is a good script. Some feedback: as a matter of best practices and
future proofing, avoid targeting windows (or elements of them).

"make new text document" will return a reference to the document just
created.

The "text" property of a document provides access to the text without
going through the windowing system. It's also faster and avoids
complications that can arise when the 1:1 relationship between documents
and windows is not in effect (as has been the case since BBEdit started
supporting multiple documents per window, back whenever that was).

Thus:

set myDoc to make new text document with properties { text:
tableContent }

followed by

tell text of myDoc
-- do the replace in here
end tell

is recommended.

R.

--
Rich Siegel Bare Bones Software, Inc.
<sie...@barebones.com> <https://www.barebones.com/>

Someday I'll look back on all this and laugh... until they sedate me.

Christopher Stone

unread,
May 24, 2021, 11:40:32 PM5/24/21
to BBEdit-Talk
On 05/24/2021, at 21:44, Rich Siegel <sie...@barebones.com> wrote:
his is a good script. Some feedback: as a matter of best practices and future proofing, avoid targeting windows (or elements of them).


Hey Rich,

Thanks for the feedback.

Actually I often use this sort of construct:



tell application "BBEdit"
    activate
    set myDoc to make new text document with properties {text:"some text"}
    return myDoc
end tell

--> text document 1 of application "BBEdit"



What I don't like about it is the reference it creates – it will break if you change the window index in the script and then refer to the reference again.



Getting a reference to any document besides document 1 produces a more sturdy reference:

tell application "BBEdit"
    set docRef to document 2
end tell

--> project document "untitled project 45" of application "BBEdit"



If I need the reference to be more robust I have to do something like this:

tell application "BBEdit"
    activate

    set docID to ID of (make new document with properties {text:"some text"})

    

    tell document id docID
        set after its text to linefeed & "some more text" & linefeed
        select insertion point after its text
    end tell

    

end tell

Most of the time working with the front document is perfectly adequate – but not always.



--
Take Care,
Chris

Duncan Thorne

unread,
May 25, 2021, 8:34:57 AM5/25/21
to BBEdit Talk
Thanks, Rich.
At first I thought, wow this is complicated. But you make it easy. I shall of course have fun when I push beyond simple find/replace, but you've given me a great start.
— D

Duncan Thorne

unread,
May 25, 2021, 8:35:04 AM5/25/21
to BBEdit Talk

I'm not sure what I started but I certainly appreciate the help, Rich and Chris
- D

Christopher Stone

unread,
May 25, 2021, 6:23:21 PM5/25/21
to BBEdit-Talk
On 05/24/2021, at 21:44, Rich Siegel <sie...@barebones.com> wrote:
This is a good script. Some feedback: as a matter of best practices and future proofing, avoid targeting windows (or elements of them).


Hey Duncan,

Here's the script using Rich's suggested best practices.

I'm using the top table on this page as my test data:



--
Best Regards,
Chris

--------------------------------------------------------
# Auth: Christopher Stone <script...@thestoneforge.com>
# dCre: 2021/05/24 21:24
# dMod: 2021/05/25 17:04
# Appl: BBEdit
# Task: Copy Safari Table to New BBEdit Document and Find-Replace.
#     : (Following Best Practices)
# Libs: None
# Osax: None
# Tags: @Applescript, @Script, @BBEdit, @Table, @RegEx, @Massage, @Data
# Vers: 1.50
--------------------------------------------------------

set jsCmdStr to "

(() => {
    return window.getSelection().toString()
})();

"
set tableContent to doJavaScriptInSafari(jsCmdStr)

tell application "BBEdit"
    activate
    
    set newDoc to make new text document with properties {text:tableContent}
    
    # Resize and reposition the new document.
    # {x1, y1, x2, y2} Upper-Left-Corner, Lower-Right-Corner.
    set bounds of front window to {0, 45, 1314, 1196}
    
    tell newDoc
        replace "Carbon|Helium" using "••••••" options {search mode:grep, case sensitive:false, starting at top:true}
    end tell
    
end tell
--------------------------------------------------------
Reply all
Reply to author
Forward
0 new messages