For any future reference, here is a script that performs the BibDesk-DEVONthink automation described above. Thanks to all contributors to this thread for their tips.
In brief, the script accepts selected BibDesk items as input. For every DEVONthink-imported or -indexed attachment in this collection of items, it adds the attachment’s x-devonthink-item URI in a Devonthink field (or DevonthinkN, if N>1) of the respective BibDesk item.
The script enables me to open these attachments directly from my BibLaTeX bibliography manager, both on the Mac (BibDesk) and the iPad (References app).
Any suggestions for improving the script would be warmly welcome. (It is noticeably slow when numerous bibliography items and/or attachments are involved.)
-- Declare global variable for logging
global logFilePath
-- Set log file path
set logFilePath to POSIX path of (path to desktop folder) & "BibDesk-DEVONthink-log.txt"
-- Function to log messages using shell with timestamp
on logMessage(theText)
set timeStamp to do shell script "date '+%Y-%m-%d %H:%M:%S'"
do shell script "echo " & quoted form of ("[" & timeStamp & "] " & theText) & " >> " & quoted form of logFilePath
end logMessage
-- Activate BibDesk
tell application "BibDesk" to activate
delay 0.3
-- Initialize counters
set totalUpdates to 0
set summaryText to ""
-- Access selection from BibDesk
tell application "BibDesk"
if not (exists document 1) then
display dialog "No BibDesk document is open." buttons {"OK"} default button "OK"
return
end if
set theDoc to document 1
try
set selectedPubs to selection of theDoc
if selectedPubs is {} then
display dialog "No references selected in BibDesk." buttons {"OK"} default button "OK"
return
end if
on error
display dialog "Could not retrieve selection. Please make sure the main BibDesk window is frontmost and items are selected." buttons {"OK"} default button "OK"
return
end try
repeat with thisPub in selectedPubs
set pubTitle to title of thisPub
set theAttachments to linked files of thisPub
set addedCount to 0
repeat with thisFile in theAttachments
set filePath to POSIX path of thisFile
set refURL to ""
set foundInDevon to false
with timeout of 600 seconds
tell application id "DNtp"
try
if current database is missing value then
my logMessage("❌ No DEVONthink database is open.")
display dialog "No DEVONthink database is open." buttons {"OK"} default button "OK"
return
end if
set theDatabase to current database
set theMatches to (contents of theDatabase whose path = filePath)
if (count of theMatches) > 0 then
set theRecord to first item of theMatches
set refURL to reference URL of theRecord
set foundInDevon to true
else
my logMessage("NOT FOUND: " & filePath & " (BibDesk: " & pubTitle & ")")
end if
on error errMsg
my logMessage("ERROR: " & errMsg & " for file " & filePath & " (BibDesk: " & pubTitle & ")")
end try
end tell
end timeout
if foundInDevon then
tell thisPub
-- Check if refURL already exists
set refAlreadyExists to false
set devonIndex to 1
repeat while devonIndex ≤ 50
if devonIndex = 1 then
set fieldName to "Devonthink"
else
set fieldName to "Devonthink" & devonIndex
end if
if exists field fieldName then
set existingVal to value of field fieldName
if existingVal is equal to refURL then
set refAlreadyExists to true
exit repeat
end if
else
exit repeat
end if
set devonIndex to devonIndex + 1
end repeat
-- If not already present, add to first empty field
if refAlreadyExists is false then
set devonIndex to 1
repeat while devonIndex ≤ 50
if devonIndex = 1 then
set fieldName to "Devonthink"
else
set fieldName to "Devonthink" & devonIndex
end if
if not (exists field fieldName) then
make new field with properties {name:fieldName}
set value of field fieldName to refURL
set addedCount to addedCount + 1
exit repeat
else
set existingVal to value of field fieldName
if existingVal is missing value or existingVal is "" then
set value of field fieldName to refURL
set addedCount to addedCount + 1
exit repeat
end if
end if
set devonIndex to devonIndex + 1
end repeat
end if
end tell
end if
end repeat
if addedCount > 0 then
set totalUpdates to totalUpdates + addedCount
set summaryText to summaryText & "• “" & pubTitle & "”: added " & addedCount & " link(s)" & linefeed
end if
end repeat
end tell
-- Show summary
if totalUpdates > 0 then
display dialog "✅ Added " & totalUpdates & " DEVONthink link(s)." buttons {"OK"} default button "OK"
else
display dialog "No new DEVONthink links were added." buttons {"OK"} default button "OK"
end if