Item links in DT3

Thanks for the replies, I’m not really worried about the script, I just wanted to see how it worked.
My problem is I can’t get the icon off my toolbar as per my screenshot above.

Hi, cgrunenberg,

you are right, all matches are listed in both versions, my description was false. You explained exactly where the difference came from. I observed that in DT2 the “search” will start with the currently opened page, that’s how “page” parameter seems to accelerate the search process, whereas in DT3, the search will always start with the first page, it will not highlight the first match until all matches are listed on the search panel, that’s why I feel one or two seconds delay in DT3. Thanks for your fine description, everythink is clear now, maybe I should not use item links in that way.

I’ve got it all sorted now, that Links script is very handy, works well on my PDFs, thanks for posting it.

I confirmed that if you are working with a PDF, the script will not save your position, but it can save selected text.

So I have revised the script below. Now, it will check to see if your cursor has a position in the selected doc, or if you have selected any text, and if so, ask what kind of link you want to create.

  • If you just select a document, without placing your cursor in it or selecting text, the script will simply put an item link to it in your clipboard
  • If you placed your cursor in the doc, the script will give you an option to create a link to either the document, or to the position in the document (this doesn’t work for PDFs)
  • If you selected text in the doc, the script will also give you an option to create a link that will search for that text in that doc. (this does work for PDFs)
tell application id "DNtp"
	try
		if not (exists think window 1) then error "No window is open."
		if not (exists content record) then error "Please open a document."
		set this_line to the current line of the tab of think window 1
		set find_this to the selected text of think window 1 as string
		
		--create list of options for dialog
		set options to {"whole document"}
		if this_line > 0 then copy "position" to the end of the options
		if not find_this = "" then copy "selected text" to the end of the options
		
		--if more than one option, display dialog
		if (count of options) = 1 then
			set answer to "whole document"
		else
			set answer to the button returned of (display dialog "What part of the document do you want to link to?" buttons the options default button 1)
		end if
		
		if answer = "whole document" then
			set itemURL to get the reference URL of (item 1 of (selection as list)) & "?reveal=1&line=0"
			
		else if answer = "position" then
			set itemURL to get the reference URL of (item 1 of (selection as list)) & "?reveal=1"
			if this_line is not equal to "" then set itemURL to itemURL & "&line=" & this_line
			
		else if answer = "selected text" then
			set find_this to my replaceText(find_this, " ", "%20")
			set itemURL to get the reference URL of (item 1 of (selection as list)) & "?reveal=1" & "&search=" & find_this
		end if
		
		set the clipboard to itemURL
		beep
		
	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

on replaceText(theString, old, new)
	set {TID, text item delimiters} to {text item delimiters, old}
	set theStringItems to text items of theString
	set text item delimiters to new
	set theString to theStringItems as text
	set text item delimiters to TID
	return theString
end replaceText

@dansroka

Thanks - very helpful

Question - is it possible for me to tweak this so that the resulting link is an active hyperlink with a relevant name (such as the backlink examples below in color) rather than non-active links (such as the white examples currently generated by the script):

I don’t think so… but I’m no expert.

Should be easy to do. ~Line 6:
set link_text to find_text
(To save the copied text as something to use later.)

Then, when the URL is copied to the clipboard, instead do:
set the clipboard to “[“ & link_text & “](“ & itemURL & “)”

Of course, that’s for markdown. Pasting an RTF formatted link might be a bit trickier but the same idea should apply.

(I haven’t tested that code, so apologies if it fails immediately!)

Yeah, it’s pretty easy for a markdown link since it is raw text. But I tried doing this for RTF before, and it gets (sigh) complicated…

What button are you referring to?

But I tried doing this for RTF before, and it gets (sigh) complicated…

That’s also one of the reasons I don’t advocate RTF. The complication is inherent in dealing with RTF files. However, we have a few ways to ease scripting for some particular issues *(as @cgrunenberg likes RTF)_.

The Back Link feature as you know works well to create a link in an RTF file

I gather that is harder to do here in Applescript as opposed to the language used to write DT3?

I gather that is harder to do here in Applescript as opposed to the language used to write DT3?

