Script to create individual Markdown notes from PDF annotations

Thanks for this. I guess that your suggested extension could be useful if you know that you have annotated something but cannot remember which PDF it was, though normally it would seem just as easy to select relevant tiles before doing anything.

Right now, the only reason I wanted to know the number of notes is that I am responding to criticisms of a manuscript that take the form of annotations on a PDF, and when I have made a correction I delete the corresponding annotation; from time to time I want an indication of how many more there are.

I’ve just released version 1.3 of the script which can now be executed from a DEVONthink smart rule.

For example, you could use a smart rule like the one below (which gets triggered by an Import or Save event):

DEVONthink_Notes_from_PDF_Annotations-v1.3-DEVONthinkSmartRule

This smart rule would automatically call the script to create (or update) Markdown records from PDF annotations whenever a PDF gets imported to (or updated within) the specified group.

Note that, if the script is executed automatically via a smart rule, script feedback will be reported via a notification (instead of a dialog), and created/updated notes won’t get selected. This is done so that you can continue working within DEVONthink without getting interrupted by the script.

It may also be worth noting that, when triggered by a DEVONthink smart rule, this script can be used in a somewhat similar fashion as the “Stream annotations …” script by @ryanjamurphy:

The main difference is that my script creates individual Markdown notes while the “Stream annotations …” script extracts a PDF’s annotations into a single file.

1 Like

Maybe, this script could work with tinderbox workflow.
More request about summary annotation in markdown with color info!

I’m planning to write a “DEVONthink Notes To Tinderbox” script next. That script could, for example, take the notes generated by the “DEVONthink Notes from PDF Annotations” script, and create corresponding notes in Tinderbox. The script should transfer all of a note’s important metadata (like label color, flag, rating, tags, annotation deep link, file & note URLs, and custom attributes like citation metadata, etc) and create corresponding Tinderbox attributes. It may even be able to recreate the cross-links between notes as regular Tinderbox links.

I’ve written a similar script for Tinderbox previously, so I know it’s doable.

I’m not sure what you mean, could you elaborate? Thanks.

I’m thrilled to hear this amazing news—it will definitely help a lot of people!
I must confess that over the past few days, I’ve been experimenting with various ways to integrate DT and TB. My main focus has been on transferring annotations created in DT, along with their metadata, into TB without any loss. However, as someone with absolutely no background in computer science, even with ChatGPT’s help, I’ve been defeated by issues like regex mismatches, the complexity of TB, and inexplicable errors after deep operations on DT using AppleScript—errors whose causes I don’t understand at all.
These challenges have held me back for quite some time. So far, the only process I’ve successfully completed is manually formatting markdown summaries of annotations using the explode feature.

Exactly, this about DEVONthink, a user ask for a function about Exporting highlight colour information in Summarise Highlights, however, up until the current version, it can still only export summaries in a single color.
Through unproductive practice, I found that if the interaction between the two pieces of software were more straightforward, richer, and customizable, the workflow would be much easier to collaborate on, especially in the exchange of certain attributes and navigation between various links.

Thanks for the clarification!

The script would maintain the PDF annotation’s highlight color by setting the “Color” attribute in Tinderbox (similar to what is shown in this screencast).

Nice work! They are so effective that can help people focus more on the flow of research rather than struggling with the unresponsiveness of the tools.

I’m so excited to have found this but I’m having a hard time getting it to work as a smart rule. Any chance someone could make a screencast? Those are really helpful! Thanks.

Does the script work for you when run manually (i.e. when installed & run as shown in the above linked screencast)?

If you want to run the script as part of an automatically triggered smart rule, you’d first copy the script to ~/Library/Application Scripts/com.devon-technologies.think3/Smart Rules. Then edit your smart rule and add an “Execute Script” action, choose “External” and select again your script. See the above sample screenshot as well as Smart Rule Scripts for more info.

It’s a good idea to make the smart rule’s conditions as specific as possible, so that the script doesn’t fire unnecessarily.

It does when I run it manually. I’ll do as you say and report back. When I tried it nothing happened but I’ll try again.

FYI, I’ve written a DEVONthink Notes to Tinderbox script that will take e.g. the annotation notes created by this script and transfer them to Tinderbox, including most of its metadata like tags, flag, rating, color & label and many custom metadata.

The script will set deep links to point back to your DEVONthink records (and PDF annotations), and can also recreate your note’s WikiLink connections as Tinderbox links.

1 Like

Hi, I am using the markdown notes (very usefull!) in another application and would like to have a link in the note to the original pdf/annotation in Devonthink. Could I add some lines to the script to make that happen?

In order to add the PDF URL (i.e., the deep link to the corresponding PDF annotation) at the end of the note, you could do the following:

  1. Open the script in Script Editor or Script Debugger.
  2. Search for the comment line that says:
    -- create a Markdown record for this annotation in DEVONthink
  1. Add the following lines before that comment line:
tell application id "DNtp"
	set recordContents to recordContents & linefeed & linefeed & "---" & linefeed & linefeed & "[" & name of pdfRecord & "](" & recordURL & ")" & linefeed
end tell
  1. Save the script.

Alternatively, if you instead would like to add the PDF URL as a property in the note’s YAML frontmatter, you could do the following instead:

  1. Open the script in Script Editor or Script Debugger.
  2. Search for the comment line that says:
    -- create a Markdown record for this annotation in DEVONthink
  1. Add the following line before that comment line:
set recordContents to my recordYAML(recordAliases, recordURL) & recordContents
  1. Now, search for the line that says:
end createDEVONthinkNotesForPDF
  1. Add this script method after that line:
on recordYAML(recordAlias, recordURL)
	set yamlStart to "---" & linefeed
	set yamlEnd to linefeed & "---" & linefeed & linefeed
	
	set yamlProperties to {}
	
	-- aliases
	copy {"aliases:" & linefeed & "  - " & recordAlias} to end of yamlProperties
	
	-- PDF URL
	copy {"pdf: " & recordURL} to end of yamlProperties
	
	return yamlStart & KeypointsLib's mergeTextItems(yamlProperties, linefeed) & yamlEnd
end recordYAML
  1. Save the script.

To illustrate how other properties could be added to the YAML frontmatter, the above method also adds the note’s alias. If you don’t need that, simply comment out the line that starts with copy {"aliases:" (i.e., prefix it with --).


Note that these are just quick hacks. Ideally, the script would allow you to specify the format of the note, e.g. based on a note template or a placeholder syntax (similar to my “DEVONthink Notes to Tinderbox” script). I may look into this for a future version of the script.

Many thanks! I just tried the first option and that is exactly what I needed.

1 Like

Thank you for an amazing set of scripts!

One issue I’m running into - completely not a fault of your scripts - is when I have replicants of a given pdf, the script will create an annotations group, but empty.

I’ve ran into this before, when doing something else, and I realize it has to do with DT not knowing which replicant is the “master” - of course, none is, that’s the essence of replicants.

Any ideas on how to potentially deal with this?

Many thanks!

Thank you for your kind words @uimike!

I just replicated a PDF file that has some annotations, and run the script. The annotations group gets created for me, and it contains notes for all PDF annotations. Is your annotations group always empty, no matter which replicated PDF gets processed?

In my case, it seems to work fine except that the location of the annotations group is always next to the first instance of the replicated PDF, no matter which of the PDF replicants I select for processing.

I fear I’ll have to give this a deeper look when I have more time. Any additional info about the issue (or maybe even a sample PDF) is appreciated.

1 Like

Than you Matthias!

I re-saved the script (to “Menu”) and it is working now - not sure why it wasn’t. I can confirm that the new group is created at the location of the selected replicant.

Very useful, really - thanks!

1 Like

Thank you for the feedback, glad to hear it also works for you with replicated PDFs now.

For me, however, the annotations group always gets placed next to one particular replicant PDF (the one that existed first?), no matter which replicant PDF I select for processing.

Ideally, the annotations group would be always placed next to the selected replicant.

1 Like