Zotero

The adequate citation tool

December 1, 2019 — September 4, 2023

Zotero! My weapon of choice for citation management.

It starts with browser plugin. With Zotero, I visit an article in my browser, and a button appears in the browser to enable me to import the article into my literature database. I click it and it magically appears in my database, with all the metadata and citation information and a copy of the PDF. After a while I have a big interactive searchable database of these things with a nice user interface and browsing tools. From there I can export to various other formats, such a BibTeX. I can render bibliographies directly in my word processor. I can do lots of other stuff. But don’t listen to me blather. Read the manual. Or the other manual.

Zotero has an API with which I can query, read and write bibliographic entries in my database, making it easy to script automatic updates and such.

It has an active user community, and I don’t feel that I am locking my data away with an untrusted party if I rely upon it. (Of course, one can always try to migrate data around from anything to anything else by exporting to BibTeX or similar, but if I have URLs in there, or consort with foreigners who dare to have diacritics in their names, this leads to trouble). I can use the API to make changes that I couldn’t make manually, without worrying about that parsing nonsense. Moreover, some other apps (Mendeley, …) already use the Zotero API so I know it is battle-tested.

Figure 1: This icon is on my desktop about 90% of my working day

0.1 Zotero 7

Figure 2: This icon is on my desktop about 90% of my working day

Announcing the Zotero 7 Beta on the Zotero forums:

Zotero 7 includes a massive architectural upgrade of Zotero’s underlying code, bringing major performance gains, better OS compatibility, native support for Apple Silicon Macs, a 64-bit Windows build for better handling of large libraries and files, and improved PDF handling. This update lays the groundwork for much more regular performance and OS-integration improvements going forward…

Given the extent of the technical changes, this initial beta may be a bit rougher than other Zotero beta builds, so while we’re not aware of any major bugs or risk of data loss, we’d recommend holding off if you’re in the middle of a project. Additionally, all Zotero plugins have needed to be rewritten to support the new version, so if you rely on third-party plugins, you should check with the plugin developers regarding Zotero 7 compatibility before upgrading.

That said, Zotero 7 doesn’t currently make any database upgrades, so you should be able to switch back and forth between Zotero 6 and 7 without problems. [Update, August 2023: The Zotero 7 beta now includes an updated reader with support for EPUB/snapshots and several new annotation types, and if you create underline or text annotations with that, you won’t be able to switch back to Zotero 6 with the same database.]

See also the following links for tracking compatibility

1 Installing Zotero

1.1 Windows or macOS

Use the standard installers.

1.2 Linux

A little more tedious with Linux. retorquere’s repo of deb installers is a simple way for Debian/Ubuntu.

For non-ubuntu systems… try packaged version?

There is a snap-app package. The weird paths of snaps mean that I must do a lot of configuration to migrate to it if I were not previously using it. It began to fee like yak shaving to continue and so I did not finish said migration and thus cannot report on it. There is a cross-platform flatpak zotero, which is fine, with the usual caveats about flatpak.

flatpak install flathub org.zotero.Zotero
flatpak override --user --filesystem=/PATH/TO/ZOTEROFOLDER \
    org.zotero.Zotero

All of the above options have been intermittently maintained. For me it has been worth the overhead of manually installing this app, since I use it all day long and I would like it to work reliably.

cd ~
wget 'https://www.zotero.org/download/client/dl?channel=release&platform=linux-x86_64'
tar -xjf '/home/dan/Downloads/Zotero-5.0.96_linux-x86_64.tar.bz2'
cd ~/Zotero_linux-x86_64/
./set_launcher_icon
ln -s ~/Zotero_linux-x86_64/zotero ~/bin/
ln -s ~/Zotero_linux-x86_64/zotero.desktop ~/.local/share/applications/

2 Why are my dates in USA format?

On macos Zotero is sometimes sycophantically eager to use the American date system despite the fact that US English is nowhere in my localization preferences, and it makes me look like I think there are 31 months in the year if I use it here. The following advanced settings I found on the user forum seems to help:

intl.regional_prefs.use_os_locales: true
intl.locale.requested: en-GB
intl.accept_languages: en-GB, en

