Linking to/from specific strings of text

Someone asked via email whether we support linking to specific strings of text in documents

I answered:

You’re right, linking to specific segments of texts isn’t currently possible. We could only do this with sufficiently scriptable apps on a case by case basis. I do want to do that with Safari and Skim for a start.

I will soon publish more about the History of Hook. But in a nutshell, CogSci Apps co-founder (Brian Shi) and I led software teams at Simon Fraser University for two major projects (multi-million $) on self-regulated learning with technology. We actually did implement linking to/from text, images, and even video segments. However, these apps were largely self-contained. (gStudy/nStudy , 2002-2009.) We needed to reinvent each app (editor, concept map, etc.), which was a very ambitious task. That removed user choice.

One of the big insights I had that led to Hook was to just be the bridge between apps, letting users choose best-of-class apps for each annotation (“meta-doc”) app. (I got this insight as I was thinking about Tundra Semiconductor, where I was an at-founding employee. Tundra developed bus-bridges. I took this hardware concept and geralized it to/ morphed it into software.)

We also plan to support quoting text which will achieve some of what you want:

  1. link to new with quotation
  2. append text

However, I think you will find that Hook’s linking function is surprising useful. And it does support important self-regulated learning use-cases.

One trick is to include a tag in your PDF inline notes that links to a marker in your linked note document. In fact, Hook includes a random string generator (gear menu) that is useful for generating such ID’s. You can also include a link from inline notes to specific meta-docs (linked docs).

I’ll expand on these ideas later.


This feature would be great, specifically in web page. However the problem is the dynamicity of the text, which it is not an issue in PDF, but on any other media. In order to avoid link to null (typical problem with XPATH or other selectors), an easy solution could be to just copy the text with the source and the time when it has been copied in the note. That would work perfectly for me. Other solution would be to create a snapshot of a webpage or a copy of the file and save it locally, but it would in time grow too much…

1 Like

When I found out about Hook yesterday, (besides being generally exited about the functions already implemented) that was my first question as well: is it possible to link together specific annotations/notes in PDFs, not just the PDF itself. That would be incredibly useful for writing any scientific content for having an overview of and quick access to every source one refers to and where exactly it supported an argument, etc.

If you could even make linking to passages of websites (though one could and probably should save those as PDFs locally to have a permanent record) and to time markers in videos (on- or offline) work, that would be amazing for studying and memorizing content.

I didn’t completely understand the following recommendation, do you have documentation on this?

One trick is to include a tag in your PDF inline notes that links to a marker in your linked note document. In fact, Hook includes a random string generator (gear menu) that is useful for generating such ID’s. You can also include a link from inline notes to specific meta-docs (linked docs).

I’m excited that you plan to implement these features with Skim and Safari. Do you have a roadmap for this? And, as an aside, are you planning on expanding your Cognitive Productivity books by including recommendations how to use Hook within the described workflows? Thanks!

I was hoping for a reference to some documentation on this, too – I would love to understand this trick better.

There’s some info on the ID/search link features here

It sounds like Evernote would do what you’re looking for.

Another interesting option is Hypothesis which allows you to link to specific text from Hook.

1 Like

