Customizing Hook integration with DEVONthink

  1. Home
  2. Docs
  3. Help & Support
  4. Integration
  5. Customizing Hook integration with DEVONthink

Note: Custom integration with DEVONthink requires DEVONthink Pro or DEVONthink Pro Office, basic DEVONthink does not have the required Applescript support.

There are two different ways Hook can integrate with DEVONthink. DEVONthink stores its documents as files in folders, and organizes them in a database. Hook can either link to the files themselves, or through the database.

By default, Hook links to the files. If you open a link to a document you linked in DEVONthink, Hook will open it with the default program for the document type (e.g. Preview for PDFs or TextEdit for RTFs) instead of opening it in DEVONthink.

If you link to the database, the links will open the linked documents in DEVONthink itself. This is special behaviour which requires custom integration scripts.

Hook doesn’t have any DEVONthink integration scripts, so if you want to customize Hook to work differently with DEVONthink, you’ll need to create a bundle of scripts from scratch. In Preferences>Scripts, click the + button at the bottom of the list of apps, and add DEVONthink to begin writing custom scripts for it.

Get Name

tell application id "DNtp"
    if exists (content record of current tab of window 1) then
        -- current open item
        get name of (content record of current tab of window 1)
    else if class of window 1 is in {viewer window, search window} then
        set selected_items to selection of window 1
        if (count of selected_items) = 1 then
            -- current selected item
            get name of item 1 in selected_items
        end if
    end if
end tell

Hook is always invoked on the frontmost window, which is window 1. There are two cases which we have to handle:

  • The most common case is that we are linking to a document which is open. It will be in the current tab, and we can get the name from that.
  • The other case is that an item is selected but not open (e.g. in list view or if if a folder is selected). We can get the name from the selection.

Get Address

tell application id "DNtp"
    if exists (content record of current tab of window 1) then
        -- current open item
        get reference URL of (content record of current tab of window 1)
    else if class of window 1 is in {viewer window, search window} then
        set selected_items to selection of window 1
        if (count of selected_items) = 1 then
            -- current selected item
            get reference URL of item 1 in selected_items
        end if
    end if
end tell

This is almost exactly alike the script for Get Name except it returns the reference URL instead of the name.

  • If more than one document is selected, or if no documents are, Get Address (and Get Name) won’t return anything, which means that no valid resource is detected

And that’s all you need to do to customize Hook’s integration with DEVONthink! Now your links to DEVONthink documents will open in DEVONthink.

But what about the other script fields? Why didn’t we write an Open Item script?

Open Item

Hook uses URLs to link items together. If DEVONthink didn’t already support URLs to open documents Hook could use an Open Item script to parse URLs and open linked content in DEVONthink. But DEVONthink has its own URL scheme, x-devonthink-item, and Hook can use it to link DEVONthink documents.

So an Open Item script is not necessary for integrating Hook with DEVONthink. But writing one anyway does allow us to further customize how Hook and DEVONthink behave.

DEVONthink’s default behaviour is to open linked documents in a new window. We can write an Open Item script to open links in a tab of the front window instead of a new window.

set itemURL to "$0"
set itemID to text ((length of "x-devonthink-item://") + 1) thru -1 of itemURL
tell application id "DNtp"
    activate
    set itemRec to get record with uuid itemID
    if window 1 exists then
        set itemTab to open tab for record itemRec in window 1
        set current tab of window 1 to itemTab
    else
        open window for record itemRec
    end if
end tell

"$0" is replaced by the URL returned by Get Address.

The script parses document-identifier from x-devonthink-item://document-identifier and uses it to get the record and open it in the front window, only opening a new window if there are no pre-existing windows.

Scheme

If we have a custom Open Item script we need to specify the scheme for it. Set the scheme to x-devonthink-item in the field under Open Item

Setting the scheme does two things:

  1. The URL returned by Get Address is transformed from x-devonthink-item://document-identifier into hook://x-devonthink-item/document-identifier. The new URL starts with hook:// so macOS passes it to Hook to handle instead of to the owner of the original scheme (e.g. x-devonthink-item).
  2. Hook uses the scheme to look up the appropriate Open Item script to use to handle each URL. When a URL like hook://x-devonthink-url/document-identifier opens Hook tries to find an Open Item script paired with the scheme x-devonthink-url

And that’s all you need to do to make your links to DEVONthink open neatly in tabs.

Link to New

Link to New creates a new document and links it to the current item. There are two things to know about writing the Link to New script.

  1. The variable “$title” will be replaced in the script with the name of the source document. It is typically used for naming the new document.
  2. The script must finish by returning the address of the new document so that Hook can link it with the source document.

There is a lot of room to customize the Link to New script according to personal taste.

tell application id "DNtp"
    set newItem to create record with {name:"$title", type:text}
    get reference URL of newItem
end tell

This is the simplest possible script. It just creates a new empty text document in the DEVONthink Global Inbox.

property folderID : "3D175C4C-4F99-4824-A927-FC8B955B0165"
tell application id "DNtp"
    set newDocGroup to get record with uuid folderID
    set newItem to create record with {name:"$title", content:"# $title\n\n", type:markdown} in newDocGroup
    set refURL to reference URL of newItem
    set itemPath to path of newItem
end tell

tell application "BBEdit"
    open itemPath
    activate
    tell application "System Events"
        key code 125 using {command down}
    end tell
end tell

get refURL

This is a more elaborate script. It does a few things.

  • creates a new markdown document
  • gives it a title header (with two new lines)
  • puts it in a predetermined folder (you can get a folder’s ID by selecting a folder and using Hook to copy a link to it)
  • opens the document in BBEdit (since DEVONthink doesn’t edit markdown files)
  • moves the cursor to the bottom of the document (ready to begin writing)

And that really is all you need to do to get started writing your own scripts to customize how Hook works for you.

If you do try your hand at writing custom Hook scripts, check out the forum! There are people who are interested in seeing what you’ve created and are happy to help if you get stuck.

Was this article helpful to you? Yes No

How can we help?