Automatically generating DT annotation document from PDF annotations


I really like the way DT allows you to generate a separate document with annotations for a particular document. Right now I copy the annotations from other PDF readers and paste them into such DT annotation documents, and then I insert backlinks. Is there a way to do this automatically for all PDFs that I import?

Best regards,

Welcome @Terje

Yes, it is possible to create a smart rule that will summarize highlights into a Markdown document, rich text, or a sheet.

Which format would you use?

Thank you @BLUEFROG

I prefer RTF.

Could it also insert the relevant page backlinks for each annotation in the pdf?

You’re welcome.

A Summary document includes the page link for the detected highlights, e.g.,…

@BLUEFROG is it possible to make each annotation a separate document? Usually I annotate books and I like to take notes and tag the notes by topic. I’m not so interested in seeing all annotations by book, I like instead to see all annotations I’ve made about a particular topic from any book.

Actually, there is a new command coming in the next release: Edit > Paste with Source Link. This will allow you to copy and paste into your diverse rich text documents and have a page link for each pasted item.

Stay tuned for more good things to come.


Thanks, that will certainly help!

1 Like

@BLUEFROG would you be able to share how you made the smart rule? Currently, I am able to search for PDF’s in annotations, but I cannot find a way to invoke the Tools>Summarize Highlights>Markdown. Thanks in advance.

Welcome @dawob

It actually involves a bit of AppleScript.

(Smart rule removed and updated below - 09.28.2022)

I’d recommend to use the record’s location group instead of the current group as smart rules shouldn’t depend on the user interface.


summarize highlights of records {theRecord} to rich in (location group)

If I do this and run from a smart rule nothing seems to be happening.

Otherwise, using current group seems to be creating summarized highlights in the top level of my database.

The in parameter is actually invalid as location group is a property of records, not a global one.

Not totally following. My use case is I’d like to use this smart rule to create summarized output alongside the original file.

I tried omitting the in as well and it is still creating in the top level of the DB. I’m assuming this is because it’s being run from a smart rule?

I removed the old smart rule above.
Here is an updated version…
Summarize On (1.5 KB)

Ahh super useful, thank you!!

Quoting the relevant part here (for me to remember and if it’s of use to anybody else)

	repeat with theRecord in theRecords
	     summarize highlights of records {theRecord} to markdown in (location group of theRecord) # saves the annotation alongside the Record when running from a smart rule
	end repeat
1 Like

You’re welcome :slight_smile:

So, I’ve taken your Smart Rule with the Applescript and tried to move it to Javascript. The code is at the bottom, and I get the error:

10/24/22, 5:18:39 PM: Summarize On Demand on performSmartRule (Error: Error: Parameter is missing.)

Here is my code:

function performsmartrule(records) {
	var app = Application("DEVONthink 3");
	app.includeStandardAdditions = true;
	records.forEach(r => {

Any insight is appreciated.

The syntax of this command is not the right one, see description of DEVONthink’s script suite in Script Editor after switching the language to JavaScript:

You might have a look at @chrillek’s great introduction to JXA:

The correct syntax for summarizeHighlightsOfwould be

app.summarizeHighlightsOf({records: [r], to: "markdown"});

Which you could in part deduce from the scripting dictionary quoted above by @cgrunenberg: The first parameter is a list of records, which translates to an Array in JavaScript. And since you have to pass an Array, using a forEach loop for every single record is a futile.

Less obvious is how to pass these parameters. As you can see (again, from the scripting dictionary, but also from @BLUEFROG’s AppleScript), the parameters are named. This is translated into JavaScript by using an object whose properties are the parameter names and their values are the value you want to pass for the corresponding parameter. Hence:

function performsmartrule(records) {
	const app = Application("DEVONthink 3");
	app.summarizeHighlightsOf({records: records,to: "markdown"})

Note includeStandardAdditions is only needed in some cases, notably when executing shell commands or for user interaction methods. And you should use const for all program variables that are not variable to avoid involuntary modifications.