Enlink selected text using applescript

This is a follow-up to a post from a few years ago (Selecting text and adding a hyperlink).

It’s a rough method in that it relies on System Events’ processes suite but given that, it seems to work reliably. It could probably be stuffed into an automator service and thus be given a keyboard shortcut (through the standard procedures). Hopefully it will be of use to others as well.

To use it, start with a link on the clipboard and an outline with some selected text. I’ve added two lines to make an easy test example (1,3). If it works then delete them.

First, it stuffs the link into a variable to free up the clipboard. It then copies the selection and finds its offset within the topic and length to derive a range of text. Finally, it applies the initial link to that range of text.

set tempo to "https://discourse.omnigroup.com/" -- example

use scripting additions
set the clipboard to tempo -- example
set enlink to the clipboard

tell application "OmniOutliner"
	activate
	tell application "System Events"
		keystroke "c" using {command down}
	end tell
	set tc to the clipboard
	
	set tx1 to item 1 of topic of selected row of document 1
	set ri1 to (length of tc) - 1
	set le1 to offset of tc in tx1
	
	set attribute "link"'s value of style of characters le1 thru (ri1 + le1) of topic of selected row of document 1 to enlink
end tell

FWIW, here is a method that doesn’t rely on the clipboard (using JavaScript For Automation).

The following script creates a new link in the note of the first selected row (assuming there is a selection):

(() => {
        // main :: IO ()
        const main = () => {
            const
                app = Application("OmniOutliner"),
                doc = app.documents[0],
                seln = doc.selectedRows()[0];

            return setItemNoteAndLink(seln)(
                'OmniGroup Website'
            )('https://www.omnigroup.com/omnifocus/ios/')
        };

        // FUNCTIONS --
        // setItemNoteLink :: Item -> String -> URL String -> Item
        const setItemNoteLink = oItem => strTitle => strURL => {
            // Sets "link" attribute of note property
            // of a given item.
            return (
                oItem.note = strTitle,
                oItem.note.style.attributes["link"].value = strURL,
                oItem
            )
        };
        
    // MAIN --
    return main();
})();
1 Like

My intent is to turn the selected text into a link (and remain part of the topic’s text). Is that possible with JS?

Yes, I think so. You can enlink any given string by editing value property of attributes["link"]. If I recall correctly, rich text contains character elements. In principle, you should be able to get a contiguous section of characters and edit the property of those.

Oh, I understand now what you want. No, unfortunately that’s not currently possible.