Make an Annotation with Links, Notes, Tags v2

For forum archives. Includes the RTF request downstream of this posting.

(*
	This annotation assistant will produce a single annotation file each time it is run.  The use case is to choose text in a PDF, optionally add a highlight to it (the highlight does not affect the operation of the script), and then run the script.  When the script is run it will:
	
	1. Check to see if a document and text (the citation) in that document are selected; otherwise terminate
	2. Ask for a "prefix" -- this is a shorthand identifier for the annotation file
	3. Ask for a "note" -- any text that describes the text (for example)
	4. Ask for tags -- a semicolon-separated list of tags that will be added to the document (can be exported as Mavericks tags) and also are listed inside the annotation document
	5. Ask for a file name for the annotation document -- the default is Prefix + name of the original document.  This can be changed in the dialog.
	6. Create a file that contains all of the above, as well as links to search for the citation, for that page of the PDF, and to open that document in the location in the database package where it is stored.  The latter link is powerful and dangerous -- do not add or remove things directly from the annotation package.
	
	v2
	
	a. Create RTF output
*)

property noDecoration : "\" style=\"text-decoration:none;"
property preferRTF : true

tell application id "DNtp"
	
	try
		
		(*
			Select a single document
		*)
		set thisItem to the first item of (the selection as list)
		if thisItem is {} then error "Please select something"
		
		(*
			Get selected citation text
		*)
		--set theCitedText to selected text of think window 1
		--if theCitedText is "" then error "Please select some text"
		
		set theCitedText to the (selected text of think window 1 as string)
		if theCitedText is "" then error "Please select some text"
		
		(*
			Create a prefix for the annotation otherwise use the name of this item
			Use case: create a text annotation in the document with the same text as the prefix
			You will find the prefix on the clipboard so add it immediately after this dialog ends
		*)
		set thePrefix to text returned of (display dialog "Annotation Prefix:" with title "Annotation Prefix" default answer "")
		if thePrefix is not "" then
			set theName to thePrefix & " " & the name of thisItem
			tell application "System Events"
				set the clipboard to (thePrefix as text)
			end tell
		else
			set theName to the name of thisItem
		end if
		
		(*
			Get a note for this clipping
		*)
		set theNote to text returned of (display dialog "Notes for this clipping:" with title "Notes" default answer "[none]")
		
		(*
			Get tags for the annotation document
		*)
		repeat
			set theTagPrompt to display name editor "Add Tags" info "Tags (separated by semicolons):"
			if theTagPrompt is not "" then exit repeat
		end repeat
		
		(*
			Get a name for the annotation document
		*)
		set theAnnotationName to text returned of (display dialog "Name for this annotation file" with title "Annoation File Name" default answer (thePrefix & ": " & the name of thisItem))
		
		(*
			Make a text-search link for this citation
		*)
		if number of words of theCitedText is greater than 5 then
			set maxWords to 5
		else
			set maxWords to number of words of theCitedText
		end if
		set thisWord to 1
		set theCitedTextText to ""
		repeat while thisWord is less than or equal to maxWords
			set theCitedTextText to theCitedTextText & word thisWord of theCitedText
			set thisWord to thisWord + 1
			if thisWord is less than or equal to maxWords then
				set theCitedTextText to theCitedTextText & "%20"
			end if
		end repeat
		set searchCitationLink to " (<a href=\"" & (the reference URL of thisItem as string) & "?search=" & theCitedTextText & noDecoration & "\">" & " Text " & "</a>)"
		
		(*
			Make a path link for this document
		*)
		set thePathLink to " (<a href=\"file://" & the path of thisItem & noDecoration & "\">" & " File " & "</a>)"
		
		(*
			Make a page link for this page if the document is a pdf
		*)
		if the current page of think window 1 ≠ -1 then
			set pageNumber to ((the current page of think window 1) as string)
			-- 20110212 adjust page number to +1 for printing purposes
			set printPageNumber to " (Pg. " & (((the current page of think window 1) + 1) as string) & ")"
			set thePage to "?page=" & pageNumber
			-- set clickHere to "(Click here - page " & pageNumber & ")"
			set clickHere to "| Page " & pageNumber & " link"
		else
			set thePage to ""
			set clickHere to "| Page Link "
			set printPageNumber to "<b><i> (no page - source is not PDF)</i></b>"
		end if
		set theURL to (the reference URL of thisItem as string) & thePage
		set thePageLink to " (<a href=\"" & theURL & noDecoration & "\">" & " Page " & "</a>)"
		
		(*
			Compile all these elements and prepare the annotation
		*)
		set theAnnotation to "<p><b>" & thePrefix & "</b> " & thePageLink & searchCitationLink & thePathLink & "</p>" & "<p>" & theCitedText & printPageNumber & "</p>" & "<b><i>Notes:</i></b><br>" & "<p>" & theNote & "</p>" & "<b><i>Tags:</i></b><br>" & "<p>" & theTagPrompt & "</p>"
		
		if preferRTF then
			set o_theAnnotation to (do shell script "echo " & quoted form of theAnnotation & " | textutil -format html -convert rtf -stdin -stdout")
		else
			set o_theAnnotation to theAnnotation
		end if
		
		
		(*
			Create the annotation document
		*)
		set theAnnotationDocument to create record with {URL:theURL, name:theAnnotationName, source:o_theAnnotation, type:rtf} in display group selector
		
		(*
			Add the tags to the annotation document
		*)
		set {od, AppleScript's text item delimiters} to {AppleScript's text item delimiters, ";"}
		set theTags to text items of theTagPrompt
		set tags of theAnnotationDocument to (parents of theAnnotationDocument) & theTags
		set AppleScript's text item delimiters to od
		
	on error error_message number error_number
		if the error_number is not -128 then display alert "DEVONthink Pro" message error_message as warning
	end try
	