Suppose that you are reading PDF of this book in Cognitive Productivity with macOS®: 7 Principles for Getting Smarter with Knowledge. Its filename is

  1. using Link to New, you get a new “notes” document. Suppose you generate an OmniOutliner document, called [cognitive-productivity-macos.ooutline. (The prefix [ is optional, and can be configured in Hook’s Notes tab. It’s handy to be able to prepend a prefix, because then you can more quickly randomly access the file with a launcher when you’re not in the context of a doc linked to it. That’s a trick I explain in the Cognitive Productivity with macOS book.)
  2. In that OmniOutliner file, you take some notes notes about the first two chapters of the book.
  3. Then you start reading the “Assess Analytically” chapter (Principle 3) and encounter the CUP’A principle.
  4. You decide to write a note about the CUP’A principle in the PDF itself.
  5. But taking and reading notes in even a great PDF reader like Skim is a bit tedious. You realize you would like to elaborate on this PDF note inside the OmniOutliner file. You thus go ahead and write this note in [cognitive-productivity-macos.ooutline.
  6. So, in the PDF note, you want to include a reference to the location in the OmniOutliner file where this note resides. Basically, you want to setup a “virtual link” between the note in the PDF and the specific location in the OmniOutliner file. This calls for a unique ID and reference to the ID (an “IDREF”).
  7. You use Hook to generate a new ID. Suppose Hook yields RL8V8-E1ZKO, which it puts in the pasteboard.
  8. In the OmniOutliner section where you elaborate on CUP’A, you paste RL8V8-E1ZKO. If you’re familiar with HTML, consider that this is like a span ID attribute <span id="RL8V8-E1ZKO"></span>. But the process for using the span is currently partly manual.
  9. In your PDF, you can include a reference to this note (like a “pointer” or an “IDREF” in XML), #RL8V8-E1ZKO. Here “#” is a symbol which by convention refers to a target. We chose the pound symbol by analogy with HTML and Markdown, where you might write a link like this [See this note](#RL8V8-E1ZKO). But any symbol would do because this is just a convention in the workflow.
  10. Later, when you are reviewing your PDF, if you want to consult your more detailed note (the one in the OmniOutliner) document, you could copy RL8V8-E1ZKO, invoke Hook, get your OmniOutliner file, and search for RL8V8-E1ZKO.

If you happen to have several notes documents linked to this same PDF (which would show up in the Hook window), then instead of just writing #RL8V8-E1ZKO in the PDF, you could prepend #RL8V8-E1ZKO with the hyperlink to the note (which Hook can easily give you). Or you could rely on Spolight, as noted below. Because RL8V8-E1ZKO is unique, Spotlight will find it. Or you can construct a search link to it, like this hook://search/?q=RL8V8-E1ZKO. (In fact, that is what the Copy a Search Link from Clipboard does. See below.)

You can use the same conventions in the other direction. That is to say that if you want to refer to a particular location in the PDF file from the OmniOutliner doc (or other file), you can create a note in the PDF , generate the ID with Hook, and plant (paste) it in the PDF note. You’d normally use Hook to access the entire PDF, and then use Skim’s search function to find the note (RL8V8-E1ZKO) in the PDF.

While this is a somewhat manual process, over the years I have found it to be quite a helpful work-around to macOS’s lack of robust anchored hyperlinks to arbitrary locations. Once you get the hang of it, it’s a rapid, automatic process for accessing specific locations in documents.

So, what value does Hook add here? In sum,

  1. It lets you link and access related documents that refer to each other (the Hook window links that you are already used to).
  2. It provides the “unique” ID generator (which a bit of AppleScript could also do). (In fact, until I had Hook, I would use an AppleScript for this myself).
  3. It can construct and serve Search links, like this hook://search/?q=RL8V8-E1ZKO. This adds an additional layer of robustness. You can cut and paste the anchored text into a different document and still be able to find them.

The compactness and uniqueness of Hook’s unique ID’s, and the ease of generating them makes more useful than manually constructing cross-references. When manually constructing cross references, more mental and physical operations are required, which consume working memory and interfere with psychological “flow”.

The ID’s generated by Hook are not guaranteed to be globally unique on your system. However, they’re long enough to be very likely to be unique on any given system. Moreover, they are short enough not to chew up your working memory (highly limited memory in the human mind).

I used Skim as an example PDF “reader” because it has a useful notes filter. (My Cognitive Productivity with macOS® discusses some of the other advantages of Skim. I also discuss Skim on

Speaking of Spotlight, as an aside: The system described above is also useful for linking to documents that have not yet been saved. Before a file is saved or an email is sent, it does not have a fixed URI (address); it cannot be the target of an alias or hook://file link. However, you can generate a search (Spotlight) link for it, which looks like this: hook://search/?q=RL8V8-E1ZKO. You can paste that link anywhere at any time, but of course Hook will only be able to find its target once the document is saved. Why is this useful? First, it lets you stay in flow. Sometimes you want to paste a link to an as of yet unsaved document. This provides a very quick , automatic and easy way to do it. Within a few seconds you can paste and link to the target ID. You don’t need to carry in your head the nagging thought “I need to link to this.” Second, the link even works for emails and shared files. For instance, you can write two emails that link to each other. As long as the parties have both messages, they will be able to use the links to each other. These are just examples, there are other uses.


They are also super useful for linking from physical documents.

For example, I use a paper Bullet Journal. To link to a digital file I can append the ID to the file name then write just the ID by hand in the Bullet Journal.

To link in the same way without using a file name (because you don’t want to change the file name for aesthetics or it will break links, or because it’s something like an email without a file name) you can create a note for the file and add the ID there.


What function of Hook are you using to generate these random IDs that you then use to link to notes within Skim? I realize I can invoke Hook on a file and copy that file’s link, and that I can invoke Hook to create a new note or a Hook file with a link therein. But how do I use Hook simply to generate a unique identifier to use as you describe here?

The command is in the Gear menu, which is described here: Gear Menu – Hook .

The Gear menu is now in Hook’s Title bar. When you place the cursor in the right corner of the title menu, a gear icon shows up. Click that icon and you get the title menu.

While the Hook window is exposed, you can also type ⌃G to see the Gear menu.

There’s also a Gear menu in Hook’s menu bar icon.

Unique ID’s don’t make for nice link names. I sometimes prepend a bit of text to make the unique ID easier to recognize. You can also create Markdown links and set the name of the link to be easier to recognize (the name of the link doesn’t need to include the ID of course). Speaking of which, Hook will support renaming of links, a request that came up on the forum recently.

Maybe I’m using this incorrectly, but it doesn’t seem to be working for me…

I generated a UUID using Hook and used the UUID as the contents of a note annotation on a PDF in Skim. Then in my markdown document, I placed a link to the UUID (i.e., hook://search/?q=UUID) so that, in theory, when I activate the link, Hook will show me the documents containing the UUID in their contents, i.e., the markdown document and the PDF I annotated. Unfortunately, only the markdown document shows up in the results (and the results are displayed in a Finder window rather than in Hook – is that supposed to happen?)… What am I doing wrong?

Just a quick reply right now… I just quickly skimmed this 2019 post. In the PDF context, I was assuming you would use hook://file URIs to connect the PDF documents (because hook://URIs are very precise), and then use a search function of the app to find the IDs (tags), which is what I do. i.e., that’s what I meant when I wrote:

i.e., you can search for that tag on the annotation app side and the PDF side.

Skim saves its annotations in extended file attributes associated with a file, and those are not found by normal Spotlight searches (there are workarounds). In Skim, you can turn on “Automatically save Skim notes backups” – those backup files are normally indexed by Spotlight. You could also use the skimembed command to move annotations into the PDF file --which is tedious .

The above don’t seem to be great use cases for hook://search/ links unless you want to quickly find several documents that deal with the same topic (tagged by the ID), or app you’re using for annotating creates resources that are indexed by Spotlight but where the app does not have an API to get their URLs. I apologize for whatever confusion the above may have caused.

FYI, we are looking at deep linking again these days – i.e., to not require a separate search . There may be something in Skim’s API that we can leverage to link to specific pages (and in principle Skim annotations). More on that late this month or next.

I might look at the post again early this week in case I’ve missed something.