Tips
Hey folks, in this post I'm sharing and explaining a custom script I wrote for DEVONthink that greatly assists me when I'm reviewing large batches of Bates-stamped documents (e.g., administrative records or discovery dumps).
Specifically, this script will:
- copy selected text in a PDF to the clipboard;
- determine the Bates number of the page the selected text is on;
- generate a Markdown-formatted Bates cite for that page linking back to the document, page, and specific passage of text that was selected; and
- append this Bates 'deeplink' to the clipboard.
ⓘ About DEVONthink
DEVONthink is comprehensive document management and productivity software exclusive to macOS that has seen continuous updates, improvements, and new features added for over two decades. The developer calls it "your paperless office." That certainly rings true for me—it's been my go-to work and study app since I first started using it in law school 7 years ago.
Example usage.
Suppose I'm reviewing the file FWS 065382–065397.pdf
near the end of a 75,000-page administrative record (true story).
Suppose I find something really incriminating on the sixth page of that document—a candid email exchange where a staff biologist wrote: "If we do this, Franklin's Bumble Bee will go extinct." (fictitious example).
If I select that sentence in the PDF and use the keyboard shortcut I've assigned to my script, ⇧ + ⌥ + C
, the following is placed in my system clipboard:
"If we do this, Franklin's Bumble Bee will go extinct." [FWS 65387](x-devonthink-item://883C7BE0-A328-4818-A4B5-3AF7E5504135?page=6&start=534&length=53&search=If%20we%20do%20this%2C%20Franklin%27s%20Bumble%20Bee%20will%20go%20extinct.).
With Markdown rendering, that becomes, "If we do this, Franklin's Bumble Bee will go extinct." FWS 65387.
Now, if I open my Markdown editor of choice—Ulysses, Obsidian, or DEVONthink itself depending on the task at hand (more on that in a future post)—and paste (i.e., ⌘ v
), the text I selected, plus the correct Bates cite with a deeplink back to the source sentence in the PDF, is inserted.
I can then at any time simply click the Bates cite and get right back to the exact point in that specific document where the incriminating statement is found.
Deeplinks are neat, right? Let's set it up.
Pre-requisites.
- This tutorial assumes you have a macOS computer with Perl and DEVONthink installed. The standard version of DEVONthink will work but I do recommend buying the Pro version, among other reasons, for easier OCR. The agencies I sue often transmit non-OCR'd documents and DEVONthink Pro is a godsend when that occurs.
- The documents you're looking at should be Bates-numbered (though my script has a fall-back mode for non-Bates numbered documents—more on that below).
- The documents should be named according to their Bates starting number or their Bates range. The script I wrote can handle any of these filename conventions:
FWS 000533.pdf
FWS-000533.pdf
FWS_000533.pdf
NMFS 002561-002985.pdf
BLM 45.pdf
AR_45-62.pdf
As you can see:
- the agency prefix doesn't matter;
- the separator between the agency prefix and the pages number(s) can be (space),
-
, or_
; and - the filename can include either the Bates number of the document's first page, or the Bates range of the complete document separated by
-
.
This makes the script flexible enough to cover the file naming conventions I see most often in my legal practice. But I have seen others that my script couldn't feasibly be made to accomodate, for example:
20170912 1813 Redacted.pdf
20170922 0000 CSERC Scoping comment letter transmittal email.pdf
20200828 County of Tuolumne transmittal submission.pdf
Butler and Wooster 2003.pdf
California Resources 2020.pdf
Cayan et al 2008.pdf
Crozier et al 2006.pdf
If you're working with documents that are Bates-stamped but use a different file naming convention, like the example above, the script won't work until you rename the files to a supported naming convention. But when you're wrangling a 2,215-document AR comprising over 75,000 pages (true story), it's infeasible manually rename them. That's why I wrote—
A nifty helper script to handle Bates documents with nonconforming filenames.
This helper script, bates
, will batch-rename folders full of documents while preserving their original filenames as metadata. The Python-language helper script is quite complex in its own right— it can handle PDFs with multiple text layers, non-OCR'd PDFs, DRM-protected PDFs, PDFs where Bates stamps are inserted as annotations, and various different Bates stamp formatting conventions.
I've written complete documentation on installing and using bates
here, but the basic usage goes like this:
bates "~/Cases/My Big Case/Adminstrative Record" \
--prefix "BLM AR " \
--digits 6 \
--name-prefix "BLM " \
--log INFO
In this example, the script will take every PDF file in the folder ~/Cases/My Big Case/Administrative Record
, and search the first and last page for Bates stamps formatted like BLM AR ######
. Once it finds them, it will stash the original file name in the file's Finder comment metadata field, then rename the file BLM {first page Bates number}-{last page Bates number}
.
With this naming convention the DEVONthink script will work.
The Bates cite deeplink AppleScript.
Alright, with the prerequisites in place and our documents abiding a compatible filename convention, the actual script this post is about can work. I've written detailed documentation for it here, but it's actually quite simple to set up:
- Copy the script from here
- Open
/Applications/Script Editor.app
- Paste in the script and save it (e.g. on your Desktop) as
Bates Source Link.scpt
- Open
DEVONthink 3.app
and click the script icon in the menu bar (it looks sorta like§
) →Open Scripts Folder
, or alternatively openFinder
and clickGo
in the menu bar →Go to folder...
and enter~/Library/Application Scripts/com.devon-technologies.think3
- Move the
Bates Source Link.scpt
to theMenu
subfolder you should now see in the Finder window
That's it.
You can use the script now by clicking the script icon (§
) in the menu bar and then Bates Source Link
.
Assign a keyboard shortcut.
... but clicking the script menu and finding the right script each time becomes a bit cumbersome, right? I thought so, too, so let's configure a keyboard shortcut for it:
- In your menu bar, click → System Settings → Keyboard → Keyboard Shortcuts → App Shortcuts
- Select
DEVONthink 3.app
and click+
- Enter exact script name as it appears in the script menu in
DEVONthink
, i.e.,Bates Source Link
- Assign your desired shortcut. A good option that doesn't conflict with default shortcuts is
⇧ ⌥ b
(Option
+Shift
+b
).
Hyperkey
I've assigned ⇪ b
(Caps Lock
+ b
) to this script.Handling non-Bates documents.
Not all documents I work with are Bates stamped, so I made the script handle other documents too.
When a document doesn't follow one of the Bates naming convention detailed above, the script will still work. But instead of determining the Bates number for the active page and formatting a deeplinked Bates cite, it will instead format a deeplinked generic cite like this:
"If we do this, Franklin's Bumble Bee will go extinct." [FWS email thread at 6](x-devonthink-item://883C7BE0-A328-4818-A4B5-3AF7E5504135?page=6&start=534&length=53&search=If%20we%20do%20this%2C%20Franklin%27s%20Bumble%20Bee%20will%20go%20extinct.).
With Markdown rendering, that becomes, "If we do this, Franklin's Bumble Bee will go extinct." FWS email thread at 6.
Conclusion
That's it for this tip, folks. Let me know in the comments if you use DEVONthink and decide to give my script(s) a whirl. And as always, feel free to expand their functionality on my repo at sij.ai. I'd be particularly interested if anyone knows how to handle rich text links in AppleScript, to make this compatible in other apps besides Markdown editors.
Cheers!
〄