Script creating annotation file works differently for JPEG and JPG images

I adapted one of the smart templates (both the template itself and the script) for creating an annotation file and installed it in my toolbar. It is supposed to save the annotation file record to the (indexed) folder containing the file I’m annotating, that is to the “first parent” of the selected file (theFrontmostDocument, set earlier in the script).

set theParents to parents of theFrontmostDocument
			set theFirstParent to item 1 of theParents
			set theRecord to import theTemplateFiles placeholders {|%documentFilename%|:theFrontmostDocumentFilename, |%documentLink%|:{|URL|:theFrontmostDocumentURL, |name|:"View document"}, |%documentURL%|:theFrontmostDocumentURL, |%documentTags%|:theFrontmostDocumentTags, |%documentCreationDate%|:short date string of theFrontmostDocumentCreationDate} to theFirstParent

This works for an annotation to a pdf file or a png image, or an image with the “jpeg” extension – it is saved in the same location as the original file. However, if the extension is “jpg” then the annotation file is saved in the database’s Inbox. Since both extensions are correctly identified by DT as Kind “JPEG image”, why doesn’t the script work correctly for a “jpg”?

What template is this based on?

Not sure what the name was or where I found it (I suspect probably here on the forums), but the header read:

– Smart template adding a localized annotation for a shown document
– Written by Eric Böhnisch-Volkmann, modified by Christian Grunenberg
– © 2009—2016 DEVONtechnologies, LLC

Why are you using a smart template for creating an annotation file? There is already a directory to contain your annotation file templates.

And there is the Preferences > General > General > Annotations dropdown to control where they’re created.

-- The non-localized default name of the new quote
property pTemplateName : "Annotation-Note"
-- property pSmartGroup : "Annotations"


-- Import helper library
tell application "Finder" to set pathToAdditions to ((path to application id "DNtp" as string) & "Contents:Resources:Template Script Additions.scpt") as alias
set helperLibrary to load script pathToAdditions
set pathToLocalizedResources to my helperLibrary's pathToLocalizedResources()

set od to AppleScript's text item delimiters
set AppleScript's text item delimiters to {", "}

try
	tell application id "DNtp"
		
		-- If a document was frontmost when activating the smart template get its item link
		
		if exists (content record) then
			set theFrontmostDocument to content record
		else if (count of the selection) is 1 then
			set theFrontmostDocument to item 1 of ((the selection) as list)
		else
			error "No document shown. Please select a document, then try again."
		end if
		set theFrontmostWindow to think window 1
		set theFrontmostDocumentURL to ("x-devonthink-item://" & uuid of theFrontmostDocument) as string
		set theFrontmostDocumentName to name without extension of theFrontmostDocument as string
		set theFrontmostDocumentFilename to filename of theFrontmostDocument as string
		set theFrontmostDocumentTags to tags of theFrontmostDocument as string
		set theFrontmostDocumentCreationDate to creation date of theFrontmostDocument
		
		
		-- Check if an annotation already exists
		-- If yes, simply open the annotation and return
		set theRecord to (the annotation of theFrontmostDocument)
		if (the annotation of theFrontmostDocument) exists then
			open tab for record theRecord
		else
			
			-- Import the predefined document
			set theTemplateFiles to my helperLibrary's pathToLocalizedResources & pTemplateName & ".rtf" as string
			set theParents to parents of theFrontmostDocument
			set theFirstParent to item 1 of theParents
			set theRecord to import theTemplateFiles placeholders {|%documentFilename%|:theFrontmostDocumentFilename, |%documentLink%|:{|URL|:theFrontmostDocumentURL, |name|:"View document"}, |%documentURL%|:theFrontmostDocumentURL, |%documentTags%|:theFrontmostDocumentTags, |%documentCreationDate%|:short date string of theFrontmostDocumentCreationDate} to theFirstParent
			
			
			-- Add the document tags to the annotation
			set the tags of theRecord to theFrontmostDocumentTags
			
			-- Adjust name and date of the annotation
			set the name of theRecord to (theFrontmostDocumentName & " (Note)")
			set the creation date of theRecord to theFrontmostDocumentCreationDate
			
			-- Finally, add the note's item link to the annotated document's URL field if possible
			if type of theFrontmostDocument is not bookmark and type of theFrontmostDocument is not feed then
				if URL of theFrontmostDocument ≠ "" then
					set theComment to comment of theFrontmostDocument
					if theComment ≠ "" then set theComment to theComment & return
					set theComment to theComment & "Original URL: " & (URL of theFrontmostDocument)
					set comment of theFrontmostDocument to theComment
				end if
				set URL of theFrontmostDocument to ("x-devonthink-item://" & uuid of theRecord) as string
			end if
			
		end if
		
		-- open tab for record theRecord in think window 1
		open window for record theRecord
		
		set AppleScript's text item delimiters to do
		
	end tell
	
