Deep Linking Hook


I recently used Hook and liked the idea of deep linking to a PDF. Therefore, I tried Skim but the search functionality is underwhelming or the other way: searching PDFs in DT is too good :slight_smile:

So I asked myself whether this would be possible?

Right now DT supports page links. Could you make it possible that Hook can get this page link as an interim step?

And last question. Is there maybe a way to let hook get the frame links in videos?

1 Like

It should be possible for Hook’s developers to implement this using the current page and current time Applescript properties of windows/tabs (as DEVONthink doesn’t provide anything actually for Hook).


May be @LucB would be a good person to ask?

1 Like

Thanks, @Grantst . We’ve indeed received requests for deep linking to DEVONthink PDFs, given that Hook supports deep links to several PDF apps. I see two cases, the second of which has two cases.

  1. if a user wants a deep link to a file that is merely indexed by DEVONthink but not in DEVONthink’s database, and if the user is content to get a hook://file/ URL, then we may be able to devise a deep link for the file. That file however would (at least for time being) open in the app implied by the macOS > Finder Open In setting for that file.
  2. if the user wants a deep link to a PDF in a DEVONthink database per se, then DEVONtechnologies would need to specify the x-devonthink-item URL format , because DEVONtechnologies owns that protocol scheme. For PDF files in Finder, we at CogSci Apps Corp. settled on a syntax an instance of which looks like this #p=2&x=0&y=0 (page number, and x/y per PDF spec (we have variants of that. ) The x and y in our case are optional; p gets the user to the right page. If DEVONtechnologies were to provide such a URL scheme, then they might want to go the extra mile and provide a getDeepURL method, otherwise Hook (and other automation) could construct the URL from AppleScript. The key is that the resultant deep URL gets honored. Otherwise, the URLs would only work inside Hook, and Hook would need to be the “middle person”, which we try to avoid doing; it’s good for users to be able to paste links anywhere and use them only with the target app. I.e., if there’s no x-devonthink-item deep URL, to make deep links to the DB would require a special hook://devonthink scheme --not ideal.

Many Hook users are DEVONtechnologies users. We at CogSci Apps Corp. value integration with DEVONthink. We would be happy to add deep linking here.

The x-devonthink-item URLs in Hook would be synced to our upcoming iOS/iPad software, which also syncs x-devonthink-item URLs in the current format.


Welcome, @LucB! In case of DEVONthink the x-devonthink-item://<uuid> scheme supports already additional parameters like page (zero-based page number) or time (offset in seconds in audio/video file). Such item links can be copied in the user interface via the contextual menu. Or created via AppleScript like this:

tell application id "DNtp"
	set theWindow to think window 1
	if exists content record of theWindow then
		set theURL to reference URL of content record of theWindow
		set thePage to current page of theWindow
		set theTime to current time of theWindow
		if thePage is not -1 then
			set theURL to theURL & "?page=" & (thePage as string)
		else if theTime is greater than 0.0 then
			set theURL to theURL & "?time=" & (theTime as string)
		end if
		return theURL
	else if (count of selected records) is 1 then
		return reference URL of selected record 0
	end if
end tell

Fantastic! thank you @cgrunenberg


This is stunning! Thank you, both of you (and the companies you represent), for working together in this fashion to bring more excellence to us users. Contrasting this with DEVONtech’s attempts to raise issues with some other vendors via obscure and frustrating support channels just makes it all the more pleasing to see how things work when two great companies meet.


wow this is great! i used to open the videos from the database externally in QuickTime to get frame link using hook. just now I replaced the script in hook with the one you posted here, it works really great. this saves a lot of time and makes things easier. thanks a lot

edit: for some reason, the links only works in my note taking app if I copy paste through hook. directly copying from DT doesn’t work as a link. [pic] the first pasted using hook. the second directly from DT

1 Like

DEVONthink is returning the raw item link, not a clickable URL. The item link can be be used to construct live URLs.

1 Like

Hi Luc -

Sorry to dredge this thread up from February, but I’m hoping you’re still keeping track of notifications here : )

I work entirely within DevonThink for my research, including using DevonThink’s PDF reader to access my (1000s of) research PDFs from various organizing folders. When I use a devonthink link to a research PDF, it just goes to page 1. Being able to “deep link” directly to the page of a very large PDF would be a game changer.

SO. Here’s my question: this post seems to be contemplating new additions to Hook (rather than existing functionality). But is that wrong? Is there some way for me to “deep link” directly to (let’s say) page 256 of an 800 page PDF using Hook if I’m working in Devonthink?