3 URL export

Zotero exposes public groups as URLs that I can e.g. include in overleaf documents.

The zotero url trick was proposed by one christian_moedrup_legaard on this page

HT Laurence Davies.

4 BetterBibTeX

Better BibTeX, a.k.a BBT, makes all the BibTeX stuff in Zotero smoother, and since BibTeX also integrates with markdown via pandoc, this is a double win.

4.1 Citation keys

The biggest trick is that BBT makes sensible, user-accessible citation keys for my references, and if I use these consistently to refer to my sources, life will go well for me.

The citation keys are generated magically by a format string. (Of course, there is no guarantee my colleagues will agree on a sensible standard for citation keys, but that problem is perennial.)

My citation key format strings for BibTeX is

[Auth:fold:nopunctordash][title:fold:nopunctordash:capitalize:skipwords:select,1,1][year]

which I think is approximately the same as the much shorter

[zotero:clean]

That may be the same as this other shortish one

[auth][veryshorttitle1_1][year]

I am not sure if the latter two options handle diacritical marks correctly; I should check. Additionally, I do not trust [zotero:clean] because occasionally its meaning changes and it ruins everything.

So. Say I would like to cite the classic

Ingrid Daubechies (1988) Orthonormal bases of compactly supported wavelets. Communications on Pure and Applied Mathematics, 41(7), 909—996. DOI.

Those cite key formulae above will all ensure that I can refer to this work as DaubechiesOrthonormal1988. I could then cite it in LaTeX as \cite{DaubechiesOrthonormal1988}, in markdown as @DaubechiesOrthonormal1988 and presumably in other systems using some other syntax.

4.2 Exporting BibTeX files via BBT

See also URL export of a BibTeX file.

Zotero will also generate the necessary bibliography databases for any given folder (e.g. .bib file) and optionally keep that file updated as I add more articles to Zotero. That is a nifty magical feature but I found it easier to write my own script to do this on my own schedule rather than relying on magic.

I am fond of excluding following BibLaTeX fields from export to keep outputs small and dense.

file,abstract,note,keywords,lccn,annotation,issn,copyright,howpublished,primaryclass,langid,license,eprintclass,urldate,shortjournal,source,title-short

BBT supports HTTP-pull export, meaning that accessing an up-to-date bib file is a matter of an HTTP request. e.g. http://127.0.0.1:23119/better-bibtex/collection?/1/citation_management.biblatex pulls all the records in the citation_management collection and this works from my local copy of Zotero, so it’s fast and reliable compared to the cloud Zotero server API, which depends upon my internet connection etc. I use this feature all the time, mostly to handle referencing in this very blog that you are now reading. In fact, I automated it with a custom BibTeX export script.

The pull export works better if for me if I set the advanced preference extensions.zotero.translators.better-bibtex.sorted to be true so that the reference sorting is consistent, otherwise it seems to be random each time fine as it is, these days.

Recently I have noticed that exporting as yaml rather than bib is more consistent across platforms for some reason, so I have been using that as the canonical storage format. Either format works fine for blogdown, which is what this blog uses.

spicy aside: CSL is close to being good for use on websites, but has a flaw: They do not support links, in the sense that there is no general way in the standard to tell a CSL renderer which thing to link, or how to style it etc. There is a hack that may support some use cases, although it is not ideal for mine. This is not to say links are impossible; it rather means that if I want something different than the fairly ugly default, I need to write my own CSL processor with some idiosyncratic, site-specific custom URL handling built in, which presupposes I have access to the source code of whatever tool I use and would like to spend time maintaining a fork of it.

I interpret this to mean that the creators of CSL imagine that we are only using it for writing stuff to be printed out on paper, and that it is not worth introducing any conveniences for the mere passing fad that is internet-based communication. This feels reactionary — I literally have not seen a paper journal for years now — but I guess that that really nice paper citations is what these passionate volunteers have identified as the first stop on their journey. If the passionate few want to spend their time steering the standard onto those rocks, and do not want me to turn the ship around, then I can jump out and swim the last mile to the beach alone.