Correct.

All sorted thanks.

Interesting script. When clicking on created link it just highlight the document the word is in. Correct?

At lest that’s what happens when I click on the created link(word highlighted) with a PDF.

It just does the “copy item link” command, but adds some of the not-so-obvious parameters to it (as described in Help > Documentation > Automation > URL Commands). I created it because I am always cross-referencing documents via the item link, but I like to add the reveal parameter so that will open in the main window instead of a separate one. Then others mentioned the super-useful line and the search parameters, so I added them on.

Yes it does highlight the text in a pdf if you choose the option to have the link open at selected text.

Thanks dansroka and everyone else. This is useful! Three comments:

  1. I suggest changing line 5 to: set this_line to the current line of current tab of think window 1; this prevents problems when you have more than one tab open (in that case “current line” yields a list such as “{-1, 18}” and “set this_line” gives an error).

  2. Working with Markdown (editing and preview panes side by side) I’m seeing slightly eccentric behaviour. The script offers the “selected text” option only when text is selected in the preview, not in the source. Yet opening the resulting link highlights the found text in the source, not the preview. Is this the expected behaviour, and if so, could it be made more consistent?

  3. In PDFs the “selected text” option works fine but the “line number” option isn’t available, presumably because PDFs don’t support line numbers. Could we get DT3’s “Copy Page Link” functionality into the script, so that we could choose “current page” as a new option behind “current line” or “selected text”, and ahead of the fallback “current document”?

1 Like

This version addresses points 1 and 3 above, I think. I’ve tweaked the way the choices are displayed; the default is now the most precise option available, in the order: selected text > line > page > whole document. And I disabled the “done” beep because to me that usually signals an error.

I’m still wondering if there’s a more consistent way to link to Markdown docs.

Now with syntax colouring thanks to Dan’s instructions below :slight_smile:

    ----------------------------------------------------------------------------------------------------------------------------------
    -- Place on the clipboard a link to the current DT document, with the option to include either the line number or
    -- the currently selected text, if any.
    -- 
    -- Original script by DT forum user dansroka and others, 2019-10
    -- See https://discourse.devontechnologies.com/t/item-links-in-dt3/50513/57
    -- 
    ----------------------------------------------------------------------------------------------------------------------------------

    tell application id "DNtp"
        try
            if not (exists think window 1) then error "No window is open."
            if not (exists content record) then error "Please open a document."
            set this_line to the current line of current tab of think window 1
            set this_page to the current page of current tab of think window 1
            set find_this to the selected text of think window 1 as string
        
            -- Create a list of options for the dialog
            set options to {"Whole document"}
            if this_page > -1 then copy "Page" to the beginning of the options
            if this_line > 0 then copy "Line" to the beginning of the options
            if not find_this = "" then copy "Selected text" to the beginning of the options
        
            -- If more than one option, ask the user to choose
            if (count of options) = 1 then
                set answer to "Whole document"
            else
                set answer to the button returned of (display dialog "What part of the document do you want to link to?" buttons the options default button 1)
            end if
        
            set itemURL to get the reference URL of (item 1 of (selection as list)) & "?reveal=1"
        
            if answer = "Line" then
                if this_line is not "" then set itemURL to itemURL & "&line=" & this_line
            
            else if answer = "Page" then
                set itemURL to itemURL & "&page=" & this_page
            
            else if answer = "Selected text" then
                set itemURL to itemURL & "&search=" & my replaceText(find_this, " ", "%20")
            
            else -- Fall back to "whole document"    
                set itemURL to itemURL & "&line=0"
            
            end if
        
            set the clipboard to itemURL
            -- beep
        
        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

    on replaceText(theString, old, new)
        set {TID, text item delimiters} to {text item delimiters, old}
        set theStringItems to text items of theString
        set text item delimiters to new
        set theString to theStringItems as text
        set text item delimiters to TID
        return theString
    end replaceText
2 Likes

Good suggestions and additions, thanks!

And to paste code with syntax coloring, type ``` on the line before and after the code, like this:
36%20AM

Thanks! Now fixed. I’d tried indenting with four spaces, and with “>”, but those didn’t work.