Any and all suggestions hugely appreciated!!!

You can create “deep links” using Skim. See this page. You can’t yet create deep links in DT, as far as I know, but maybe that will come in the future.

1 Like

You can actually create links in DEVONthink to e.g. PDF pages, Markdown sections, rich text paragraphs or to a video frame.

1 Like

Can you do that using Hook? I must have missed that development somewhere. There is a lot to keep up with …

Hmmm … I just tried using Hook to create a link to a PDF inside DT and it gives me an item link, but not the page. But using DT instead of Hook will give me the page number.

1 Like

got it --thanks guys!

Thank you @cgrunenberg

This works quite well to get the address of page or frame with Hook and saves me lots of time!

But I also want to know how I can change the name of the link by adding page number or frame time. For example, I have PDF file named DT Help. When I use your scripts, no matter which page or frame, the return markdown link is [DT Help](x-devonthink-item://<uuid>page=3). I want to modify it as [DT Help Page 3](x-devonthink-item://<uuid>page=3) automatically.

I tried by myself some coding of AppleScript in Hook’s Get Name interface. But I am quite not familiar of the syntax, I failed to solve it. So could you help me?

Maybe @LucB has the quick solution to my request.

The default codes of getting name in Hook is as following

tell application id "DNtp"
    if exists (content record of current tab of window 1) then
        -- current open item
        return name of (content record of current tab of window 1)
    end if
    if class of window 1 is equal to viewer window then
        set selected_items to selection of window 1
        if (count of selected_items) = 1 then
            -- current selected item
            return name of item 1 in selected_items
        end if
    end if
    -- selected group
    return name of root of window 1
end tell 

This is unfortunately lacking a bit of context.

Apparently, @cgrunenberg’s code posted above creates the correct DT link (i.e. one to a certain page). Now, the code you posted only shows us how to get the name of a DT record. What we’d need to see is the actual code that Hook (I assume what you posted is somehow used in Hook) uses to assemble its link. Since the DT link already includes the page number, it should be trivial to append it to the name of the link (or rather the link text, since a name is actually an attribute of a link that’s not coming into play here).

So somewhere someone does something like
set the link to "[" & DTname & "](" & DTURL & ")"
(not verbatim, though!) and that’s the place where you’d want to change the code: Extract the page no from DTURL and append it in the form "Page " & pagenumber as string to the part in brackets above.

@chrillek Thanks for your reply and sorry for missing info.

From my understanding by looking at the Hook user interface, in Hook, Get Name and Get Address are separated (as shown in the below figure). I actually pasted @cgrunenberg scripts to Get Address part and in the Get Name part I need to modify the scripts accordingly to change the name of the Markdown link as I wrote and requested in my last thread.

So my request is how to modify here. Any advice is very appreciated since I am struggling to deal with the AppleScript syntax. :grinning:

I’m feeling your pain.

Thanks for the explanation, that makes it clearer now. Basically you have to copy/paste the part of the Get Link script that gets the page no, ie
set thePage to current page of theWindow
into the Get Name script and return a value for the name as you see fit. Something like &” page “& thePage at the end of the current definition of the name.

Unfortunately, the variables are named differently in both scripts, so you’d have to figure out what theWindow refers to.

I’m sure is not too complicated, but I’m not going down the AppleScript road.

Rosemary Orchard says in this podcast that she has found situations where the same script command works with Applescript but will not work with JXA due to bugs in the way JXA is implemented by Apple. Thus she prefers Applescript over JXA.

Have you (or others) experienced similar situations? Any specific examples of known situations where Applescript works but the JXA version does not?

1 Like

There are some cases with whose where JS requires more convoluted ways then AS. Also, apparently sometimes parameters get not passed correctly to or from JXA to an application. We’ve seen that with DT record’s data property and also with an array parameter to one method that gets complied emptied out in the JXA version and remains intact in AS. And @mdbraber told me about problems with JavaScript libraries in JXA that are apparently absent with AppleScript libraries.

Then, if we’re talking ObjC, there’s the question of blocks: AS has them, some ObJC methods require them, but I have no idea how to provide them with JXA.

It might actually be worth exploring other JS approaches like node. In any case, when I said “I’m not going down the AppleScript road”, I was more talking about the language as such. The more I look at it, the more painful it gets. And it does not even have a defined grammar (afaik), so is it even a programming language in the proper sense of the term?

PS: The link you posted leads to a website requiring registration. Another road I’m not going down (anymore).