At the moment, the citations on this blog look OK

4.3 Interactive citation finding

BBT supports a Cite-as-you-write interaction, in the form of a GUI popup citation finder for generic editors. I do not use this because I export my citations to a BibLaTeX file on disk using HTTP-pull (below) and my editors already support smart citation natively for BibLaTeX files on disk.

citr provides an interactive citation finder for RStudio that works with BetterBibTeX.

install.packages("citr")

I do not use it, because I do not like RStudio.

There is a new citation processor, citeproc-rs in recent Zotero. Evaluation TBD.

5 Pro tips

Figure 3: I’m not quite sure what the purpose of this Zotero presskit graphic is, unless it be to appear decoratively, and yet slightly confusingly, half way down a blog post about Zotero

5.1 Use an existing folder of PDFs

Integrate with an existing folder of PDFs? Do not wish to use Zotero’s storage system? Richard Zach points out

… you keep your PDF directory synced across computers (e.g., if it lives in your Dropbox), linking the PDFs is just as good. If you add a PDF, Zotero will look up the metadata for you and add a reference to your database.

I do this. As a bonus, this means I don’t have to pay Zotero for storage on their cloud server. I pay them anyway because I want to support this project. Maybe I should just donate?

NB: this is likely to break native e-reader/tablet clients, if they do not support the custom sync method. As things currently stand, though, native tablet clients are not useful, so this is not a factor. There is now an iOS client.

See also Ilya Kashnitsky, Zotero hacks: unlimited synced storage and its smooth use with rmarkdown.

5.2 Quick copy shortcut breaks

Occasionally (for me, frequently) the Quick copy keyboard shortcut breaks. Per default this is Ctrl-Shift-C. This should be fixed by restarting Zotero. Nerds can enter the following in the developer console:

await Zotero.Translators.reinit()

This solves the problem for me.

It does not solve a related problem which arises on Ubuntu 20.04 where Ctrl-Shift-C just seems a contentious key combination to use and does weird stuff which is never what I want. It launches a terminal in VS Code, even though I disabled that shortcut, it never does anything in Zotero. Since this is only bad enough to annoy me but not so cripple me as to be worth going down a rabbit hole of GNOME keyboard shortcut debugging, I will not investigate this further. I reassigned it to a different key, Ctrl-Shift-B, and it seems to work better so far.

6 No need to install zotero

There is a web app with certain useful features one can use without install: ZoteroBib: Fast, free bibliography generator.

7 Hacking

Figure 4

I promised that Zotero’s selling point was its hackability. So I should mention how one goes about hacking it. One thing that was confusing to me is that there are two parts to the Zotero system.

  1. There is a client, the zotero app, that runs on my machine. Confusingly this can also run its own local web server.
  2. There is the Zotero service, run on a George Mason University server somewhere.

Both these parts have their own APIs and many tasks can be accomplished through either, and some only through one. There are pluses and minuses to each.

7.1 Server side

The server side of Zotero has an internet-facing Web API. Its virtues are that

  1. I can use my language of choice, not just javascript, to do things and
  2. it is simple; there is no messing about with the complicated build chain of javascript apps.

However, it is

  1. slow
  2. more restricted and
  3. does not have access to the UI, just the server-side data.

Nonetheless, it is an easy way to get certain stuff done, such as mass updating of tags or spelling or whatever. I use it for data-cleaning (I have a script which walks through the collection, looks for suspect citation ids and deletes them.

I am currently writing a new script to sync tags and collections to be the same (i.e. putting an article in a collection called gp_regression will also tag it with gp_regression; the reason is that the UI for each is deficient but in different ways I can’t search for articles by intersection (i.e. being in 2 folders) but I can with tags. On the other hand actually assigning tags to things is gruelling because their UI requires way too much dragging and dropping of tiny little widgets.

7.2 Client side

The client has a Javascript API, as it is essentially a javascript app. I could use this to develop plugins and such. More probably, But actually, I don’t have time for such because this is yak shaving. As a kind of mini-trick, I can still execute javascript manually for one-off tricks, e.g. batch editing.

I was briefly trying to use the client API to write a custom exporter for Zotero. I did not finish because BetterBibTex, it transpires, does what I wanted but better.

Nonetheless, if I want to reinvent a wheel, or even do something new, here are overview docs, detail docs, and all the code.

One problem I had was writing to output formats which need a unique citekey reference to the items in the bibliography. Here is a simple example which deals with that citekey issue (albeit with an outdated version of the citekey system) Here is a soothing walk-through of the whole process. Once again, BBT solves that problem, so I will spend no more thought on it.

8 Tablet/e-reader

Not wholly satisfactory. One can read on the zotero.org site, which is fine but not ideal. A native app would be nice. There have been many and they seem mostly discontinued. The Zotero mobile page tracks the latest updates.

Given none of the contenders seems, at a glance, good, I prefer no client at all. I use the Zotero plugin zotfile to synchronise a folder full of attachments to my tablet. It’s not perfect, but it’s easy and robust, and many apps exist to browse a folder of PDFs. NB Zotfile is discontinued and will eventually stop working. Maybe it can be replaced by retorquere/zotero-opds which would sync via OPDS. Hmm, that seems to have stalled. Watch this space for updates (e.g. * MuiseDestiny/zotero-file, a reimplementation..

Settings Note: I use zotero rename; formerly I used the rename string {%av}{%y }{%t}.

Active mobile clients at time of writing seem to be

  • official iOs app (check apple store)
  • Zoo
  • ZotEZ² claims to support nonstandard sync
  • zandy
  • Papership (3rd party, iOs) looks neat for iOs.

9 Blog integration

tl;dr. There are many over-engineered solutions to get zotero citations in a blog. I use blogdown with Better BibTeX export. There are other options below.

9.1 Via BetterBibTeX and blogdown

See BetterBibTex export.

9.2 Zotero-mdnotes

Zotero-mdnotes is

A Zotero plugin to export item metadata and notes as markdown files.

Possibly a competitor, the more featureful windingwind/zotero-better-notes

9.3 Via CSL

CSL is a citation rendering mini-language used by modern journals and software to express house style. And I can use it too.

Figure 5: Citation export workflow

This is a slightly weird way to get plain-text citations out; CSL is a system for instructing citation software how to render citations in a rich-text word processor; but it can be forced to pump out plain text or markdown. It is robust ad simple. There is a CSL editor online so this is easy-ish. One catch is that you might, like me, wish to get my BibTeX citation keys out to refer to them. But Bibtex keys are not accessible to CSL, so this doesn’t work. AFAICT this is built into the CSL spec.

CSL has a citation-label variable, but it doesn’t correspond to the bibtex keys generated by BBT, which is unsatisfactory.

  • Here is my docutils/ReST style file, restructuredtext.csl, which renders citations as plain text with ReST markup, including anchor links.

    It’s ugly, because it has to battle with a grumpy rich-text XML infrastructure to render plain text, but it gets the job done without any coding, and is robust against software changes.

  • Similarly, here is my Markdown style file, markdown.csl, which, likewise, renders citations as plain text with Markdown markup, including anchor links.

  • Emiliano Heyns has a BibTeX key CSL hack, which renders Emiliano’s particular preferred citekey \{LeDT06} by reimplementing the BibTeX key generation (sadly not quite matching mine.)

9.4 Via the Atom citation picker

For Atom+Zotero+Markdown, you could try zotero citation, which adds a citation picker to the atom editor. References look like

[$Heyns, 2014$](#@heyns2014)
[$Heyns, 2014$](?@heyns2014,heyns2015)

They are rendered in the output by an in-built pandoc filter, which is installed separately. One locates the output bibliography in the document in either pandoc-YAML or plaintext format at

[#bibliography]: #

I don’t bother; BetterBibTeX works fine for my needs and across many editors.

9.5 Dynamic bibliography generation in situ

Erik Hetzner’s zotxt can avoid the need to create bibfiles, rendering bibliographies directly by querying the zotero app, rather than rendering an intermediate file. Since rendering an intermediate file is scriptable, this does not appeal to me.

10 Incoming plugins