
Automating Zotero with AppleScript (and JavaScript)
Learn how to improve efficiency working with citations within the Zotero application using macOS.
Zotero background
I recently published an article detailing some AppleScripts that I use for ReadCube Papers, and I thought it would be useful to show additional scripts that I used for Zotero. Zotero is an open-source bibliography software package that manages PDF documents and provides the ability to export citations to literature cited formats for hundreds of journals.
Swap first name and last name in the authors’ field
When I imported my ReadCube Papers library into Zotero, the author’s first name and last name did not map correctly for several citations. In my case, the authors’ names were in firstname lastname
format in the lastname
field. Using GUI scripting, I used AppleScript to move the first name to the correct field and leave the last name where it was, rather than manually doing a copy and paste for each author. GUI scripting involves manually simulating keystrokes that mimic selecting words, copying text, tabbing to a new field, and pasting the text.
For the script below to work, both the author's first name and last name must be in the lastname
field and in the first name last name order. Assuming this is true, and the cursor is placed at the beginning of the lastname
field, the script will move the first name to the correct field and leave the last name as is. Key code 123
is the right arrow key.
use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions
tell application "System Events"
tell process "Zotero"
key code 123 using {shift down, option down}
delay 0.1
keystroke "x" using command down
delay 0.1
keystroke tab
delay 0.1
keystroke "v" using command down
delay 0.1
keystroke tab
end tell
end tell
This script simulates keystrokes to highlight the first name, cut the first name, tab from the lastname
field to the firstname
field, and paste the first name into the firstname
field.
Saving this script in the ~/Library/Scripts/Applications/Zotero
folder will make the script available in FastScripts when Zotero is the front application. To trigger this script, I used an unused function key, F16
, which was convenient to type multiple times if there were numerous author names to swap. The keystroke tab
line in the above script automatically moves the cursor to the next author, so this does not need to be done manually. The F16
key can either be pressed again to perform the same operation on the next author or ignored if all author first and last names have been populated correctly.
Selecting menu items via keyboard shortcuts
Note that these scripts that select menu items could also be done with the macOS built-in keyboard shortcut feature in the keyboard system preferences. I use the scripting approach to manage all the keyboard shortcuts in one place (rather than having shortcuts in system preferences and shortcuts in FastScripts). However, using the keyboard system preferences does not require a third-party utility.
Changing the display font size
Several menu items in Zotero don't have a keyboard shortcut where one would be helpful. These menu items include the following:
- Making the text larger and smaller
- Displaying the run JavaScript window
Using a handler from MacScripter, I used the following arguments with the do_submenu
handler to increase the Zotero font size:
do_submenu("Zotero", "View", "Font Size", "Bigger")
. Handlers allow you to reuse code snippets easily.
The full AppleScript with the handler and the execution of the handler is here:
do_submenu("Zotero", "View", "Font Size", "Bigger")
on do_submenu(app_name, menu_name, menu_item, submenu_item)
try
-- bring the target application to the front
tell application app_name
activate
end tell
tell application "System Events"
tell process app_name
tell menu bar 1
tell menu bar item menu_name
tell menu menu_name
tell menu item menu_item
tell menu menu_item
click menu item submenu_item
end tell
end tell
end tell
end tell
end tell
end tell
end tell
return true
on error error_message
return false
end try
end do_submenu
Show JavaScript window
Because I often bulk edit metadata in Zotero to ensure consistency, I like to have quick access to the JavaScript window that makes this possible. This script is similar to the one used to change the font size, but the first line points to a different menu item. Pasting the code below in an empty Script Editor window and saving the script here ~/Library/Scripts/Applications/Zotero
makes the script accessible to FastScripts when Zotero is the frontmost application. I assigned a keyboard shortcut of ⌘J, as this is currently not used by Zotero.
do_submenu("Zotero", "Tools", "Developer", "Run JavaScript")
on do_submenu(app_name, menu_name, menu_item, submenu_item)
try
-- bring the target application to the front
tell application app_name
activate
end tell
tell application "System Events"
tell process app_name
tell menu bar 1
tell menu bar item menu_name
tell menu menu_name
tell menu item menu_item
tell menu menu_item
click menu item submenu_item
end tell
end tell
end tell
end tell
end tell
end tell
end tell
return true
on error error_message
return false
end try
end do_submenu
Bulk changing metadata with JavaScript
As of version 6.04, Zotero does not have built-in support for bulk changing metadata. For example, if I wanted to rename J Appl Ecol
to Journal of Applied Ecology
in multiple articles, I would have to edit the journal field manually for each entry that I wanted to change. Fortunately, Zotero has support for JavaScript within the application, and using a script from the Zotero wiki, I was able to modify it to perform the journal renaming just described.
To use the script below,
- Back up your current Zotero library. While I’ve used this script many times myself without any issues, if you’ve never used it, you should have a backup of your library in case it doesn’t work as expected. You have been warned.
- Select the items from the Zotero library that you want to change the journal name for.
- Paste the following code into the JavaScript window. Using the previous script, you can assign a keyboard shortcut to this menu item.
- Change the values of the 2nd and 3rd lines to the name of the journal you would like to replace and the new name, respectively.
- Run the script
var fieldName = "publicationTitle";
var oldValue = "J Appl Ecol";
var newValue = "Journal of Applied Ecology";
var fieldID = Zotero.ItemFields.getID(fieldName);
var s = new Zotero.Search();
s.libraryID = ZoteroPane.getSelectedLibraryID();
s.addCondition(fieldName, 'is', oldValue);
var ids = await s.search();
if (!ids.length) {
return "No items found";
}
await Zotero.DB.executeTransaction(async function () {
for (let id of ids) {
let item = await Zotero.Items.getAsync(id);
let mappedFieldID = Zotero.ItemFields.getFieldIDFromTypeAndBase(item.itemTypeID, fieldName);
item.setField(mappedFieldID ? mappedFieldID : fieldID, newValue);
await item.save();
}
});
return ids.length + " item(s) updated";
Note that the first line of this script can be modified to bulk change other metadata fields. The complete list of fields is available on the Zotero website. From that list, the field
name is what you enter on the first line of the script, and the localized
name is the plain English description of the field.
Finishing up
The above scripts can be adapted to your Zotero workflow to automate the interface to make for more efficient interactions with the application. Using the JavaScript window is particularly helpful for bulk metadata changes when cleaning up your Zotero library.