and an additional condition as described by @dansrokahere.
Now that I finally wrote it I know again why I started and stopped trying to write it several times: It’s unbelievable hard to write a script and to remember to copy a link again before the next test run. In the end I used a macro that automatically copied the link after each error
-- Modify x-devonthink item links to reveal records
use AppleScript version "2.4"
use framework "Foundation"
use framework "AppKit"
use scripting additions
try
set thePasteboard to current application's NSPasteboard's generalPasteboard()
set thisPasteboardItem to (thePasteboard's pasteboardItems())'s objectAtIndex:0
set thisPasteboardItem_Types to thisPasteboardItem's |types|()
set theDataArray to current application's NSMutableArray's arrayWithArray:{}
repeat with i from 0 to (thisPasteboardItem_Types's |count|()) - 1
set thisType to (thisPasteboardItem_Types's objectAtIndex:i)
if (thisType's isEqualTo:"dyn.ah62d4rv4gu8zs3pcnzme2641rf4guzdmsv0gn64uqm10c6xenv61a3k") then
set thisPropertyList to (thisPasteboardItem's propertyListForType:thisType)
set thisPropertyList_firstObject to (thisPropertyList's firstObject())
repeat with j from 0 to (thisPropertyList_firstObject's |count|()) - 1
(thisPropertyList_firstObject's replaceObjectAtIndex:j withObject:(((thisPropertyList_firstObject's objectAtIndex:j)'s stringByAppendingString:"?reveal=1")))
end repeat
(thisPropertyList's replaceObjectAtIndex:0 withObject:thisPropertyList_firstObject)
(theDataArray's addObject:(current application's NSPropertyListSerialization's dataWithPropertyList:thisPropertyList ¬
|format|:(current application's NSPropertyListXMLFormat_v1_0) options:0 |error|:(missing value)))
else if (thisType's isEqualTo:"dyn.ah62d4rv4gu8yc6durvwwaznwmuuha2pxsvw0e55bsmwca7d3sbwu") then
set thisPropertyList to (thisPasteboardItem's propertyListForType:thisType)
(thisPropertyList's replaceObjectAtIndex:(0) withObject:(thisPropertyList's firstObject()'s stringByAppendingString:"?reveal=1"))
(theDataArray's addObject:(current application's NSPropertyListSerialization's dataWithPropertyList:thisPropertyList ¬
|format|:(current application's NSPropertyListXMLFormat_v1_0) options:0 |error|:(missing value)))
else
set theString to (thisPasteboardItem's stringForType:thisType)
if (theString's hasPrefix:"x-devonthink") then
set theStrings to (theString's componentsSeparatedByString:linefeed)
repeat with j from 0 to (theStrings's |count|()) - 1
set thisString to (theStrings's objectAtIndex:j)
if not (thisString's isEqualTo:"") then
set thisString to (thisString's stringByAppendingString:"?reveal=1")
try
(theStrings's replaceObjectAtIndex:j withObject:thisString)
on error
set theStrings to (current application's NSArray's arrayWithArray:{thisString})
end try
end if
end repeat
set newString to (theStrings's componentsJoinedByString:linefeed)
(theDataArray's addObject:(newString's dataUsingEncoding:(current application's NSUTF8StringEncoding)))
else
(theDataArray's addObject:(thisPasteboardItem's dataForType:thisType))
end if
end if
end repeat
thePasteboard's clearContents()
repeat with i from 0 to (theDataArray's |count|()) - 1
(thePasteboard's setData:(theDataArray's objectAtIndex:i) forType:(thisPasteboardItem_Types's objectAtIndex:i))
end repeat
on error error_message number error_number
display alert "Error: \"Hmm\"" message error_message as warning
return
end try
Wow, thank you very much for this! In my testing so far, using a Keyboard Maestro shortcut, it has worked exactly as hoped.
You have obviously gone down further into the rabbit hole of using Foundation classes in AppleScript than I have . Thanks for taking the time to write this and posting it.
I have it running via KM triggered by a hot key combination. To have it run when you copy the item link via menu, would you recommend having KM trigger when “the system clipboard changes”?
I found that in my attempt at this, the script modifying the clipboard would trigger the script over and over. So I added an additional condition to stop it:
-- Modify x-devonthink item links to reveal records
use AppleScript version "2.4"
use framework "Foundation"
use framework "AppKit"
use scripting additions
set theClipboard to (the clipboard) as string
if theClipboard starts with "x-devonthink" and theClipboard does not contain "&?reveal=1" then
try
set thePasteboard to current application's NSPasteboard's generalPasteboard()
set thisPasteboardItem to (thePasteboard's pasteboardItems())'s objectAtIndex:0
set thisPasteboardItem_Types to thisPasteboardItem's |types|()
set theDataArray to current application's NSMutableArray's arrayWithArray:{}
repeat with i from 0 to (thisPasteboardItem_Types's |count|()) - 1
set thisType to (thisPasteboardItem_Types's objectAtIndex:i)
if (thisType's isEqualTo:"dyn.ah62d4rv4gu8zs3pcnzme2641rf4guzdmsv0gn64uqm10c6xenv61a3k") then
set thisPropertyList to (thisPasteboardItem's propertyListForType:thisType)
set thisPropertyList_firstObject to (thisPropertyList's firstObject())
repeat with j from 0 to (thisPropertyList_firstObject's |count|()) - 1
(thisPropertyList_firstObject's replaceObjectAtIndex:j withObject:(((thisPropertyList_firstObject's objectAtIndex:j)'s stringByAppendingString:"&?reveal=1")))
end repeat
(thisPropertyList's replaceObjectAtIndex:0 withObject:thisPropertyList_firstObject)
(theDataArray's addObject:(current application's NSPropertyListSerialization's dataWithPropertyList:thisPropertyList ¬
|format|:(current application's NSPropertyListXMLFormat_v1_0) options:0 |error|:(missing value)))
else if (thisType's isEqualTo:"dyn.ah62d4rv4gu8yc6durvwwaznwmuuha2pxsvw0e55bsmwca7d3sbwu") then
set thisPropertyList to (thisPasteboardItem's propertyListForType:thisType)
(thisPropertyList's replaceObjectAtIndex:(0) withObject:(thisPropertyList's firstObject()'s stringByAppendingString:"&?reveal=1"))
(theDataArray's addObject:(current application's NSPropertyListSerialization's dataWithPropertyList:thisPropertyList ¬
|format|:(current application's NSPropertyListXMLFormat_v1_0) options:0 |error|:(missing value)))
else
set theString to (thisPasteboardItem's stringForType:thisType)
if (theString's hasPrefix:"x-devonthink") then
set theStrings to (theString's componentsSeparatedByString:linefeed)
repeat with j from 0 to (theStrings's |count|()) - 1
set thisString to (theStrings's objectAtIndex:j)
if not (thisString's isEqualTo:"") then
set thisString to (thisString's stringByAppendingString:"&?reveal=1")
try
(theStrings's replaceObjectAtIndex:j withObject:thisString)
on error
set theStrings to (current application's NSArray's arrayWithArray:{thisString})
end try
end if
end repeat
set newString to (theStrings's componentsJoinedByString:linefeed)
(theDataArray's addObject:(newString's dataUsingEncoding:(current application's NSUTF8StringEncoding)))
else
(theDataArray's addObject:(thisPasteboardItem's dataForType:thisType))
end if
end if
end repeat
thePasteboard's clearContents()
repeat with i from 0 to (theDataArray's |count|()) - 1
(thePasteboard's setData:(theDataArray's objectAtIndex:i) forType:(thisPasteboardItem_Types's objectAtIndex:i))
end repeat
on error error_message number error_number
display alert "Error: \"Modify x-devonthink item links to reveal records\"" message error_message as warning
return
end try
end if
The script manipulates what DEVONthink had put on the pasteboard. The script’s output works the same way as an unmanipulated DEVONthink link works, i.e. if you get an RTF link in app A then you’ll also get an RTF link with the script - only difference is that it reveals the record.