end tell


1 Like

A very useful script, thanks Korm. :smiley:

Thanks! Is it too much trouble to add a version of the script for RTF output?

Also is there any chance you could modify this to exclude the help dialogue boxes and just have it create a note per quote?

I would prefer to tag after the note is created because the dialogue box does not offer previous tag suggestions.

Also I would prefer to add extra reading notes to the quote once the note file has been created because then I can reflect on the quoted text more easily.

The note could also be auto-named as the pdf preceded by a number that corresponds in increments of one to allow for the addition of new quotations as needed.

Fantastic script.

I’ll say it again - you need to write that book! :wink:

That’s an :bulb: I would buy it.

Revised v2 20150601

This had been superseded by later more robust versions. See later in thread

Here is an updated version of Korm’s script which allows for multiple annotations to the same document to be easily referenced.

Clicking the URL field of annotated document will bring up a separate tag view containing all the documents which have annotated the original document. Create a tag called “annotations” in the tags folder before using the script

Its based on Korm’s ideas in this thread:
[url]manually cross-linking & adding rich text notes to items?]


(* Original script by Korm

modified by Frederiko using Korm's ideas for multiple annotations using tags: https://discourse.devontechnologies.com/t/manually-cross-linking-adding-rich-text-notes-to-items/17667/12


Usage:
Create a tag called "annotations" in the tags folder. All the tags will be stored underneath that tag avoiding tag bloat.
*)

property noDecoration : "\" style=\"text-decoration:none;"
property preferRTF : true

tell application id "DNtp"
		
		(*
         Select a single document
      *)
		set thisItem to content record of think window 1
		set thisItemUUID to (uuid of thisItem) as string
		
		(*
         Get selected citation text
      *)
		--set theCitedText to selected text of think window 1
		--if theCitedText is "" then error "Please select some text"
		
		set theCitedText to the (selected text of think window 1 as string)
		if theCitedText is "" then error "Please select some text"
		
		
		
		(*
         Create a prefix for the annotation otherwise use the name of this item
         Use case: create a text annotation in the document with the same text as the prefix
         You will find the prefix on the clipboard so add it immediately after this dialog ends
      *)
		set thePrefix to text returned of (display dialog "Annotation Prefix:" with title "Annotation Prefix" default answer "")
		if thePrefix is not "" then
			set theName to thePrefix & " " & the name of thisItem
			tell application "System Events"
				set the clipboard to (thePrefix as text)
			end tell
		else
			set theName to the name of thisItem
		end if
		
		(*
         Get a note for this clipping
      *)
		set theNote to text returned of (display dialog "Notes for this clipping:" with title "Notes" default answer "[none]")
		
		(*
         Get tags for the annotation document
      *)
		repeat
			set theTagPrompt to display name editor "Add Tags" info "Tags (separated by semicolons):"
			if theTagPrompt is not "" then exit repeat
		end repeat
		
		
		(*
		Adds the uuid of the document and adds it as a tag to the annotation document
		*)
		
		try
			
			set annotationURL to (the reference URL of (the child named thisItemUUID of (the tag group named "annotations" of the current database)))
		on error
			
			set theRecord to (create record with {name:thisItemUUID, type:group} in tag group named "annotations" of current database)
			set annotationURL to the reference URL of theRecord
			
		end try
		
		set theTagPrompt to (theTagPrompt & ";" & thisItemUUID)
		
		(* Get a name for the annotation document
      *)
		set theAnnotationName to text returned of (display dialog "Name for this annotation file" with title "Annotation File Name" default answer (thePrefix & ": " & the name of thisItem))
		
		(*
         Make a text-search link for this citation
      *)
		if number of words of theCitedText is greater than 5 then
			set maxWords to 5
		else
			set maxWords to number of words of theCitedText
		end if
		set thisWord to 1
		set theCitedTextText to ""
		repeat while thisWord is less than or equal to maxWords
			set theCitedTextText to theCitedTextText & word thisWord of theCitedText
			set thisWord to thisWord + 1
			if thisWord is less than or equal to maxWords then
				set theCitedTextText to theCitedTextText & "%20"
			end if
		end repeat
		set searchCitationLink to " (<a href=\"" & (the reference URL of thisItem as string) & "?search=" & theCitedTextText & noDecoration & "\">" & " Text " & "</a>)"
		
		(*
         Make a path link for this document
      *)
		set thePathLink to " (<a href=\"file://" & the path of thisItem & noDecoration & "\">" & " File " & "</a>)"
		
		(*
         Make a page link for this page if the document is a pdf
      *)
		if the current page of think window 1 ≠ -1 then
			set pageNumber to ((the current page of think window 1) as string)
			-- 20110212 adjust page number to +1 for printing purposes
			set printPageNumber to " (Pg. " & (((the current page of think window 1) + 1) as string) & ")"
			set thePage to "?page=" & pageNumber
			-- set clickHere to "(Click here - page " & pageNumber & ")"
			set clickHere to "| Page " & pageNumber & " link"
		else
			set thePage to ""
			set clickHere to "| Page Link "
			set printPageNumber to "<b><i> (no page - source is not PDF)</i></b>"
		end if
		set theURL to (the reference URL of thisItem as string) & thePage
		set thePageLink to " (<a href=\"" & theURL & noDecoration & "\">" & " Page " & "</a>)"
		
		(*
         Compile all these elements and prepare the annotation
      *)
		set theAnnotation to "<p><b>" & thePrefix & "</b> " & thePageLink & searchCitationLink & thePathLink & "</p>" & "<p>" & theCitedText & printPageNumber & "</p>" & "<b><i>Notes:</i></b><br>" & "<p>" & theNote & "</p>" & "<b><i>Tags:</i></b><br>" & "<p>" & theTagPrompt & "</p>"
		
		if preferRTF then
			set o_theAnnotation to (do shell script "echo " & quoted form of theAnnotation & " | textutil -format html -convert rtf -stdin -stdout")
		else
			set o_theAnnotation to theAnnotation
		end if
		
		
		(*
         Create the annotation document
      *)
		set theAnnotationDocument to create record with {URL:theURL, name:theAnnotationName, source:o_theAnnotation, type:rtf} in display group selector
		
		(*
         Add the tags to the annotation document
      *)
		set {od, AppleScript's text item delimiters} to {AppleScript's text item delimiters, ";"}
		set theTags to text items of theTagPrompt
		set tags of theAnnotationDocument to (parents of theAnnotationDocument) & theTags
		set AppleScript's text item delimiters to od
		
		(*
		Sets the URL of the document to the reference URL of the tag. 
		*)
		
		set URL of thisItem to annotationURL
		
		
	on error error_message number error_number
		if the error_number is not -128 then display alert "DEVONthink Pro" message error_message as warning
	end try
	
end tell

[edit] Script now tags all annotations in the “annotations tag” so the tag folder is not burdened by hundreds of pointless tags. You should never have to go to the annotations tag because you would invariably get to the relevant tag when you click the annotated documents URL field
[edit] Removed reliance on having selected item highlighted. This could cause inconsistent results when using the back button. Now the annotated document is always derived from the active windo

Frederiko

Much obliged Frederiko, for the extra work - and as always, korm, for the initial work and effort!

I apologise for being that person - but with the integration and changes to quite a few scripts, I must confess to not being entirely sure if I am implementing this correctly… Could you kindly verify?

1.) Open the PDF you want to have annotations linked to - select text.
2.) Invoke the script, complete all (if desired) the fields [prefix/sufffix/note/tag etc] - select the place where it is to be stored
3.) Find the newly-created file - find the newly created tag with the unique identifier.
4.) Copy that tag - and apply it/copy it, to any other files you want linked/grouped to the master file.
5.) When the master file is opened, clicking on the link - opens up the new window, displaying all the related files?

Is that correct? Very useful – just wanted to be sure I wasn’t missing something!

Revised v2, above

Hello Cassady,

I understand, I am having to go back and rework this modification into about 10 of my scripts because it seems so useful.

Correct

Correct

There is no need for this step. Everytime you make an annotation to a master document with this script that annotation will be added to the correct tag group.

Clicking the annotation URL (at the top of the master document) will bring up the tag view of all the linked annotations. See my answer to your step four, for an easier way to get the relevant identifying tag for the master document.

If you want to add files that are linked to the master document, and they have not been added with this script, I would use the following script to copy the master file’s uuid (which is also the tag). You can then simply paste this into the tag field of any document you want to link to the master file.

tell application id "DNtp"
	if the current page of think window 1 = -1 then
		set the clipboard to (the uuid of (the first item of (selection as list)) as string)
	else
		set thecontentrecord to content record of think window 1
		set the clipboard to (the uuid of thecontentrecord) as string
	end if
	
end tell

[edit code fixed so it works now]

(this copies the uuid from the active window rather than the selection, which invariably is what you want)

Correct

(please all see the modified script that I have posted above since your posting)

Korm’s script is really very modifiable. So for example one variation of the script I use replaces the dialog box requesting a prefix with an automatic prefix of the page number from the master document. It also replaces the dialog box for file name by making the filename the first 10 words of the selection. This works very well with the tag view because you instantly get a pretty good idea if the particular page and cited text has been annotated before. I also don’t have a need to include the tags in the annotation so I can eliminate this step.

Frederiko

Re: Peter100’s request to open the new RTF in order to take additional notes (and add groups/tags), you could look at a slightly different take that I recently asked about on an older thread: New rtf doc from selected text with URL to pdf
Look in particular at korm’s modified code (Aug 19).
That code has you select PDF text (or, I discovered, just a page or part of a page if it’s an image-only PDF), then it creates a new RTF file in the group you assign, pastes the selected text into the RTF and adds a URL link from the RTF back to the PDF page, and then opens the RTF so you can take more notes (side by side with the original if you want). You can add other tweaks as well: add the summary filename to the body for the AI…

That thread’s code doesn’t include the autonumbering and automatic annotation tag that this thread’s code has, just the group assignment. If you prefer the other features of this code, I’d guess you could add them to that code or add something similar to this thread’s code. For example:

  1. set theAnnotationDocument to create record…
  2. open window for record theAnnotationDocument

So many ways to skin a cat. If your analysis requires fine gradations in your notes, a single document needs to be broken up into a lot of separate notes (the venerable “one thought, one note” note-card method).

It’d be nice if Devonthink could include a couple different models (i.e. scripts) for note-taking, or at least offer a variation on the current Annotation model, which only allows one annotation file per PDF. I know lots of historians who would be interested in that functionality, but will never dive into Applescript, or this forum.

@korm & @Frederiko:

I’ve unfortunately been too snowed under of late to even give things a proper go, but will soon.

Regardless, didn’t sit right with me that I popped up, asked a bunch of questions - and had them answered - only to disappear again: so here be a quick thanks for the effort put in above.

@ostwaldj

I agree. It has puzzled me that gts’ fantastic QuoteHighlight&Annotate Script (despite dating back to 2010) ([url]QuoteHighlight&Annotate script]) has never made into the default install. It is just obviously so much of an advance on the default annotation template. Instead it has been buried on the forums where only the most dedicated will find it. At the very least the thread should have been made sticky. I think unfortunately the same will happen to this thread. Korm’s insight into breaking up annotation and attaching multiple annotations to a single document would be of huge benefit to researchers, academics and lawyers (who I suspect are the three heaviest users of DT). It is a significant improvement over what has gone before.

Frederiko

Revised v2 above

I’ve been a long time lurker in these forums, but I made an account just to agree with the above. That annotation script is pretty much why I use Devonthink. Not just for itself, but for the workflow that it helped me create.

Devonthink is an incredibly powerful program, but guiding that power is not easy. That script helped me more than anything else.

Inspired by korm’s work to build a better interface for the annotation template using keyboard maestro, here is an advanced annotation template that doesn’t require km. Like the most recent versions it uses tags to allow multiple annotations to a single document.

Annotation with date.jpg

This script has a few advantages over previous scripts:
a) You can edit the cited text at the time of making the annotation
b) You can choose to open the annotation document immediately after doing the annotation.
c) You can set the creation date of the annotation. If the annotation box check box is ticked the default creation date of the annotation is the same as that of the document.
d) The notes field can be copied to the spotlight comment field.
e) It cleans up the cited text by removing any non alpha-numeric text.

(c and d are especially useful for creating chronologies)

Just unzip and drop the script bundle into your devonthink scripts directory (taking note of korm’s advice below if you have a problem).

Credits:
The core of the code is korm’s code used in his keyboard maestro script.
The gui is built with Carsten Blüm’s Pashua (http://www.bluem.net/en/mac/pashua/), and the Pashua runtime is included in the bundle.

[edit]
v1.1 Search link works properly; the document being annotated is the frontmost document rather than the selected document; c & d added.
Quick annotate with group tagging v1.1.scptd.zip (264 KB)

Revised v2 above

Updated

Thanks to everyone for this thread. I (naively?) thought that the ability to take, and sort, and link notes about documents was the main rationale for Devonthink as a research tool. But until I found this thread, I was unable to figure out how to do it. The manual has 238 mentions of “link,” but I could not find a coherent explanation of how to create cross-links among master/related documents. (e.g. a tutorial. See below for a partial answers.)

In any case, I think with these threads I will be able to figure this out, with “only” another hour or two of effort. Since I’m just a trial user of DT, it may make the difference between buying it, and giving up.

Now I suggest, echoing earlier comment, that this information be pulled into a sticky thread, and ultimately into a PDF tutorial. For other newbies, here are the threads I’ve found that are key.
Removed Macro for Keyboard Maestro
QuoteHighlight&Annotate script
posting.php?mode=reply&f=20&t=18885 (this thread)
manually cross-linking & adding rich text notes to items?
Mystified by Annotation - is there a plain-language tutorial A useful tutorial on how to use all this.
Related:
A useful discussion of how to structure documents in a DB and use “see also” to find links. Someone else's use of AI

Finally, the bibliography manager Bookends has some of this capability. Every referenced document can have an unlimited number of “notes” which are tied to that document. The notes can be tagged individually. And when you highlight a passage in a PDF, it automatically creates a note containing the highlighted text. Of course, Bookends is specialized and much less flexible.
(All errors and omissions in this message are mine. I’m just starting to figure this out. If someone who does understand these issues would summarize the essentials, we would all be grateful.)

2 Likes

@ R^2_is_misleading: Stick with it. DT is complex because of its freeform nature. When it all clicks together I haven’t found any other piece of software which remotely compares.

How annotations work

An annotation contains several links to the page in the document that is being annotated. (If its a pdf, otherwise just to the document)
a) In the Url field;
b) In the Hyperlink in the document called Page;
c) In the Hyperlink in the document called Text.

The annotation can also be reached under any of the Tag groups which reference it.

Annotation_Document.jpg

All the annotations to an original document can be reached by clicking on the URL link at the top of the document. This brings up a separate window with a list of all the annotations to the document. (technically its the tag group hidden under the tag group annotations but you should never have to worry or look in that tag group)

linking tag group.jpg

I hope this is helpful.
Fredriko

(There are some interesting posts on the bookend forum on integrating bookends annotations with DT https://www.sonnysoftware.com/phpBB3/viewtopic.php?f=6&t=3465