I’ve recently started using DEVONthink PRO to manage my library of PDFs. Unfortunately, given my current setup, I’m not able to make most of DEVONthink to browse through my library. I’m hoping someone here might be able to help.
My library of PDFs contains a number of files all of which are titled using the corresponding citation key in my main .bib database. Thus, for each PDF in my library titled key.pdf, there’s an entry in my main .bib file with all the necessary metadata (title, author, publication year, etc.).
I’d like to find a way of using the metadata to browse through the library of PDFs using DEVONthink. I can imagine, though I’m not yet in a position to implement, a number of sophisticated position. But perhaps it would be enough to do something like this: For each item in the library, use its title (of the form key.pdf to fetch information from my main .bib file that would then be used to define an alias for the pdf. I would then be able to have a view of my library in DEVONthink that would contain author and title information for each entry.
Does anyone have any hints on how best to go about doing this? Has anyone dealt with a similar situation?
I realize I could just rename files using the metadata, perhaps relying on something like Zotero or BibDesk, but that would not work for me. The main constraint is to have each PDF associated with an entry in my main .bib file named using the format key.pdf where key is, of course, the key corresponding to said entry.
Thanks for your quick reply. The main issue is that the file name does not contain enough information to e.g. order by author or title etc. I realize one could use metadata embedded in the PDF, when available, for browsing. And in a way, that would be ideal—the file name is the last thing I want to know about a PDF in this context. Trouble is, many of the PDFs I have in my library do not have adequate metadata. If I could use my .bib file to populate the metadata of the PDF that would be wonderful, but I do not know how to do that either.
I thought about that, but I know almost nothing about scripting with AppleScript. I’ll take a look and see if I can put something together. Do you off the top of your head know of a good reference where I could learn more about writing to the DT record using applescript? Thanks!
Open your BibTeX file in Bibdesk (a free, open-source bib manager). This script will take the selection in Bibdesk, look for the corresponding PDF file in DEVONthink 3, and sync the metadata. Keep in mind that It will sync only the selected entries in Bibdesk. The DEVONthink database with the PDF file must be open.
use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions
-- Script to link Bibdesk entries to DEVONthink Pro records along with custom metadata - by Bernardo Vasconcelos (2022).
-- Use at your own risk
tell application "BibDesk"
set theSelection to the selection of document 1
repeat with thisItem in theSelection
-- accessing field values
set theID to id of thisItem
set theCitation to cite key of thisItem
--set thePriority to the rating of thisItem as text
set theType to the type of thisItem as text
set theRating to the value of field "rating" of thisItem as text
set theTitle to the value of field "Title" of thisItem
set theAuthor to the name of author of field "Author" of item 1 of theSelection as text
set theAbstract to the value of field "abstract" of thisItem
set theEditor to the value of field "editor" of thisItem
set theTranslator to the value of field "Translator" of thisItem
set thePlace to the value of field "Address" of thisItem
set thePublisher to the value of field "publisher" of thisItem
set theYear to the value of field "Year" of thisItem
set theISBN to the value of field "isbn" of thisItem
set theJournal to the value of field "journal" of thisItem
set theVolume to the value of field "volume" of thisItem
set theIssue to the value of field "volume" of thisItem
set thePages to the value of field "pages" of thisItem
set theDOI to the value of field "doi" of thisItem
set theNotes to the value of field "Annote" of thisItem
set theKeywords to the value of field "keywords" of thisItem
set theLanguage to the value of field "language" of thisItem
set theAttachments to the value of field "attachments" of thisItem
set theURL to the linked URL of thisItem
try
set refVolume to ""
if theVolume is not "" then
set refVolume to " (" & the_volume & ")"
end if
end try
try
set refTranslator to ""
if theTranslator is not "" then
set refTranslator to "Trad.: " & theTranslator & ". "
end if
end try
try
set refEditor to ""
if theEditor is not "" then
set refEditor to "Ed.: " & theEditor & ". "
end if
end try
try
set refArticle to ""
set refArticle to (theAuthor & ". " & theTitle & ". In: " & theJournal & " " & refVolume & theIssue & ", " & theYear & "." & " Pp." & thePages)
end try
try
set refBook to ""
set refBook to (theAuthor & "; " & theTitle & ". " & refEditor & refTranslator & thePlace & ": " & thePublisher & ", " & theYear)
end try
try
set theRef to ""
if (theType = "article") then
set theRef to refArticle
else if (theType = "book") then
set theRef to refBook
end if
end try
end repeat
tell application id "DNtp"
set thePDF to search "filename:" & theCitation & ".pdf"
try
set theRecord to the content record of think window 1
if theRecord is {} then error "Please select some contents."
end try
try
set thePriority to ""
if theRating is "1" then set thePriority to "1️⃣"
if theRating is "2" then set thePriority to "2️⃣"
if theRating is "3" then set thePriority to "🔥"
if theRating is "4" then set thePriority to "🔥🔥"
if theRating is "5" then set thePriority to "🔥🔥🔥"
end try
try
add custom meta data theCitation for "bibkey" to theRecord
add custom meta data thePriority for "Priority" to theRecord
add custom meta data theRating for "rating" to theRecord
add custom meta data theType for "type" to theRecord
add custom meta data theTitle for "title" to theRecord
add custom meta data theAbstract for "abstract" to theRecord
add custom meta data theAuthor for "authors" to theRecord
add custom meta data theEditor for "editor" to theRecord
add custom meta data theTranslator for "translator" to theRecord
add custom meta data thePlace for "Place" to theRecord
add custom meta data thePublisher for "publisher" to theRecord
add custom meta data theYear for "date" to theRecord
add custom meta data theISBN for "is?n" to theRecord
add custom meta data theJournal for "journal" to theRecord
add custom meta data theVolume for "volume" to theRecord
add custom meta data theIssue for "issue" to theRecord
add custom meta data thePages for "page" to theRecord
add custom meta data theDOI for "doi" to theRecord
add custom meta data theRef for "Reference" to theRecord
add custom meta data theNotes for "notas" to theRecord
add custom meta data theKeywords for "keywords" to theRecord
add custom meta data theLanguage for "language" to theRecord
add custom meta data ("x-bdsk://" & theCitation) for "bibdeskurl" to theRecord
add custom meta data theURL for "link2" to theRecord
--set the URL of theRecord to ("x-bdsk://" & theCitation) as text
end try
try
set the aliases of theRecord to theCitation
set the tags of theRecord to theKeywords
set the name of theRecord to theRef
set theDntp_Link to ""
set theDntp_Link to reference URL of theRecord
end try
end tell
end tell
tell application "BibDesk"
set theSelection to the selection of document 1
set the value of field "Local-url" of thisItem to theDntp_Link
end tell
I forgot to say: test it on dummy files first. And keep backups.
You cannot undo changes made by scripts. That is, ⌘Zwon’t work after running the script.
My suggestion is: try with a dummy BibTeX file and dummy PDF files. Just name them as you would name your real files. Then make adjustments to the script to better fit your needs. On the first try, whatever you do, don’t just select your whole library and run it blindly.
In addition to Bibdesk as described above by @Bernardo_V, you could accomplish all of what you described using a combination of Zotero, some Zotero extensions, and additional software and workflows, but getting there will take some time and perseverance. Unlike for Bookends, DEVONthink doesn’t have anything out of the box to support Zotero, but the following may help get a sense of how it could be done:
Renaming your PDFs based on BibTeX citekeys could be achieved in Zotero using a combination of the extensions Better BibTeX and Zotfile. The former generates BibTeX citekeys; the latter can rename/move/reorganize files based on a configuration you define.
In DEVONthink, you can index the folder of PDFs maintained by Zotero, and thus gain ability to search, annotate and mark up the PDFs in DEVONthink, and more.
It is possible to set things up so that the URL field for a PDF in DEVONthink is the Zotero entry, which makes it convenient and quick to jump from DEVONthink to Zotero where you keep full bibliographic information. The DEVONthink keyboard shortcut is ⌃⌘u (“Launch URL”). To make this possible, you have to use a combination of smart rules in DEVONthink and some external software that will communicate with Zotero to get the information. Some postings that describe people’s approaches are this one and this one and also this thread.
It is also possible to store more bibliographic data directly in DEVONthink by defining custom metadata fields. Then, every document (including every external PDF indexed by DEVONthink) can have values for those custom metadata fields. I myself have a setup by which I store BibTeX citekeys, year, and type of reference (journal, book, etc.) in custom fields. Getting those values out of Zotero and into the metadata fields is done using DEVONthink smart rules that run another external tool I’ve been working on. (It’s unfortunately not in a state where other people could easily use, but I hope to get it out there someday soon …) Anyway, my point is that by defining custom fields in DEVONthink to store the data you want, you could achieve better bibliographic handling and integration with other tools – something worth keeping in mind no matter what you use, Zotero or otherwise.
Thanks everyone for your suggestions. I do have the Pro version, so that’s a solution to look into. For now, I came up with a somewhat crude bit of Emacs lisp that does what I need, by passing the metadata to exiftool and writing author and title information on the PDF. If anyone is interested, I’d be happy to share…
OK, for what it’s worth, what I’m doing for now is now up on the Wiki page of Emacs’s citar package—my solution builds on that packages functions, so it only made sense to make it available up there as well.
Here at any rate is the function I’m using:
(defvar ex/citar-library-backup-path "/path/to/library/backup")
(defun ex/update-pdf-metadata-alt (key-entry)
"Add/update metadata of PDF for KEY-ENTRY."
(interactive (list (citar-select-ref)))
(let* ((entry (cdr key-entry))
(key (car key-entry))
(file (car (citar-file--files-for-entry
key
entry
citar-library-paths
'("pdf"))))
(nofile nil)
(title (citar-clean-string (citar-get-value 'title entry)))
(author (cond ((citar-has-a-value '(author) entry)
(citar-get-value 'author entry))
((citar-has-a-value '(editor) entry)
(concat (citar-get-value 'editor entry) " (ed.)")))))
(if (not file)
(print (format "I could not find an PDF file associated with \'%s\'" key))
(progn
(copy-file file my/bib-library-backup-path 1)
(call-process-shell-command
(concat "exiftool -overwrite_original_in_place -Title='" title "' -Author='" author "' " file))))))
@Bernardo_V, this looks very helpful. I was getting an error at first. It wasn’t working when I ran it on a record that was indexed in DT3, but then I resolved the issue by importing the PDF into DEVONthink. It seemed like this script only worked if the PDF has been imported, but then I tried testing it with different PDFs, and I was surprised to discover that it successfully updated the metadata for an indexed file!
I experimented running the script on a handful of different records, but I couldn’t figure out what conditions must be met for it to run successfully. It seems like if I select the records that I want to sync in both DT3 and BibDesk, then it always does what it’s supposed to. But besides that, I can’t figure it out.
I want to modify the script so that if the BibDesk record contains a valid path in the “file” field, DEVONthink will index that path (or find the file if already indexed) and then sync the metadata from BibDesk to the DT3 item. But I’m stumped.
@aaaaaaaaaaaaaaaa, you can use lookup record with path to find a record using a file path. Take a look at the Applescript dictionary or search the forum for this command to find examples. If you remain stumped after trying this, just let us know.