on error errMsg number errNum
	set AppleScript's text item delimiters to do
	display alert "An error occured when adding the annotation." message errMsg as warning
end try

Thanks but see my amended previous reply.

Simple Rich Text.rtf (616 Bytes) put into…

~/Library/Application Support/DEVONthink 3/Annotations.noindex/

Because I wanted certain customizations that I didn’t seem to be able to accomplish with a normal template (e.g., setting the annotation file creation date to that of the original file and appending “(Note)” instead of “(Annotation)” to the filename), and I wanted to be able to trigger it from the toolbar.

I do have the preference set to create annotations in the current folder, but AFAIK that only applies to annotations made through the normal route, not those created by a custom script.

There’s a bunch of unnecessary overhead in that older code. Here is a simple learning edition example that does the same essential thing…

set rsrc to ((path to me as string) & "Contents:Resources:Documents:") as string

tell application id "DNtp"
	if (count (selected records)) is not 1 then return
	
	set sel to (selected record 1)
	if exists (annotation of sel) then
		open tab for record (annotation of sel)
		return
	else
		tell sel
			set recLocGroup to location group
			set recURL to reference URL
			set recName to name without extension
			set recTags to tags
			set recComment to comment
			set cDate to creation date
		end tell

		set annotationDoc to import (rsrc & "%recName% (Note).rtf" as string) placeholders {|%recName%|:recName, |%documentLink%|:{|URL|:recLink, |name|:recName}, |%recordTags%|:my tagsToString(recTags), |%recordCreationShortDate%|:short date string of cDate} to recLocGroup
		set tags of annotationDoc to recTags
		set comment of annotationDoc to recComments
        set creation date of sel to cDate
		set annotation of sel to annotationDoc
		open window for record annotationDoc
	end if
end tell

on tagsToString(theTags) -- Tags are a list so they must be coerced to a string if used in the document's text.
	set od to AppleScript's text item delimiters
	set AppleScript's text item delimiters to ", "
	set tempText to (text items of theTags) as string
	set AppleScript's text item delimiters to od
	return tempText as string
end tagsToString

And there is no issue when using this with any kind of document.

OK, thanks, I’ll give this approach a try. But I have a question about the “set rsrc” statement at the start. What exactly does this do? Assuming that “me” here means the templatescriptd package, there is no Documents folder in Contents: Resources. How does the script get the name of the rtf template? In the smart template packages I have looked at, the template file is in an en.lproj folder. Just trying to relate this code to what I’ve been working with so far.

(By the way, any idea yet why my script doesn’t work correctly with jpg-extension files?)

But I have a question about the “set rsrc” statement at the start. What exactly does this do?

It targets the script’s Resources directory.

Assuming that “me” here means the templatescriptd package, there is no Documents folder in Contents: Resources.

Directories can be added, deleted, or modified as needed.

How does the script get the name of the rtf template?

It’s hardcoded into the script.

In the smart template packages I have looked at, the template file is in an en.lproj folder.

That would be for a localized version, e.g., if you were running DEVONthink in German you’d put things in a de.lproj directory.

(By the way, any idea yet why my script doesn’t work correctly with jpg-extension files?)

I didn’t specifically test it as it’s old and unoptimized code so I opted to present you with a more optimal and updated approach to learn from.

Here is the smart template I built from scratch:
Annotation File.templatescriptd.zip (9.1 KB)

It took some effort, but I finally tweaked it to work as I needed. Thank you for providing a smart template example pared down to basics – it can be difficult to determine what of the structure and code in the supplied templates is necessary and what is optional. (E.g., the localization stuff.) Some of us need a bit more guidance than “copy one of the packages as a base for building your own.”

For reference, in case anyone else wants to build on Jim’s sample, I ran into a couple of issues:

  • In the “set … to import” code, the %documentLink% placeholder references the variable recLink, which has not been initialized.
  • “set creation date of sel to cDate” should read “set creation date of annotationDoc to cDate”. (cDate is the creation date of sel.)
  • I wanted the reference URL of the annotation to be copied into the URL field of the original document, with “set URL of theDoc to reference URL of annotationDoc” (after moving any existing document URL to Comments). It refused to work, until I removed the “set annotation of theDoc to annotationDoc” code. Removing “set annotation” doesn’t seem to affect the behavior of the annotation; for example, Annotations > Remove works normally, so DT recognizes it as an annotation file.
  • The filename of the template file in the Documents folder doesn’t match what is hardcoded into the “import” code. Need to remove " %author%".

That said, it does work correctly with jpg-extension images and deposits the annotation into the same folder as the original. :smile:

You’re welcome and indeed it wasn’t meant as a complete replacement for your template. It was an example for guidance with a better approach and some possible things, hence including things like the %author%. In fact, all of our templates and scripts are provided as modifiable resources to learn from and tweak as needed. (However, we obviously recommend duplicating before modification). :slight_smile: