Using Insert Back Link in AppleScript

I have a simple script that copies highlighted text and appends the filename to the top. Instead of the filename, I would like to append the output of ‘Insert Back Link’ (basically, an active link to the selected location of the highlight). I can’t quite figure out how to get the output of Insert Back Link in place of the filename. Do you have any tips?

tell application id “DNtp”
   if exists (content record) then
      set selectedText to ( selected text of think window 1)
         tell content record
            set currentText to plain text
            set recordName to name
            if selectedText ≠ currentText then
               set the clipboard to (recordName & return & selectedText)
            end if
         end tell
      end if
end tell

The Back Link is just the reference URL of the file.

tell application id "DNtp"
	if (exists content record) then
		set recType to (type of content record) as string
		set recURL to reference URL of content record
		if recType = "PDF document" then
			set currentPage to current page of think window 1
			-- This is a zero-based index, so if you're on page 30, it will report 29
			set currentAttribute to "?page=" & currentPage
		else if recType = "quicktime" then
			set currentTime to round (current time of think window 1 as real) rounding as taught in school
			-- This just gives a nice, clean integer, e.g. 4 instead of 3.8782290
			set currentAttribute to "?time=" & currentTime
		else
			set currentAttribute to ""
			-- Sets currentAttribute to a null value so nothing is appended to the URL.
		end if
		set newLink to recURL & currentAttribute
		-- String the reference URL and the attribute together.
		-- Note you could also add "?reveal=1" if you wanted to reveal the file in the database.
	end if
end tell

PS: Help > Documentation > Automation, especially the Item Links chapter.

2 Likes

current time is not something that I see as a property of think windows in the osascript library for DT3, and it triggers a script compilation error here …

(middle of the script above)

any thoughts ?

UPDATE
Scratch that – the script was launching DT2, and I can see current time in the DT3 library.

I’ve edited my copy to use:

application id "com.devon-technologies.think3"

Having tried it in DT3 with an MPEG-4 movie record which returns the record type ‘quicktime’, however, I notice FWIW, that it triggers the following error:

error "Can’t make «class DTti» of «class thwi» 1 into type real." number -1700 from «class DTti» of «class thwi» 1 to real

This reshuffle seems to work here (separating the get from the coercion):

(macOS 10.14.5, DT 3.0 beta 2)

tell application id "com.devon-technologies.think3"
    if (exists content record) then
        set recType to (type of content record) as string
        set recURL to reference URL of content record
        if recType = "PDF document" then
            set currentPage to current page of think window 1
            -- This is a zero-based index, so if you're on page 30, it will report 29
            set currentAttribute to "?page=" & currentPage
        else if recType = "quicktime" then
            set v to (current time of think window 1) as real
            set currentTime to round (v) --rounding as taught in school
            --This just gives a nice, clean integer, e.g. 4 instead of 3.8782290
            set currentAttribute to "?time=" & currentTime
        else
            set currentAttribute to ""
            -- Sets currentAttribute to a null value so nothing is appended to the URL.
        end if
        set newLink to recURL & currentAttribute
        -- String the reference URL and the attribute together.
        -- Note you could also add "?reveal=1" if you wanted to reveal the file in the database.
    end if
end tell

Couldn’t reproduce that error in JavaScript, so perhaps just one of those AppleScript object referencing subtleties ?

JavaScript for Automation version
(() => {
    'use strict';

    const main = () =>

        dt3ContentRecordURLMay();


    // DEVONthink 3 ------------------------------------------

    // URL for first selected record, if any
    const dt3ContentRecordURLMay = () => {
        const
            dt3 = Application('DEVONthink 3'),
            mb = dt3.contentRecord();
        return maybe(
            '( No record selected in DEVONthink 3 )',
            x => x,
            bindMay(
                null !== mb ? (
                    Just(mb)
                ) : Nothing(),
                rec => {
                    const
                        t = rec.type(),
                        w = dt3.thinkWindows.at(0);
                    return Just(
                        rec.referenceURL() + (
                            'PDF document' === t ? (
                                '?page=' + w.currentPage()
                            ) : 'quicktime' === t ? (
                                '?time=' + Math.round(
                                    w.currentTime()
                                )
                            ) : ''
                        )
                    );
                }
            )
        );
    };

    // GENERIC FUNCTIONS ----------------------------------

    // Just :: a -> Maybe a
    const Just = x => ({
        type: 'Maybe',
        Nothing: false,
        Just: x
    });

    // Nothing :: Maybe a
    const Nothing = () => ({
        type: 'Maybe',
        Nothing: true,
    });

    // bindMay (>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b
    const bindMay = (mb, mf) =>
        mb.Nothing ? mb : mf(mb.Just);

    // Default value (v) if m.Nothing, or f(m.Just)

    // maybe :: b -> (a -> b) -> Maybe a -> b
    const maybe = (v, f, m) =>
        m.Nothing ? v : f(m.Just);

    // MAIN ---
    return main();
})();

It’s inadvisable to run DEVONthink 2 and 3 on the same account, due to issues like this. Your call, but I’d rather avoid the hassle. :slight_smile:

Thanks for this! Is there a way to setup newLink in the clipboard so that when I paste the clipboard contents, the link is active instead of just the string?

Please clarify what you’re referring to, including any helpful screencaps.

Yes, right now I am using the code you sent above and sending it to the clipboard:

set the clipboard to (recordName & return & newLink & return & selectedText)

This gives me the following when I paste the clipboard into a text file:


However, I want to paste the active link, like this:

Define text file.

This is one of the methods I wrote to do this exercise, and posted nine years ago or so :slight_smile:

Put the current selection and rich text URL (“back link”) on the clipboard.

set MaxLen to 500

tell application id "DNtp"
	try
		set theSelection to the first item of (the selection as list)
		
		if theSelection is {} then error "Select an item, please"
		if the kind of theSelection is not in {"PDF", "PDF+Text", "RTF", "RTFD"} then error "Source should be a PDF or RTF"
		
		set theString to selected text of think window 1
		if theString is "" then error "Select some text, please"
		if length of theString is greater than MaxLen then error "That selection is longer than " & MaxLen
		set theStringEncoded to (do shell script "php -r 'echo trim(urlencode(" & "\"" & theString & "" & "\"));'" as string)
		
		set docName to the name of theSelection
		
		if the current page of think window 1 ≠ -1 then
			-- the document is a PDF
			set thePage to the (current page of think window 1) as string
			set pageURL to the reference URL of theSelection & "?page=" & thePage & "&?search=" & theStringEncoded
			set o_HTML to quoted form of ("<font face=\"helvetica\">" & theString & " (See " & docName & ": " & "<a href=\"" & pageURL & "\"> page " & thePage & "</a>" & ")" & "</font>")
		else
			-- the document is not a PDF
			set pageURL to the reference URL of theSelection & "?search=" & theStringEncoded
			set o_HTML to quoted form of ("<font face=\"helvetica\">" & theString & " (See " & "<a href=\"" & pageURL & "\">" & docName & "</a>" & ")" & "</font>")
		end if
		
		do shell script "echo " & o_HTML & " | textutil -format html -convert rtf -stdin -stdout | pbcopy -Prefer rtf"
		
	on error error_message number error_number
		if the error_number is not -128 then display alert "DEVONthink Pro" message error_message as warning
	end try
	
	
end tell
1 Like

Bluefrog, the text files I am using are always RTF files, though I also want to be able to select text from PDF files. The code from korm is working great except for two issues:

  1. for some reason, even when I am selecting text from an RTF file, the error ‘Source should be a PDF or RTF’ is activated. I don’t know why it doesn’t recognize the kind of these files as RTF. I have tried multiple RTF files. It works fine for PDF files.
  2. I can run the applescript without any issue when I remove the error check for a PDF or RTF file, but when I turn the script into an application (which I need to do in order to turn it into a service to assign a keyboard shortcut), I am asked to allow permission (see below) every time I run the application. Is there a way to automatically grant permission in the code or universally on my computer?

    Thanks

Does anyone have any advice about how to give the script access control within the script so I don’t have to keep Allowing Control every time? (see immediate previous comment). I can’t figure out how to do this. This pop-up does not come up when I just run the script from within DT3. However, to assign a keyboard shortcut, I have to make it an application to turn it into a service, and when I do that and activate the keyboard shortcut, the pop-up appears asking to Allow Control each time.

This is an Apple issue. Try opening the Folder Actions Setup, Apple’s own app, in the Finder.

Every. Single. Time.


By the way, kind is a localized string value. This means the kind on my system is Rich Text Document but on a German system it would be RTF-Dokument.

Using type is the more portable method, and coercing (type of theSelection as string) is even a little safer.

I’m sorry, I don’t understand. How would attaching a script to a folder action in apple solve my issue? Forgive me, I’m a bit new at this. Thank you for the tip on RTFs.

How would attaching a script to a folder action in apple solve my issue?

It doesn’t. I was showing an example of the behavior in macOS Mojave. The Folder Actions Setup is Apple’s own app and yet it requires you to okay running it, every time you use it.

Is there any other solution to attach a keyboard shortcut to copy a selection of text with a back link to the file it is in that would not involve having to Allow Control at every instance?

Where is your script saved on your machine?

~/Library/Application Scripts/com.devon-technologies.think3/Menu/My Scripts/

See Help > Documentation > Automation > AppleScript > Script Shortcuts
:slight_smile: