Better BibTeX (BBT) is a plugin for Zotero and Juris-M that makes it easier to manage bibliographic data, especially for people authoring documents using text-based toolchains (e.g. based on LaTeX / Markdown).
Features
Facilities for generating citation keys
Automatically generate citation keys without key clashes! Generate citation keys that take into account existing keys in your library even when they are not part of the items you export. Prevent random breakage!
Generate citation keys based on contents of your items using citekey formulas.
Set your own, stable citation keys, drag and drop LaTeX citations, add other custom BibLaTeX fields.
Conversion between formats and encodings
Zotero does all its work in UTF-8 Unicode, which is absolutely the right thing to do. Unfortunately, for those shackled
to BibTeX and who cannot (yet) move to BibLaTeX, unicode is a major PITA. Also, Zotero supports some simple HTML markup
in your items that Bib(La)TeX won’t understand.
BBT will convert from/to HTML/LaTeX:
<i>...</i>⇔\emph{...}/\textit{...}
<b>...</b>⇔\textbf{...}
<sup>...</sup>⇔\textsuperscript{...} and <sub>...</sub>⇔\textsubscript{...}.
More can be added on request.
BBT contains a comprehensive list of LaTeX constructs, so stuff like \"{o} or \"o will be converted to their unicode equivalents on import (e.g., \"{o} to ö), and their unicode equivalents back to \"{o} if you have that option enabled (but you don’t have to if you use BibLaTeX, which has fairly good Unicode support).
If you need literal LaTeX in your export: surround it with <script>…</script> (or <pre>…</pre>, which do the same) markers.
Fixes date field exports: export dates like ‘forthcoming’ as ‘forthcoming’ instead of empty, but normalize valid dates
to unambiguous international format.
Auto export of collections or entire libraries when they change.
At its core, BBT behaves like any Zotero import/export module; anywhere you can export or import bibliography items in Zotero,
you’ll find Better X listed among the choices.
If nothing else, you could keep your existing workflow as-is, and just enjoy the improved LaTeX ↔ unicode translation on import and export and more accurate field mapping.
Better BibTeX works from BibTeXing and Tame the
BeaST for BibTeX, and
The Biblatex Package for BibLaTeX, but
since there isn’t really a definitive manual for either format that is universally followed by Bib(La)TeX
editors/processors, I’m pragmatic about implementing what works.
Got problems? We got fixes!
If you have any questions on BBT’s use, do not hesitate to file a GitHub issue and ask for help.
If you’re reporting a bug in BBT, please take a moment to glance through the support request guidelines; it will make sure I get your problem fixed as quick as possible.
Clear bug reports commonly have really short time-to-fix, so if you report something, stick around – it may be done as you wait.
The support request guidelines are very detailed, perhaps to the point of being off-putting, but please do not fret; these guidelines simply express my ideal bug submission.
I of course prefer very clearly documented issue reports over fuzzy ones, but I prefer fuzzy ones over missed ones.
Subsections of Better BibTeX for Zotero
Installation
Install by downloading the latest release – if you use Firefox, make sure to right-click and save the XPI file, not just clicking it – and then in Zotero:
In the main menu go to Tools > Plugins
Select ‘Plugins’
Click on the gear in the top-right corner and choose ‘Install Plugin From File…’
Choose .xpi that you’ve just downloaded, click ‘Install’
After the initial installation, the plugin will auto-update to newer releases, so you should need to perform the process described here only once.
Note: the default setting of BBT will generate different citekeys than Zotero would itself generate; the keys from Zotero are not always safe for use in bibtex/biber. If you want to get the stock zotero keys, set the pattern in the preferences to zotero. I very much recommend not choosing zotero as your pattern unless you have existing articles that use keys generated by previous Zotero-native BibTeX export.
Note: BBT needs to be installed in Zotero, not Firefox. There used to be two versions of Zotero, one standalone, and one that was installed in Firefox. BBT is a Zotero extension and lives where Zotero lives; Zotero is no longer available as a Firefox plugin, only as standalone. If you download BBT using Firefox by simply (left)clicking on it, Firefox will download it, think it is a Firefox plugin, try to install it, and will fail with a complaint it is corrupt, hence the right-click and save.
Better BibTeX bundles 5 translators you might care about:
Export
These translators are supported by the auto-export functionality built into Better BibTeX:
Better BibLaTeX exports items in BibLaTeX format (but better, natch)
Better BibTeX exports items in BibTeX format
Better CSL JSON exports items in pandoc-compatible CSL-JSON format, with added citation keys and parsing of metadata
Better CSL YAML exports the same as the Better CSL JSON exporter, but in YAML format
Collected Notes exports just notes – standalone notes and notes attached to items, not the extra field – to HTML. This way, Zotero can serve as a (very) simple research notebook.
Import
Better BibTeX exports and imports entries in Bib(La)TeX format
Included, but you should usually ignore it.
I would hide these if I could. They’re used for Zotero’s drag-and-drop citation facility, and for Better BibTeX debugging.
BetterBibTeX JSON exports and imports items in BetterBibTeX debug format. The error reporter uses this format
Better BibTeX Quick Copy exports citations to be copy-pasted into your LaTeX/Markdown document in the form \cite{< key >}/[@key]
Preferences
The Better BibTeX Configuration can be found under the regular Zotero preferences pane, tab ‘Better BibTeX’.
The configuration of Better BibTeX is a little baroque compared to the standard Zotero Bib(La)TeX exporters (which
only have hidden preferences). The defaults should just work, but here’s an attempt to describe what they do.
Making any change here will drop your entire export cache. This is usually not a problem unless you have a
really large library, but you can read about what is involved here.
Active citation key formula
default: auth.lower + shorttitle(3,3) + year
Set the pattern used to generate citation keys. The format of the keys is documented [here]({{ ref . “citing” }}).
Changing this setting does not affect existign keys - for this you would need to select the items and refresh the keys.
Force citation key to plain text
default: yes
If you have deviated from the default citation key format pattern by [specifying your own]({{ ref . “citing” }}), you may
wind up with non-ASCII characters in your citation keys. You can prevent that using the fold function at the
appropriate place in your pattern, but checking this checkbox will just apply fold to all your keys.
Enable citation key search
default: yes
Enable searching on citation keys. Slows down startup on very large libraries. Requires Zotero restart to enable/disable.
Automatically pin citation key after
default: 0
When > 0, BBT will automatically pin the first citation keys it generates for an item after this many seconds.
Keeping citation keys unique
Ignore upper/lowercase when comparing for uniqueness
default: yes
Treat “AugusteComte” and “augustecomte” as the same key when testing for uniqueness
Keep keys unique
default: within each library
Auto-generated (non-pinned) keys automatically get a postfix when they would generate a duplicate. By default, the check for duplicates is restricted
to the library/group the item lives in. When set to global, the check will include all libraries/groups, so auto-generated keys would be globally
unique. Changing this setting does not affect existign keys - for this you would need to select the items and refresh the keys.
Options:
across all libraries
within each library
On conflict with a pinned key, non-pinned keys will be
default: kept (causes key duplicates)
This determines what happens if you pin a key to a value that is already in use in a different item but not pinned there.
Neither are ideal, you just get to pick your poison. If you let BBT change the non-pinned key by adding a postfix character,
the citation key changes which could be problematic for existing papers. If you keep the non-pinned key as-is, your library now has duplicate keys.
Options:
postfixed (causes key changes)
kept (causes key duplicates)
Ideographs in citekeys
Apply kuroshiro romajization in Japanese names/titles. Uses a lot of memory.
default: no
When on, BBT will load kuroshiro for romajization in citation keys. This uses a lot of memory, easily 100MB. If you don’t have Japanese titles/names, keep this off.
Enable ‘jieba’/‘pinyin’ filters in citekey patterns. Uses a lot of memory.
default: no
When on, BBT will make Chinese word segmentation (jieba) and transliteration (pinyin) available for citation keys generation. This uses a lot of memory, easily 70MB, and adds several seconds to the startup time of BBT. If you don’t have Chinese titles/names, keep this off.
Split all Chinese-like single-field names, unless the item’s language is set to Japanese and Japanese support is enabled.
default: yes
Split all Chinese-like single-field names.
Warn me when changing citation keys in bulk
default: 10
For those who are curious about what the Clear/Generate BibTeX key right-click options do, this will warn
you if you are doing this on more than 10 (default) at the same time, to prevent your curiosity from changing
all your citation keys at once.
Subsections of Preferences
Export
The Better BibTeX Configuration can be found under the regular Zotero preferences pane, tab ‘Better BibTeX’.
The configuration of Better BibTeX is a little baroque compared to the standard Zotero Bib(La)TeX exporters (which
only have hidden preferences). The defaults should just work, but here’s an attempt to describe what they do.
Making any change here will drop your entire export cache. This is usually not a problem unless you have a
really large library, but you can read about what is involved here.
BibTeX
Export unicode as plain-text latex commands (recommended)
default: yes
BibTeX has really spotty Unicode support, so you generally want this on. It will translate things like accented characters
to their equivalent LaTeX constructs on export.
Disregard name prefixes when sorting
default: no
Name handling is a lot more complex than I had ever thought it to be. A lot more complex. BibTeX has really limited ways of dealing with names with particles (van, von, de, etc). If you turn this on, BBT will add code to have van Gogh sorted under Gogh.
Export numeric edition as English-written ordinals
default: no
Try to convert a numeric edition value to English words during BibTeX exports
Add URLs to BibTeX export
default: no
Most BibTeX styles do not support DOI/URL fields. Of the styles that do support them, many forget to load the required ‘url’ package, so make sure to load it yourself. DOI and URL fields are so-called ‘verbatim’ fields, and without the ‘url’ package loaded compilation will likely fail.
Options:
no
in the ’note’ field
in the ’note’ field, but assuming the ‘url’ package is not loaded
in the ‘url’ field
in the ‘url’ field, but assuming the ‘url’ package is not loaded
BibLaTeX
Export unicode as plain-text latex commands
default: no
BibLaTeX actually has really good Unicode support, so you generally want this off. But for some geezers such as me it is
simply more pleasing to have things like accented characters translated to their equivalent LaTeX constructs on export.
Use BibLaTeX extended name format (requires biblatex 3.5)
default: yes
Use the extended biber 2.7 format for names with particles - only works in BibLaTeX 3.5 or later.
This biblatex has a new (less ambiguous) way to store creator names. It’s technically
superior, but the LaTeX world moves slowly, so many people won’t have it yet. But if you’re an early adopter,
you can enable it here
add use-prefix when family name has a prefix
default: yes
When a family name prefix is found, add useprefix=true
Fields
Fields to omit from export (comma-separated)
default: <not set>
If there are some fields you don’t want in your bibtex files (such as note for example), add a list of them here, separated by comma’s.
BibTeX/BibLaTeX
Export language as
default: langid
Export either langid, language or both fields based on the item language (if any).
Options:
langid
language
both
When an item has both a DOI and a URL, export
default: both
Does what it says on the tin, really. If an item has both a DOI and an URL, you can choose to have them both exported, or either one of them. Note that for BibTeX,
you must load the url package when you have doi or url fields. doi and url fields are so-called verbatim fields with different escaping rules, and
BibTeX compilation will likely error out without the package loaded.
Options:
both
DOI
URL
Include JabRef-specific metadata:
default: 0
Export JabRef-specific fields: timestamps, titles for attachments, and groups for each collection an item is part of. Note that having this on will disable caching in exports, which is really undesirable specifically for auto-exports.
Options:
no
for JabRef 3
for JabRef 4
for JabRef 5
Quick-Copy
Quick-Copy/drag-and-drop citations
Quick-Copy format
default: LaTeX citation
Used for drag-and-drop/quick copy using Better BibTeX citation keys. In the Zotero “Export” pane, choose Better BibTeX Quick Copy
as the default export format for quick copy, and choose the desired format for the drag-and-drop citations here.
In the case of Eta templates, the selected items are available as it.items. <%= JSON.stringify(it.items) %> will show you the available data on the items.
Options:
LaTeX citation
Cite Keys
Eta template
GitBook
org-ref citation
org-ref v3 citation
Org-mode citation link
Org-mode select link
Pandoc citation
Roam Cite Key
RTF Scan marker
Zotero select link
Jupyter notebook
Jekyll cite
LaTeX command
default: cite
Used for drag-and-drop/quick copy citations in LaTeX format. Set the desired LaTeX citation command here. If you set this to citep,
drag-and-drop citations will yield \citep{key1,key2,...}
Surround Pandoc citations with brackets
default: no
Used for drag-and-drop/quick copy citations in Pandoc format. You can use this option to select whether you want
to have these pandoc citations surrounded with brackets or not.
Org-mode select link
default: using Zotero item key
OrgMode to select items in your library
Options:
using Zotero item key
using Better BibTeX citation key
Zotero select link
default: using Zotero item key
Hyperlink to select items in your library
Options:
using Zotero item key
using Better BibTeX citation key
Eta template
default: <not set>
Used for drag-and-drop/quick copy citations in Build your own format. This is going to get pretty technical, sorry.
You can paste a Eta template here. Inside the template, you will find an array it.items, each of which is a serialized Zotero item.
To find out what an item looks like inside the template, export some items as BetterBibTeX JSON.
postscript
Miscellaneous
Automatically abbreviate journal title if none is set explicitly
default: no
If set, generates journal abbreviations on export using the Zotero journal abbreviator, according to the abbreviation style selected in the list below the checkbox.
Sort TeX/CSL output (useful if you use version control on the output):
default: citation key (slower on very large libraries)
BBT sorts the output for TeX and CSL exports to have the output be versioning-friendly.
Options:
off (fastest)
item creation order (plenty fast)
citation key (slower on very large libraries)
Include comments about potential problems with the exported entries
default: no
Generate quality reports for exported entries. These show up only in BibTeX and BibLaTeX report formats and indicate things like missing required fields and
duplicate citation keys.
Include automatic tags in export
default: yes
Some importers or Zotero extensions (such as the ShortDOI manager for example) create tags on items that are more for item management than that
they are descriptive of the item. When this is off, such tags will not be included in the export.
Apply title-casing to titles
default: yes
If you’re dead-set on ignoring both BibTeX/BibLaTeX best practice (see the BBT FAQ) and the Zotero recommendations on title/sentence casing, you can turn this off to suppress title casing for English items
Apply case-protection to capitalized words by enclosing them in braces
default: yes
If you’re dead-set on ignoring both BibTeX/BibLaTeX best practice (see the BBT FAQ) and the Zotero recommendations on title/sentence casing, you can turn this off to suppress automatic brace-protection for words with uppercase letters.
Cache
Enable caching for background exports
default: yes
Even though BBT exports happen in a separate thread, some work needs to be done before the background export can
start. Part of this work is preloading the cache. You can shorten the (blocking) preparation time by turning off
the cache, at the cost of longer export times.
Automatic export
The Better BibTeX Configuration can be found under the regular Zotero preferences pane, tab ‘Better BibTeX’.
The configuration of Better BibTeX is a little baroque compared to the standard Zotero Bib(La)TeX exporters (which
only have hidden preferences). The defaults should just work, but here’s an attempt to describe what they do.
Making any change here will drop your entire export cache. This is usually not a problem unless you have a
really large library, but you can read about what is involved here.
Automatic export
default: On Change
Determines when [automatic exports]({{ ref . “exporting” }}) are kicked off. Having it disabled still marks
auto-exports as needing updates, so when you re-enable it, those exports will start. On-change means exports
happen whenever an item in the export changes/is added/is removed. On idle does more or less what
Disabled (that is, no exports but mark as needing changes), but will kick off exports when your computer is
idle. You mostly want this if your computer is performance-constrained (aka slow).
Options:
On Change
When Idle
Paused
Delay auto-export for
default: 5
If you have auto-exports set up, BBT will wait this many seconds before actually kicking off the exports to buffer multiple changes in quick succession
setting off an unreasonable number of auto-exports. Minimum is 1 second. Changes to this preference take effect after restarting Zotero.
Import
The Better BibTeX Configuration can be found under the regular Zotero preferences pane, tab ‘Better BibTeX’.
The configuration of Better BibTeX is a little baroque compared to the standard Zotero Bib(La)TeX exporters (which
only have hidden preferences). The defaults should just work, but here’s an attempt to describe what they do.
Making any change here will drop your entire export cache. This is usually not a problem unless you have a
really large library, but you can read about what is involved here.
Insert case-protection for braces:
default: minimal
On import, BBT will add case-protection (<span class=“nocase”>…<span>) to titles that have words in {Braces}.
There’s plenty of bib(la)tex files out there that do this a little overzealously, and you may not like the resulting HTML code in your items, even though this is what the braces mean in bib(la)tex, and Zotero supports it.
If you turn this off, the markup is omitted during import. When you select ‘yes’, all braces that bib(la)tex would interpret as case protection (which is not all of them) are converted to span elements. In minimal mode, the number of span elements is minimized.
Options:
minimal
yes
no
When scanning an AUX file, attempt to import entries from the attached bib file when their citation keys are not in Zotero
default: no
By default, when scanning for cited items in the aux file, BBT will just generate a note listing all citation keys it cannot find in Zotero.
When this option is turned on, BBT will attempt to import such missing items from the bib file that the AUX file being scanned points to.
Sentence-case titles on import:
Sentence-case titles on import:
default: yes, but try to exclude already-sentence-cased titles
Bib(La)TeX entries must be stored in Title Case; Zotero items are expected to be entered as sentence-case.
With this option on, BBT will try to sentence-case during import. This sentence-casing uses heuristics, no natural language processing is performed, and the results are not perfect.
You can turn this off, but you may then also want to disable Apply title-casing to titles (which has its own problems, see the help entry for that option on this page).
With ‘yes, but try to exclude already-sentence-cased titles’, BBT will attempt to detect titles that are already sentence cased and leave them as-is on import.
Options:
yes, but try to exclude already-sentence-cased titles
yes
no (import titles as-is)
Migrate BetterBibTeX preferences/citation keys
Miscellaneous
The Better BibTeX Configuration can be found under the regular Zotero preferences pane, tab ‘Better BibTeX’.
The configuration of Better BibTeX is a little baroque compared to the standard Zotero Bib(La)TeX exporters (which
only have hidden preferences). The defaults should just work, but here’s an attempt to describe what they do.
Making any change here will drop your entire export cache. This is usually not a problem unless you have a
really large library, but you can read about what is involved here.
Fields
When merging items, also merge:
their citation keys into an bib(la)tex ids field
default: no
When merging items, also merge their citation keys into an bib(la)tex ids field.
fields that are understood to be CSL fields by Zotero
default: no
When merging items, also merge fields that are understood to be CSL fields by Zotero.
their tex.* fields
default: no
When merging items, also merge their tex.* fields.
@string definitions
Expand the @string vars below during imports
default: yes
When enabled, BBT will prepend the @strings section below to all Bib(La)TeX imports and will expand the strings during export.
If a field could be a @string reference, export it as an unbraced @string reference
default: No
When enabled, BBT will try to retain @string vars its exports unsurrounded by braces; when set to ‘detect’, single-word strings will be assumed to be externally-defined @string vars,
when set to ‘match’, only @strings declared in the @strings section of the preferences will be preserved. If you don’t know what this means, leave it off.
Options:
No
Assume single-word fields to be @string vars
Match against the @string declarations below
Match against the @string declarations and their values below
Hidden preferences
The Better BibTeX Configuration can be found under the regular Zotero preferences pane, tab ‘Better BibTeX’.
The configuration of Better BibTeX is a little baroque compared to the standard Zotero Bib(La)TeX exporters (which
only have hidden preferences). The defaults should just work, but here’s an attempt to describe what they do.
Making any change here will drop your entire export cache. This is usually not a problem unless you have a
really large library, but you can read about what is involved here.
You can edit most Better BibTeX preferences through the Preferences window in Zotero. However, Better BibTeX supports additional hidden preferences. These settings are intended for more advanced use.
Zotero
To view the full list of Better BibTeX’s preferences, including many hidden preferences, go to the Advanced pane of the Zotero preferences and click “Config Editor”. Enter “better-bibtex” into the Filter field at the top of the list that comes up. Preferences that can be safely changed by users are described below.
The Better BibTeX hidden preferences are preceded by “extensions.zotero.translators.better-bibtex.”
ascii
default: <not set>
If you have unicode turned on you can still selectively replace some characters to plain-text commands; any characters entered here will always
be replaced by their LaTeX-command counterparts.
autoExportIdleWait
default: 10
Number of seconds to wait after your system goes idle before kicking off auto-exports.
biblatexExtendedDateFormat
default: yes
Support for EDTF dates in biblatex
charmap
default: <not set>
a JSON mapping from single character to raw LaTeX, to augment the default mapping; these will be applied when you export as ASCII. DO NOT edit this preferencedirectly,
but create a CSV (not semicolons) file named charmap.csv in the zotero data directory under the better-bibtex folder with columns unicode (the source character),
text (representation in LaTeX text mode, if any) and math (representation in LaTeX math mode, if any, without dollar signs).
csquotes
default: <not set>
if you set csquotes to a string of character pairs, each pair will be assumed to be the open and close parts of a pair and
will be replaced with a \\enquote{...} construct.
git
default: config
Can be off, config or always
import
default: yes
Use BBTs importer instead of Zotero’s importer
importCitationKey
default: yes
On import, assign the existing citation key to the item being imported
importDetectURLs
default: yes
On import, detect URLs in non-standard bib(la)tex fields and import them as attachments
importExtra
default: yes
On import, place all bib(la)tex field Zotero doesn’t have an existing field for in the Zotero extra field of the item
importJabRefAbbreviations
default: yes
Expand journal abbreviations to the full journal name on import.
importJabRefStrings
default: yes
During import, replace titles matching a list of common @string definitions with the value of that @string
importNoteToExtra
default: <not set>
On import, import note-like fields in this comma-separated list to the extra field, unless the note has rich text.
During import of bib(la)tex, these types will be treated as event-like, in which case if an entry has both an location and an address field, the location will go to Zotero’s Place field. In all other instances, address will go to Place.
importSentenceCaseQuoted
default: yes
During import, also sentence-case quoted parts of titles
importUnknownTexCommand
default: ignore
What to do when encountering a TeX command the parser does not know about. Please only use values:
ignore: ignore the command entirely
tex: import and mark as TeX code, so on re-export it will be output as-is
text: import without marking it as TeX code, so on re-export it will be treated as regular text
itemObserverDelay
default: 5
I’ve had reports where Zotero notifies extensions that items have changed, but if BBT then actually
retrieves those same items, Zotero complains they “haven’t been saved yet”. Super. This preference sets
the number of microseconds BBT should wait after being notified before acting on the changed items.
mapMath
default: <not set>
Any characters entered here will prefer a math-mode LaTeX-command counterpart over a text-mode mapping, if a math-mode command is available.
mapText
default: <not set>
Any characters entered here will prefer a text-mode LaTeX-command counterpart over a math-mode, if a text-mode command is available.
packages
default: <not set>
Some LaTeX commands only work when certain packages are loaded. By default, BBT will export Bib(La)TeX that requires no extra packages, but
you can provide a comma-separated list here of packages to load to get higher fidelity export (for some admittedly niche characters).
Details of these packages and what they add can be found [here]({{ ref . “exporting/unicode.md” }}).
parseParticles
default: yes
Name particle handling. Only turn on when requested and we’re talking about it on github.
Import translators cannot set the date-added and date-modified of the items that are imported, they always get the current time as their date-added. BBT will leave fields it can’t map as
tex.[field] in the extra field of the item. If you enter a list of comma-separated field mappings here, like date-added = dateAdded, timestamp=dateModified, BBT will offer a menu option
to remove them from the extra field and set the corresponding date of the item to their values, assuming they can be parsed as simple dates (no circa and stuff).
postscript
default: <not set>
Snippet of javascript to run [after each entry generation]({{ ref . “exporting/scripting.md” }}).
postscriptOverride
default: <not set>
You can use a custom postscript per export directory:
Edit the hidden preference postscriptOverride, and set it to a filename like postscript.js
In the directory where you intend to export to, create a file called postscript.js (or whatever you set the preference to) and add the postscript you want there
Export to that directory.
A postscript override will disable caching for that export.
preferencesOverride
default: <not set>
You can use custom preferences per export directory:
Edit the hidden preference preferencesOverride, and set it to a filename like preferences.json
In the directory where you intend to export to, create a file called preferences.json (or whatever you set the preference to), or called [bibfile you are exporting to].json and add the desired preference overrides in the format {"override": { "preferences": {"skipFields": "note"} } }. You can get your current preferences by exporting to BetterBibTeX JSON and removing everything except config.preferences, and renaming config to override.
Export to that directory.
A preferences override will disable caching for that export.
rawImports
default: no
When you set this on, BBT will import bib files leaving any LaTeX commands as-is, and add the #LaTeX tag for raw re-exports.
rawLaTag
default: #LaTeX
When an item has this tag, all its fields will be assumed to hold raw LaTeX and will undergo no further transformation.
If you set this to *, all items will be assumed to have raw LaTeX.
relativeFilePaths
default: no
When exporting a Bib(La)TeX file, if the attachments are stored anywhere under the directory the bibliography is exported to, use relative paths
to those attachments. Caching is disabled when this option is on, so it affects performance.
separatorList
default: and
Separator between list elements in list-type fields. You will need to add --listsep='|' to your biber calls.
separatorNames
default: and
Separator between author names. You will need to add --namesep='|' to your biber calls.
list of words to skip in title when generating citation keys
startupProgress
default: popup
Zotero takes a few seconds to start up, which is sometimes mistakenly attributed to BBT. BBT will tell you what phase the startup process is in (of Zotero and BBT) to
prevent support requests for something that I cannot change. Please only use values:
popup: show a popup during startup
progressbar: show a progressbar in the top of the frame
strings
default: <not set>
If you have externally maintained @string vars paste them here and they will be resolved for subsequent imports. These should be entered as @string declarations, such as @string{IEEE_J_PWRE = "{IEEE} Transactions on Power Electronics"}, not just the var name.
stringsOverride
default: <not set>
You can use a custom @string list per export directory:
Edit the hidden preference stringstOverride, and set it to a filename like strings.bib
In the directory where you intend to export to, create a file called strings.bib (or whatever you set the preference to) and add the @string declarations you want there
Export to that directory.
A strings override will disable caching for that export.
list of fields to treat as verbatim during import. If you’re importing e.g. Mendeley-generated BibTeX, which is out of spec in various ways, try removing file from this list before import.
warnTitleCased
default: no
Both Zotero and BBT expect titles to be in sentence-case, but a lot of sites offer import data that is Title Cased. When exporting these titles to bib(la)tex you’re going
to get a lot of extra unwanted braces, because all these Title Cased words will look like proper nouns to BBTs own title-casing mechanism. When this setting is on, you will be warned
when you import/save items in Zotero with titles that look like they’re Title Cased, so that you can inspect/correct them.
Better BibTex adds a couple of export formats to Zotero’s export dialog and several ways to improve export for plaintext-based authoring.
The Better BibTeX configuration pane can be found under the regular Zotero preferences pane, tab ‘Better BibTeX’ where you can tweak the exports, such as
Additionally you can automate exporting (parts of) your library either using auto-export or pull export.
Pinning (fixing) the citation key
By default, BBT will generate citation keys from your items using the formatting pattern you specified. If you want the key to be stable even when you change the item,
you can fix its citation key to a value of your choosing by adding the text Citation Key: [your citekey] on a line of its own in the extra field of the item.
Add your own BibLaTeX fields
LaTeX fields
You can add your own fields to the export which are not derived from regular Zotero item fields by adding them in the extra field:
either by using lines such as
tex.origdate= 1856
tex.origtitle= All This & More
or
tex.origdate: 1856
tex.origtitle: All This & More
The difference between lines with an = or an : is that the fields marked with = are considered to be valid (“raw”) latex and will be passed on into the generated files as-is. The lines marked with : are assumed to be plain-text and LaTeX special characters (such as the & above) will be escaped.
CSL fields
The final way to add fields is by using CSL fields in the
format {:original-date: 1856} or Original Date: 1856 on a line of its own. These fields will not only be exported to Bib(La)TeX, but will
also be picked up by the Zotero Bibliography manager, even though not all Zotero styles yet support this.
Note that the default biblatex styles do not seem to support origdate; you can find possible solutions for this at Stack
Exchange here
and here.
Changing the exported entry type
If you add a field called tex.entrytype, the value of that field value will be used as the entry type
instead of the one usually inferred from the Zotero item type. You can use this to create, for example,
@customa{citekeyhere, ....} type entries.
Background exports
To help out with larger libraries, BBT will export using an isolated thread (“worker thread”), which will prevent Zotero from locking up during exports.
This was introduced in 5.2.0; at time of writing it passes all tests, and feedback so far has been positive, but it’s a wild departure from how Zotero exports work, so
I consider it experimental at this stage. If you are experiencing errors,
please do report them, and
you can (temporarily I hope) disable by going into the BBT advanced preferences and drag the parallel exports slider to 0.
If BBT detects an error during background exports, it will disabled them, so that subsequent exports will be foreground exports. You can re-enable them using the same slider by dragging it back to the default 1.
To export a library, group or collection, right-click on it in the left Zotero pane and choose “Export Library…” or “Export Collection…”.
With BBT’s export translators (e.g., “Better BibTeX”), checking the Keep updated option will register the export for automation.
After you’ve completed the current export, any changes to the collection or library will trigger an automatic re-export to update the file.
You can review/remove exports from the BBT preferences. While I’ve gone to some lengths to make sure performance is OK, don’t go overboard with the number of auto-exports you have going. Also, exporting only targeted selections over your whole library will get you better performance. You can set up
separate exports for separate papers for example if you have set up a collection for each.
Managing auto-exports
There are two important concepts in play for auto-export
register a collection/library for scheduled exports, and
executing these scheduled exports
When you check “keep updated” in the export screen, that means “in the future, schedule this export for re-export when any of its items change, to the file I pick next”. If you do not check this checkbox, that merely means you are not registering the export you are doing, rather than undoing an auto-export you scheduled before.
When these scheduled exports are ran depends on a further configuration in the preferences. You can choose to have scheduled exports to be ran:
on change: run the scheduled export as soon as possible
on idle: run the scheduled export as soon as Zotero goes idle (meaning you haven’t used it for some seconds)
paused: run the scheduled exports manually, or run then whenever you change the setting back to “on change” or “on idle”. In sthis mode, exports are still scheduled, they are just not ran until you give permission.
After you’ve set up an auto-export using an Keep updated export,
you can manage your auto-exports in the BBT preferences under the
Automatic exports tab. There, you can remove auto-exports or change
settings on them. You cannot add new auto-exports
from here, that can only be done by initiating an export.
Getting your BBT-generated bib(la)tex/citekeys to other places
You may want to use your BBT generated bib(la)tex on other systems; maybe you use Overleaf (as I do), maybe you have your documents compiled using github actions (as I do). In any case, you want your auto-exported items to show up somewhere else. If you’re thinking of this in the context of Overleaf, here’s a TL;DR of the pros and cons:
Auto-export + cloud-sync + import by URL
pro: gets the full Better BibTex / Better BibLaTeX file into Overleaf
pro: free or already included in what you pay for your cloud service
con: requires cloud service which has direct-download links (Dropbox seems to offer this, as does Onedrive, but I haven’t tested this)
Auto-export + Dropbox - Overleaf integration
pro: gets the full Better BibTex / Better BibLaTeX file into Overleaf
con: paid option on Overleaf
Auto-export + git:
pro: gets the full bibtex file to Overleaf, tested and works
con: requires technical expertise to set up, paid option on overleaf
con: only gets the BBT citekeys, BibTeX is generated by Zotero itself
DropBox / Google Drive / Box.com / …
Or any other of the plethora of choices that are available today that will “cloud-sync” your files. Will work with any cloud service, as long as it delivers direct-download links, as this method will import into Overleaf by URL.
1.Export the Better Bibtex / Better LaTeX file into an cloud shared folder, with the “keep updated”-option checked
2.Create/generate/find a direct-download link. Google is your friend.
3.Import your cloud-saved bib-file into Overleaf by “Add file -> From external URL”
4.When adding new sources, refresh both the Zotero client, and click the “refresh”-button in the file on Overleaf
If working in a group, this can be accomplished by repeating step 1 for each person into the same cloud-shared folder. When doing step 1, make sure to use the same filename as the original bib-file. This will overwrite the bib-file every time the library is refreshed.
git support
BBT auto-export works nicely with git services (such as Overleaf, which is where I use it myself; the instructions for setting up Overleaf for git can be found here, but any git service (gitlab, github, etc) should work exactly the same. I’m toying with various online services here.
Note that this is more for the technically inclined, you will need to be comfortable with the command line to set this up. I can’t think of a real benefit to using git over cloud-sync unless, like me, you like to keep a backup history in git.
To activate git support, first clone the repo that holds your article/thesis/whatnot from your provider (github, overleaf, etc), run git config zotero.betterbibtex.push true in a command shell in that clone, and set up an auto export to that directory; at each update, BBT will now also push your library to the git service. For the technically curious, that means it does:
git pull
Performs the export
git add <your library file>
git commit -m <your library file>
git push
Note that the nature of git commit/push is not file-bound; if you made edits to other files, and added those, they will be committed and pushed along. If you want to be super-careful, the best way to go about it is to have a separate clone of your repo that BBT auto-exports to, and then another repo that you do your own edits in. I don’t use it myself this way, but you have been warned.
Pinning BBT citekeys for Overleaf
If you only want BBTs citation keys on Overleaf, you can simply pin
them and use the regular Overleaf-Zotero integration. This will get
you the pinned keys, but the bibtex is generated by the standard
Zotero exporters. If you want this to be done by default, set autoPinDelay to a non-zero value.
Markdown/Pandoc
In addition to LaTeX, BBT plays very well with pandoc:
you can drag and drop citations from Zotero into your markdown documents.
you can cite as you write in your favorite editor with varying levels of comfort, mostly depending on how easy (VSCode, Sublime) or hard (looking at you Scrivener) it is to extend your editor.
you can even convert your markdown document into a LibreOffice/Word document with actual live Zotero items as if you had entered them into Zotero all along (see below)
Use CSL, not bibtex with pandoc
Many tutorials on the use of pandoc to generate documents with
citations seem to use bibtex as a bibliography format. I would
encourage the use of CSL instead. Internally, both Zotero and pandoc-citeproc use
CSL citation engines; the two options you have are:
Not only is the extra step through “pandoc-citeproc in convert mode” unnecesary, the translation between bibtex and CSL is complex and often lossy:
Because Zotero primarily targets the built-in CSL processor, it
assumes titles are stored in sentence case (as CSL styles
assume sentence case); bibtex expects title case titles, so Zotero
converts titles to title case on export to bibtex. “pandoc-citeproc in
convert mode” will then take that title-cased bibtex and convert
it back to sentence case. Neither Zotero nor pandoc-citeproc use
natural language processing; the conversion between casing styles
is largely done using heuristics. This conversion is imperfect,
and you don’t gain any benefit from it.
The item model of Zotero/CSL on the one hand and bibtex on the
other has important differences, and in the conversion, choices
must be made on what to put where, and what to drop. Zotero and
pandoc-citeproc do not necessarily have the same business rules,
and this unspoken difference can be another cause of loss.
All of these problems go away if you just skip the detour via bibtex and export (Better) CSL from Zotero and use that in your pandoc process.
From Markdown to Zotero live citations
You can convert a Pandoc-compatible markdown source to a LibreOffice or Word document with live citation fields connecting to Zotero.
make sure you have pandoc version 2.16.2 or later.
optional: add some metadata to your markdown file in a YAML header:
---
# all the regular stuff you have herezotero:
library: <group name># omitted to use your personal libraryscannable-cite: false# only relevant when you're compiling to scannable-cite .odtclient: <zotero or jurism># defaults to zoteroauthor-in-text: false# when true, enabled fake author-name-only cites by replacing it with the text of the last names of the authorscsl-style: apa# pre-fill the stylesorted: true# sort clustered citations by author....
or you can specify them on the pandoc command line:
And hey presto, a live LibreOffice/Word file, or an ODT file with
scannable cites. When you first open the document with live citations, open the Zotero
document preferences and click OKbefore you refresh, or you’ll get a confirmation
popup for each citation. Also, the Word document is sometimes deemed
corrupt when opening it, but running the pandoc command again without
any changes fixes it ¯\_(ツ)_/¯
LibreOffice doesn’t recognise Zotero citations in DOCX,
see issue #2070,
and you must use ODT.
You can also specify transferable: true to create a transferable document. You don’t really need this for ODT or DOCX (just use Pandoc to create those directly using this filter), but it will allow transferring your document to GDocs.
Zotero needs to be running, with BBT installed, while you compile your document.
With regards to sorting citations within a cluster, this is how Zotero does it by default, where pandoc keeps citations in the order you entered them. You can override this by setting sorted to false, for example to retain a prefix at the front, but it may generated citations that are not style-compliant.
You can fetch your bibliography on the url http://127.0.0.1:23119/better-bibtex/collection?[collectionID].[format]1. You can get this URL for a group, library or collection by right-clicking it and selecting Download Better BibTeX export...
You can add options to the export as URL parameters:
&exportNotes=[true|false]
&useJournalAbbreviation=[true|false]
You can fetch your library as part of your build, using something like curl from your Makefile, or with a BibLaTeX remote statement like
the value of translatorID taken from the header of any existing Zotero translator to get an export in that translator format
addbibresource from pull export will only work if you are compiling your document on the
same system your Zotero client with BBT runs on. Technically
it can be made to work for pulling from other systems, but it’s
even more arcane to set up than git support.
Note that as of Zotero 5.0.71, access to this URL will no longer work from the browser for security reasons; curl and other programmatic access will work.
Replace portnumber 23119 with 24119 for Juris-M. ↩︎
You got customized. If you go into the Export tab of the Better BibTeX preferences, subtab postscript, you will find a text box (empty by
default) where you can edit a javascript snippet which will be executed for each entry generated in the Bib(La)TeX
exporter. In this code, you have access to the entry just before it will be written out and cached. There is an API
to do this, and it’s fairly stable, but usually you can just open a new issue and ask me to write it, and I’ll add it
here (it’s how the examples got here). Postscripts are available in 4 of the translators:
BetterBibLaTeX
BetterBibTeX
BetterCSLJSON
BetterCSLYAML
You can (and totally should) check in which translator your postscript is running, which you can do by testing for
Translator.<id> where <id> is one of these four names, using something like
If you want to run a postscript in the CSL translators but don’t care whether it will output YAML or JSON, you can test for Translator.BetterCSL, which will be true when either one of BetterCSLJSON or BetterCSLYAML is active. Analogously, Translator.BetterTeX will be true if either of Better BibTeX or Better BibLaTeX is active.
In the postscript, the entry being built is available as tex (primary), entry, reference and this (legacy) in BetterTeX postscripts, or csl (primary), entry, reference and this in BetterCSL postscripts; the Zotero item it is being built from is available as zotero (primary) or item (legacy).
You should really test for the translator context in your postscripts using the Translator.<name> tests mentioned above. If you don’t because you have a postscript that pre-date postscript CSL support, you will probably be using the legacy use of this to set things on the entry being built, and calling tex.add in those postscripts; since, for CSL postscripts, this is not set, it will make the script will non-fatally error out, so you’re very probably good to go as-is. But please fix your postscripts to test for the translator context.
The API for Better BibTeX and Better BibLaTeX
The postscript should be a javascript snippet. You can access the data with following objects and methods:
zotero is the Zotero item that’s the source for the entry being built.
tex is the BibTeX entry you are building, and the entry has a number of fields.
e.g. you can access the date in zotero item zotero.date.
tex.has is a dictionary of fields for output.
tex.date is the parsed and normalized version of zotero.date.
e.g. you can see whether the year field has been set by testing for tex.has.year, and when e.g. for a season-date only the year is exported in bibtex, you can find it in tex.date.season
tex.add is the function to add or modify keys in tex.has. It accepts the following named parameters in the form of an object:
name: name of the bib(la)tex field to output
value: the value for the field without LaTeX encoding
bibtex: the value for the field with LaTeX encoding already applied. If both bibtex and value are present, bibtex takes precedence
enc: specifies how to encode the value field. Valid values are:
latex: encode markup and special characters to LaTeX. This is the default, if you don’t provide an enc parameter, latex is assumed
verbatim: encode under verbatim rules
literal: encode under literal rules
raw: assume value is already LaTeX-encoded (same as passing the value in bibtex)
url: encode as verbatim url
sep: if value is an array, and enc is latex, encode each array element using latex and join the results with the string in sep. Defaults to an empty string.
html: boolean indicating whether the value is full HTML (really only useful for notes)
caseConversion: boolean indicating whether the field should have title-casing applied.
e.g. change the value of year in output tex.add({name: 'year', value: "your_year_value"})
tex.addCreators adds the contents of zotero.creators to tex.
author encoding has a fair number of moving bits and generates multiple fields (author, editor, etc), this function is here so you can manipulate zotero.creators and call tex.addCreators to replace
the existing creator fields on tex.
tex.remove removes a field previously added by tex.add or tex.addCreators
The API for BetterCSLJSON and BetterCSLYAML
csl is the CSL object being built. Any changes made to this object will directly change the CSL object being output.
zotero is the Zotero item it’s being built from.
There isn’t really an API. You can use regular javascript to manipulate the csl object, which is a CSL-JSON object.
Item types and fields
In a postscript zotero.itemType will have one of these values:
annotationZ
artwork
attachment
audioRecording
bill
blogPost
book
bookSection
case
classicJM
computerProgram
conferencePaper
datasetZ
dictionaryEntry
document
email
encyclopediaArticle
film
forumPost
gazetteJM
hearing
instantMessage
interview
journalArticle
legalCommentaryJM
letter
magazineArticle
manuscript
map
newspaperArticle
note
patent
podcast
preprintZ
presentation
radioBroadcast
regulationJM
report
standard
statute
thesis
treatyJM
tvBroadcast
videoRecording
webpage
Other fields on the zotero object are:
DOI
ISBN
ISSN
abstractNote
accessDate
adminFlagJM
adoptionDateJM
albumJM
applicationNumber
archive
archiveCollectionJM
archiveIDZ
archiveLocation
artworkMedium
artworkSize
assemblyNumberJM
assignee
audioFileType
audioRecordingFormat
authorityZ
billNumber
blogTitle
bookAbbreviationJM
bookTitle
callNumber
caseName
code
codeNumber
codePages
codeVolume
committee
company
conferenceDateJM
conferenceName
country
court
date
dateAmendedJM
dateDecided
dateEnacted
dictionaryTitle
distributor
divisionJM
docketNumber
documentNameJM
documentNumber
edition
encyclopediaTitle
episodeNumber
filingDate
firstPage
formatZ
forumTitle
gazetteFlagJM
genre
history
identifierZ
institution
interviewMedium
issue
issueDate
issuingAuthority
journalAbbreviation
jurisdictionJM
label
language
legalStatus
legislativeBody
letterType
libraryCatalog
manuscriptType
mapType
medium
meetingName
meetingNumberJM
nameOfAct
network
newsCaseDateJM
numPages
number
numberOfVolumes
openingDateJM
opusJM
organizationZ
originalDateJM
pages
parentTreatyJM
patentNumber
place
postType
presentationType
priorityDateJM
priorityNumbers
proceedingsTitle
programTitle
programmingLanguage
publicLawNumber
publicationDateJM
publicationNumberJM
publicationTitle
publisher
references
regnalYearJM
regulationTypeJM
regulatoryBodyJM
reignJM
releaseJM
reportNumber
reportType
reporter
reporterVolume
repositoryZ
repositoryLocationZ
resolutionLabelJM
rights
runningTime
scale
section
series
seriesNumber
seriesText
seriesTitle
session
sessionTypeJM
shortTitle
signingDateJM
status
studio
subject
supplementNameJM
system
thesisType
title
treatyNumberJM
type
university
url
versionNumber
videoRecordingFormat
volume
volumeTitleJM
websiteTitle
websiteType
yearAsVolumeJM
(types/fields marked Z are only available in Zotero, fields marked with JM are only available in Juris-M).
Debugging
There isn’t much in place in terms of debugging, as tranlators (and
thus postscripts) are not allowed to do any UI work. You can do
old-fashioned printf-style debugging by calling Zotero.debug(...)
in your postscript – it will output the string you pass into the
Zotero debug log which you can inspect from the Help menu. You
can for example do Zotero.debug(JSON.stringify(item)) to see what
the Zotero item looks like to the translator.
Samples
Add accessdate, url for BibTeX
Since BibTeX doesn’t really have well-defined behavior across styles the way BibLaTeX does, BBT can’t generate URL data which is compatible with all BibTeX styles. If you know the style you use yourself, you can add the data in the format you want using a postscript. The script below will add a note for the last accessed date, and a \url tag within the howpublished field, but only for BibTeX, not for BibLaTeX, and only for webpage entries:
if (Translator.BetterBibTeX&&zotero.itemType==='webpage') {
if (zotero.accessDate) {
tex.add({ name:'note', value:"(accessed "+zotero.accessDate.replace(/\s*T?\d+:\d+:\d+.*/, '') +")" });
}
if (zotero.url) {
tex.add({ name:'howpublished', bibtex:"{\\url{"+tex.enc_verbatim({value:zotero.url}) +"}}" });
}
}
Comma’s in keywords
If you want to retain commas in your keywords (e.g. for chemical elements) and separate with a comma-space, you could do:
as the default encoder knows what to do with arrays, if you give it a separator.
Add DOI in note field
if (Translator.BetterTeX&&zotero.DOI) {
vardoi=zotero.DOI;
if (doi.indexOf('doi:') !=0) { doi='doi:'+doi; }
tex.add({ name:'note', value:'['+doi+']' });
}
Add arXiv data
arXiv is a bit of an odd duck. It really isn’t a journal, so it shouldn’t be the journal title, and their own recommendations on how to include arXiv IDs is a little lacking: this doesn’t say where to include the arXiv:... identfier, and this says not to include it. Nor does it give any recommendations on how to achieve the desired output.
But for arguments’ sake, let’s say you get the desired output by including an empty journaltitle field (ugh) and stuff the arXiv:... ID in the pages field (ugh). You could do that with the following postscript:
if (Translator.BetterTeX&&zotero.arXiv) {
tex.add({ name:'pages', value:zotero.arXiv.id });
if (!tex.has.journaltitle) { tex.add({ name:'journaltitle', bibtex:'{}' }); }
}
Custom field order
Specify the ordering of the listing of fields in an exported Biblatex/Bibtex entry. Your postscript:
if (Translator.BetterTeX) {
// the bib(la)tex fields are ordered according to this array.
// If a field is not in this list, it will show up after the ordered fields.
// https://github.com/retorquere/zotero-better-bibtex/issues/512
constfront= ['author', 'date', 'title', 'publisher']
constorder=front.filter(field => tex.has[field]).concat(Object.keys(tex.has).filter(field => !front.includes(field)))
for (const [field, value] oforder.map(f => [f, tex.has[f]])) {
deletetex.has[field]
tex.has[field] =value }
}
In Zotero when using an Export Format of Better Biblatex we’ll get something like the following entry …
@book{nietzsche_1974_gay,
author = {Nietzsche, Friedrich Wilhelm},
date = {1974-03},
title = {The {{Gay Science}}: {{With}} a {{Prelude}} in {{Rhymes}} and an {{Appendix}} of {{Songs}}},
publisher = {{Random House}},
origdate = {1882},
shorthand = {GS},
keywords = {Philosophy / General,Philosophy / History Surveys / Modern},
translator = {Kaufmann, Walter},
timestamp = {2016-06-05T20:12:28Z},
pagetotal = {407},
shorttitle = {The {{Gay Science}}},
isbn = {0-394-71985-9},
edition = {1}
}
if (Translator.BetterTeX&&tex.has.title) {
tex.add({ name:'title', value:zotero.title.replace(/(<i>)/ig, '<span class="nocase">$1').replace(/(<[/]i>)/ig, '$1</span>'))
}
Detect and protect LaTeX math formulas
if (Translator.BetterTeX&&tex.has.title) {
tex.add({ name:'title', value:zotero.title.replace(/(\$.*?\$)/g, '<script>{$1}</script>') });
}
Or, detect and protect (simple) LaTeX commands
if (Translator.BetterTeX&&tex.has.journal) {
tex.add({ name:'journal', value:tex.has.journal.value.replace(/(\\\w+)/g, '<script>{$1}</script>') });
}
Detect and protect MathJax
if (Translator.BetterTeX) {
// different for bibtex and biblatex exporters
constnote= ['annotation', 'note'].find(field => tex.has[field])
if (note) {
letnotes=zotero.notes.map(note => `<div>${note}</div>`).join('')
notes=notes .replace(/(\$\$[\s\S]*?\$\$)/g, '<script>$1</script>')
.replace(/\\\(/g, '<script>$')
.replace(/\\\)/g, '$</script>')
tex.add({ name:note, value:notes, html:true });
}
}
Replace director with author for videoRecording and film entries
Creator handling is fairly complicated, so to change the authors/editors/creators of any kind, you must change them on zotero and then call addCreators to do the needful. addCreators will replace the existing creators that were added to tex with the current state in zotero.creators, however you left it.
if (Translator.BetterBibLaTeX) {
switch (zotero.itemType) {
case'videoRecording':case'film':for (constcreatorofzotero.creators) {
if (creator.creatorType==='director') creator.creatorType='author' }
tex.addCreators();
break;
}
}
Changing the entry type from collection to book
if (Translator.BetterBibLaTeX) {
if (tex.entrytype==='collection') tex.entrytype='book'}
Set the entry type to misc for arXiv preprints in BibTeX
if (Translator.BetterBibTeX&&tex.entrytype==='article'&&zotero.arXiv) {
if (tex.has.journal&&zotero.arXiv.source==='publicationTitle') {
tex.remove('journal');
}
if (!tex.has.journal) tex.entrytype='misc'}
Citing documents with a physical archive location
This is one area where some of the supposedly most popular packages – biblatex,
biblatex-apa, biblatex-chicago, biblatex-mla – are all over the
place, if they explicitly support archival material at all. There
doesn’t seem to be a solution that caters for all of these and
possibly other packages, too. biblatex has no special fields for
dealing with info about physical archives, even if it does have
provisions for electronic archives via the fields eprint (identifier),
eprintclass (section of an archive), and eprinttype (name of the archive).
Of the packages mentioned above, only one (biblatex-mla) has a
clear schema of how to record archival information (type @unpublished;
fields number, library, location). Note that the library field
is unique to biblatex-mla. (biblatex does define the field, but
never uses it in its standard styles, and we find no indication
that either biblatex-apa or biblatex-chicago would use it for a
physical archive.)
Given all of this, I’m going to leave referencing of physical
location to postscripts for now. If you enable the quality report, BBT
will list Zotero fields with data that has not been used in the
export:
@letter{MillionDemiInfirmes1968,
title = {Un Million et Demi d'infirmes, Handicapés Physiques et Mentaux},
date = {1968-05-31},
url = {https://archives.strasbourg.eu/archive/fonds/FRAM67482_0592_114Z/view:115037},
urldate = {2021-04-08},
type = {Letter}}
% == BibLateX quality report for MillionDemiInfirmes1968:% Unexpected field 'title'% Unexpected field 'type'% ? Unused archive: Archives de la Ville et l'Eurométropole de Strasbourg% ? Unused archiveLocation: 114 Z 1 248% ? Unused callNumber: 114 Z 1 248
@unpublished{MillionDemiInfirmes1968,
title = {Un Million et Demi d'infirmes, Handicapés Physiques et Mentaux},
date = {1968-05-31},
url = {https://archives.strasbourg.eu/archive/fonds/FRAM67482_0592_114Z/view:115037},
urldate = {2021-04-08},
type = {letter},
library = {Archives de la Ville et l'Eurométropole de Strasbourg},
number = {114 Z 1 248}}
% == BibLateX quality report for MillionDemiInfirmes1968:% Unexpected field 'number'% Missing required field 'author'
if (Translator.BetterBibLaTeX) {
tex.add({ name:'rights', value:zotero.rights});
}
Use ~ in file paths to avoid the .bib file being different on different computers
For example on a Linux machine you might have /home/myname and on MacOS it is typically /Users/mypossiblyothername. If you sync a bib file on both to a git repo you will see a lot of diffs everytime due to them fighting each other.
if (Translator.BetterTeX&&!Translator.options.exportFileData&&zotero.attachments&&zotero.attachments.length) {
for (constattofzotero.attachments) {
if (att.localPath) {
att.localPath=att.localPath.replace(/^\/.*?\/.*?\//, '~/')
}
}
tex.add({ name:'file', value:zotero.attachments, enc:'attachments' })
return { cache:false }
}
It can be useful to have paths to attachment files included in json files, which is currently not the case, see issue 518.
if (Translator.BetterCSLJSON) {
csl.file=zotero.attachments.map(a => a.localPath).join(";");
}
Convert Windows attachment paths to Unix
if (Translator.BetterTeX&&!Translator.options.exportFileData&&zotero.attachments&&Translator.exportPath.includes('\\\\')) {
if (zotero.attachments) {
tex.add({ name:'file', bibtex:tex.enc_attachments({ value:zotero.attachments }, path => path.replace(/^[A-Z]:/i, '').replace(/\\\\/g, '/')) })
}
}
Extra fields
In some cases the Zotero fields do not offer a place to enter the
data you need to get your exported entries just right. For this Zotero
has a so-called “cheater syntax” which allows you to add extra
“fields” as separate lines in the extra field all items in Zotero
have. These fields are supported by the citation processor inside
Zotero, and BBT understands them too, and adds one “cheater syntax
of its own.
You can add such fields by adding each on their own line in the following format:
Label: value
or the older format you migh have seen, which is supported but considered depracated:
{:csl-variable: value}
The full list of labels and the Zotero/CSL variables they translate to can be found in the table at the end.
These extra-fields are available to postscripts as extra.kv.<variable-name>. Which variable it is depends (sorry):
when you export to CSL, it is attempted to map it to the corrsponding CSL fields; if none are available, it is available under their zotero name
when you export to Better BibTeX/Better BibLaTeX, it is attempted to map it to the corresponding zotero fields; if none are available, it is available under their csl variable name
There’s three type of fields:
text
date
name
Text is just that. For dates, BBT will do its darndest to parse the crazy dates so many people seem intent in using but if you want consistent results, stick to YYYY-MM-DD. For names, use either just text (equivalent to a single-part name in Zotero), or <family name> || <given name>.
BBT-specific
There is also a BBT-specific extra-field format that looks like
tex.field: value
These fields are simply copied to the output by BBT, so if you have
tex.bestfield: philosophy
you will end up with
bestfield = {philosophy}
in the written bib(la)tex.
You can make BBT export the field only for bibtex or biblatex by changing the prefix to bibtex. (so bibtex.bestfield:) or biblatex. respectively. Finally, you can use = instead of : as a delimiter, and that will indicate to BBT that what follows the = is “raw LaTeX”; BBT will not do any escaping and just copy it out unchanged. This means, for example, that you would probably want
tex.corp: Black & Decker
tex.formula= $\sum\limits_{i=1}^{n} -p(m_{i})\log_{2}(p(m_{i}))$
and not
tex.corp= Black & Decker
tex.formula: $\sum\limits_{i=1}^{n} -p(m_{i})\log_{2}(p(m_{i}))$
BBT will apply case-protection rules for non-raw fields by including capitals in the prefix, eg
TeX.corp: Black & Decker
It is important to note that these BBT-specific fields are not recognized by any other exporter. They might end up in notes for some other exporters; there’s nothing I can do about that.
Label/variable list
note: I list the Zotero fields here, not the bibtex fields. The Zotero fields are translated to bibtex fields but that translation is pretty complicated and I don’t have a simple description of it at this time.
If you’re lucky and you live in the 21st century or later, you can just use unicode in BibLaTeX and you don’t have to bother about anything that follows except if you’re the curious kind.
Some of us though are bound to outlets that still demand BibTeX, and there’s geezers like me who just prefer the aesthetic of TeX commands over fancy-schmancy unicode, or you find TeX commands easier to search for in your doc than having to memorize how to enter Ψ. BBT has an extensive map of unicode characters, but translating unicode to TeX comes with a massive downside – support for non-ascii characters is scattered across a myriad of packages that you will have to usepackage into your document. The default set are supported by your latex distribution, and require nothing extra in your preamble, but to achieve that I’ve had to make some compromises. You can amend those choices by telling BBT you have extra packages available. BBT can export commands from the following packages:
If you’d really just rather hand-code your LaTeX constructs, BBT makes that possible:
You can add literal LaTeX anywhere in your item by surrounding it with <script>...</script> (<pre>...</pre> will also work for historical reasons) markers. BBT will
convert to/from unicode and (un)escape where required but will pass whatever is enclosed in the pre tags unchanged.
An entry tagged with #LaTeX (case-sensitive!) will have all fields exported as if they’re wrapped in
<script>...</script>, so you can include LaTeX markup in your items.
Recognizing initials in names
In names, you can force first names like Philippe to be exported to {\relax Ph}ilippe (which causes it to get initial Ph. rather than P. in styles that do initials) capitalizing the letters you want to have used as the initials, so PHilippe.
JSON-RPC
You can call into BBT using JSON-RPC on the URL http://localhost:23119/better-bibtex/json-rpc . An example could look like:
returns: { id: number; key: string; libraryID: number }
collection: The forward-slash separated path to the collection. The first part of the path must be the library name, or empty (//); empty is your personal library. Intermediate collections that do not exist will be created as needed.
translator: The name or GUID of a BBT translator
path: The absolute path to which the collection will be auto-exported
displayOptions: Options which you would be able to select during an interactive export; exportNotes, default false, and useJournalAbbreviation, default false
replace: Replace the auto-export if it exists, default false
Add an auto-export for the given collection. The target collection will be created if it does not exist
collection: The forward-slash separated path to the collection. The first part of the path must be the library name, or empty (//); empty is your personal library. Intermediate collections that do not exist will be created as needed.
aux: The absolute path to the AUX file on disk
Scan an AUX file for citekeys and populate a Zotero collection from them. The target collection will be cleared if it exists.
search([[’title’, ‘contains’, ‘Zotero’]]): search for ‘Zotero’ in the Title
search([[’library’, ‘is’, ‘My Library’]]): search for entries in ‘My Library’
(this function try to resolve the string ‘My Library’ into is own libraryId number)
search([[‘ignore_feeds’]]): custom action for ignoring the feeds
search([[‘ignore_feeds’], [‘quicksearch-titleCreatorYear’, ‘contains’, ‘Zotero’]]): quick search for ‘Zotero’ ignoring the Feeds
search([[‘creator’, ‘contains’, ‘Johnny’], [’title’, ‘contains’, ‘Zotero’]]): search for entries with Creator ‘Johnny’ AND Title ‘Zotero’
search([[‘joinMode’, ‘any’], [‘creator’, ‘contains’, ‘Johnny’], [’title’, ‘contains’, ‘Zotero’]]): search for entries with Creator ‘Johnny’ OR Title ‘Zotero’
search([[‘joinMode’, ‘any’], [‘creator’, ‘contains’, ‘Johnny’], [’title’, ‘contains’, ‘Zotero’], [‘creator’, ‘contains’, ‘Smith’, true]]): search for entries with (Creator ‘Johnny’ OR Title ‘Zotero’) AND (Creator ‘Smith’)
Open the PDF associated with an entry with a given id.
the id can be retrieve with e.g. item.search(“mypdf”) -> result[0].id
mind that the items.export method had a bug where it would double-wrap the JSON-RPC response; the extra layer has been removed in 6.7.143, but if you were expecting the previous result you will have to update your code.
The BibTeX citations keys generated by the standard Zotero exporters are always generated at time of export, using an algorithm that usually generates unique keys. For serious LaTeX users, “usually” presents the following problems:
If a non-unique key is generated, which one gets postfixed with a distinguishing character is essentially
non-deterministic.
The keys are always auto-generated, so if you correct a typo in the author name or title, the key will change
You can’t see the citation keys until you export them
For a LaTeX author, the citation keys have their own meaning, fully separate from the other entry data, even if
people usually pick a naming scheme related to them. As the citation key is the piece of data that connects your
bibliography, this is a piece of data you want to have control over. BBT offers you this control:
Stable citation keys, without key clashes. BBT generates citation keys that take into account other existing keys in your library in a deterministic way, regardless of what part of your library you export, or the order in which you do it.
BBT is conservative about citation key changes, and allows you to fix keys to any value of your choosing.
Generate citation keys from JabRef(-ish) patterns.
You can also
Drag and drop LaTeX citations using these keys to your favorite LaTeX editor
Show your citation keys in the item list view.
Set your own, fixed citation keys
By default, BBT generates the citation key from the item information, and this key may change when you edit the item. Such keys are called dynamic keys. In contrast, fixed keys are marked with a pushpin in the item list view and in the item details to distinguish them from dynamic keys.
You can fix the citation key (called pinning in BBT) for an item by adding the text Citation Key: <your citekey> anywhere in the
extra field of the item on a line of its own. You can generate a pinned citation key by selecting one or more items, right-clicking, and selecting Generate BibTeX key, which will add the current citation key to the extra field, thereby pinning it.
Drag and drop/hotkey citations
You can drag and drop citations into your LaTeX/Markdown/Orgmode editor, and it will add a proper \cite{citekey}/[@citekey]/[[zotero://select...][@citekey]. The cite command is
configurable for LaTeX by setting the config option in the preferences. Do not include the leading backslash.
This feature requires a one-time setup: choose the Quick Copy format under the Citation keys preferences for BBT, and go to Zotero preferences, tab Export, under Default Output Format, select “Better BibTeX Quick Copy: [format you just selected]”.
Configurable citekey generator
BBT also implements a citekey generator for those entries that don’t have a citekey set explicitly; the formatter pattern language used to follow
the JabRef key formatting syntax, but now uses a javascript-ish format. You can set your generator pattern in the Better BibTeX
preferences (you can get there via the Zotero preferences, or by clicking the Better BibTeX “Preferences” button in the addons pane.
Better BibTeX knows four kinds of “things” to build the citekey from:
“functions”, these produce text based on the item the key is being constructed from, eg shorttitle. Even though these are largely case insensitive, they must start with a lowercase letter.
“field access”, direct text from the zotero item fields; these again are largely case insensitive, but they must start with an uppercase letter
“filters”, these are actions that act on the text returned from either functions, field access, or from a subformula like (auth + title || year). these are fully case insensitive, and you can chain these together, each acting on the output of the previous filter.
bare strings (text quoted in single or double quotes)
There are 5 ways you can build subformulae:
composition: (auth + title)
alternates: (auth || title) (use the first thing that returns any text, so auth if that returns text, otherwise title)
conditions: (auth && title) (ascertain that the first returns any text before using the last, so use title only if auth would have returned something)
ternaries: (auth ? year : title) (if auth returns any text, use year, otherwise use title). Ternary operators have the format condition ? output_if_true : output_if_false, and you can use it like an if-or statement.
(auth + title) > 0 or auth > 0 are shorthand for (auth + title).len / auth.len.
these can be combined, eg (auth || shorttitle || year) ? (auth + title) : (year || title), but subformulae cannot appear in parameters, so title.select(auth ? 3 : 4) is not valid. Filters (explained below) can be applied to subformulae, so (title || auth).lower checks whether the title function produces output (i.e. not empty). If it does, the title function is used; otherwise, the formula will use the auth function. It then converts the output of (title || auth) to lowercase.
You can also explicitly test whether a formula part is not empty and jump to the next formula if not:
title.lower.len + year; auth + year
which would have the formula evaluate whether the title function returns a non-empty text; if this condition is not met, formula evaluaton jumps to the next formula auth + year. You can also test for a minimal length using eg
(title > 1) + year; auth + year
which is shorthand for
title.len('>',1) + year; auth + year
which checks whether the title output is longer than 1 character. Note the parentheses around the > expression – the formula uses javascript operator precedence, and title > 1 + year means title > (1 + year).
The default key pattern is auth.lower + shorttitle(3,3) + year; if you have papers that use keys which were generated by the key generator of the standard Bib(La)TeX exporters of Zotero you may want to use zotero.clean instead in order to ease migration from existing exports for people who previously used the standard Zotero Bib(La)TeX exports.
auth.lower + shorttitle(3,3) + year, means
last name of first author without spaces, in lowercase because of the .lower filter
The first n (default: 3) words of the title, apply capitalization to first m (default: 0) of those.
year of publication if any,
a letter postfix (a, b, c, etc) in case of a clash (this part is always added, you can’t disable it, although you can change it to Zotero-style numeric)
Changing a pattern will only affect items created/changed after you changed the pattern; existing keys are not automatically regenerated when you change the pattern. If you want your keys to update after a pattern change you will have to select your items, right-click, and select Refresh. This will not affect keys you have pinned.
If you want to get fancy, you can set multiple patterns separated by a semicolon (;) or vertical bar (|), of which the first will be applied
that yields a non-empty string. If all return a empty string, a random key will be generated.
An example application for this behavior is to use the tex.shortauthor from the extra field when defined to generate short citation keys for entries with long group author names, but to default to auth.lower otherwise:
extra('tex.shortauthor').transliterate.clean.lower.len + year; auth.lower + year
You can add a verbatim text by just including it in single or double quotes:
extra('tex.shortauthor').transliterate.clean.lower.len + year; 'default' + auth.lower + year
Formulas have some ternary and or-style choice support; you can use them in formulas instead of a function, but not in parameters; you can for example use
(title ? title : auth).lower + year
or
(title || auth).lower + year
instead of
title.len + year; auth + year
and you can test for length of subsections; what you would previously do with
auth + title + len + year
to jump to the next formula if auth and title were both empty is now
(auth + title).len + year
Generating citekeys
To generate your citekeys, you use a formula composed of functions and filters. Broadly, functions grab text from your item, and filters transform that text.
Note: editing the formula does not update any citation keys. A new formula takes effect for items changed from that point forward. If you want to apply your new formula, select the items, right-click, and choose BBT -> Refresh
If you are used to the bracketed formula syntax, the syntax has changed to a javascript-ish format. The old syntax was getting harder to maintain and its inflexibility prevented new extensions to the functions being implemented cleanly.
PSA: as of Zotero 5.0.71, access to the CAYW URL will no longer work from the browser for security reasons; curl and other programmatic access such as from editors access will work.
Good news for TeXnicians and those down with Mark (aka Markdown, RST, whatnot): this is the time to go pester the author of your favorite editor for Zotero integration!
Editor integration
vim
Graciously supplied by David Lukes:
paste it in your .vimrc (and modify to your liking):
function! ZoteroCite()
" pick a format based on the filetype (customize at will)letformat = &filetype =~ '.*tex' ? 'citep' : 'pandoc'letapi_call = 'http://127.0.0.1:23119/better-bibtex/cayw?format='.format.'&brackets=1'letref = system('curl -s '.shellescape(api_call))
returnrefendfunctionnoremap <leader>z "=ZoteroCite()<CR>pinoremap <C-z> <C-r>=ZoteroCite()<CR>
This inserts the citation at the cursor using the shortcut ctrl-z (in insert mode) or <leader>z (in normal, visual etc. modes, <leader> being backslash by default).
Alternatively, if you use a recent version of Vim (not Neovim) and have written your config file in vim9script, you may be interested in a vim9script version of the above solution to take advantage of JIT compilation:
In this case, the keybinding Ctrl-X Ctrl-Z in insert mode inserts a Zotero citation. You can add a normal-mode keybinding in the same way as for the legacy VimScript version provided above.
emacs
@newhallroad wrote a function in elisp, which brings up the CAYW input, adds the chosen items as pandoc citations to the buffer, and moves the point to after the citations. This is for markdown-mode. Emacs users who use org-mode may (or may not) need something different.
(defun alk/bbt-zotero-insert-key ()
"Run shell command to bring up better bibtex cayw input and insert pandoc citation at point"
(interactive)
(shell-command "curl -s http://127.0.0.1:23119/better-bibtex/cayw?format=pandoc^&brackets=true" t nil) ; caret escapes ampersand
(search-forward "]") ; place cursor after inserted citation
)
Zotero Citations for Atom
A sample implementation of real integration (rather than the working-but-clunky workarounds using paste) can be found in the Zotero Citations package for the Atom editor.
VS Code Citation Picker for Zotero
If you don’t feel like typing citations out (and let’s be honest, you don’t), executing VS Code Citation Picker for Zotero extension for the VS Code editor will call up a graphical picker which will insert these for you, formatted and all.
Scrivener 2.0/Marked 2 for Mac
Dave Smith has gracefully written instructions on how to set up Scrivener 2.0 and Marked 2 for OSX to use the CAYW picker, including ready-to-run apps
Scrivener 1.0 for Windows
Emilie has writen instructions for using the CAYW picker for Scrivener 1.0 in Windows 10, with the necessary files
ConorIA has more versatile solution called zotero4overleaf, which was inspired by Emma’s scripts. This should allow use with Overleaf, which is pretty insane that it’s possible if you think about it.
Overleaf
David Lukes takes Overleaf integration one step further with a GreaseMonkey/TamperMonkey userscript which not only allows popping up the CAYW picker straight from your browser, no other tools required, but adds a hotkey to refresh your bib file on Overleaf. This should work with the free subscription, no fiddling with git or dropbox required.
DIY
BBT exposes an URL at http://127.0.0.1:23119/better-bibtex/cayw 1. The url accepts
the following URL parameters:
parameter
probe
If set to any non-empty value, returns ready. You can use this to test whether BBT CAYW picking is live; it will not pop up the picker
format
Set the output format
clipboard
Any non-empty value will copy the results to the clipboard
minimize
Any non-empty value will minimize Zotero windows after a pick
texstudio
Any non-empty value will try to push the pick to TeXstudio
selected
Any non-empty value will use the current selection in Zotero rather than popping up the pick window
select
More of a gimmick than anything else, but if you add select=true, BBT will select the picked items in Zotero.
The following formats are available:
natbib. Generates natbib citation commands. Extra URL parameters allowed:
command: the citation command to use (if unspecified, defaults to cite)
latex and cite are aliases for natbib with the assumption you want the cite command to be cite
citep and citet are aliases for natbib with the assumption you want the cite command to be citep or citet, respectively.
biblatex. Generates biblatex citation commands. Extra URL parameters allowed:
command: the citation command to use (if unspecified, defaults to autocite)
mmd: MultiMarkdown
pandoc. Accepts additional URL parameter brackets; any non-empty value surrounds the citation with brackets
formatted-citation: output formatted citation as per the current Zotero quick-export setting, if it is set to a citation style, and not an export format
formatted-bibliography: output formatted bibliography as per the current Zotero quick-export setting, if it is set to a citation style, and not an export format
translate invokes a Zotero export translator. Extra URL parameters allowed:
translator: stripped name of one of the BBT translators (lowercased, remove ‘better’, and only the letters, e.g. biblatex or csljson), or a translator ID. Defaults to biblatex.
exportNotes: set to true to export notes
useJournalAbbreviation: set to true to use journal abbreviations
json: the full pick information Zotero provides.
eta: formats the pick using Eta, with the picks exposed as it.items. To see what the items look like, use the json formatter. URL parameter required:
template: the Eta template to render
The eta formatter is great for experimentation, but if you need a format for a common target application, feel free to request a change to have that added to this list.
The picker passes the following data along with your picked items if you filled them out:
field
locator
the place within the work (e.g. page number)
prefix
for stuff like “see …”
suffix
for stuff after the citations
suppress author
if you only want the year
However not all output formats support these. Pandoc and scannable cite are the richest ones, supporting all 4. MultiMarkdown supports
none. The formatted- formats will ignore these. LaTeX supports all 4, in a way:
in the latex (natbib) format: if you choose suppress author for none or all of your items in a pick, you
will get the citation as you would normally enter it, such as \cite{author1,author2}, or
\citeyear{author1,author2}. If you use locator, prefix, suffix in any one of them, or you use suppress author
for some but not for others, the picker will write them out all separate, like \cite[p. 1]{author1}\citeyear{author2},
as natbib doesn’t seem to have a good mechanism for combined citations that mix different prefixes/suffixes/locators.
in the biblatex format: suppress author is ignored unless the command is one of \cite, \autocite
or \parenciteand there is one items only, in which case the starred variant of the command is returned, which
hides the author; for multiple items with locators, prefixes or suffixes, the s-affixed variant of the
command is generated
Some of the formatters use abbreviated labels for the results if you include a locator. The defaults are:
locator label
abbreviation
article
art.
chapter
ch.
subchapter
subch.
column
col.
figure
fig.
line
l.
note
n.
issue
no.
opus
op.
page
p.
paragraph
para.
subparagraph
subpara.
part
pt.
rule
r.
section
sec.
subsection
subsec.
Section
Sec.
sub verbo
sv.
schedule
sch.
title
tit.
verse
vrs.
volume
vol.
In your call to the CAYW URL, you can override the abbreviations by adding them to the query, e.g. http://127.0.0.1:23119/better-bibtex/cayw?format=mmd&page=&Section=sec., page-picks will have no label, and Section-picks will get sec. rather than Sec..
The clipboard option can be used as a workaround for editors that haven’t gotten around to integrating this yet. If
you use this option you will probably want to bind to a hotkey, either system-wide (which is going to be platform-dependent, I know
AutoHotKey works for windows, for OSX Karabiner ought to
do the job, and for Linux xbindkeys could do the job.
For example, if you call up http://127.0.0.1:23119/better-bibtex/cayw?format=mmd&clipboard=yes, the Zotero citation picker will pop up. If you then select two items that happen to have cite keys adams2001 and brigge2002, then
the response body will be [#adams2001][][#brigge2002][], and
[#adams2001][][#brigge2002][] will be left on the clipboard
For Juris-M, the port number 23119 must be replaced with 24119. ↩︎
So you have decided that enough is enough, and you want to migrate
your existing Word/Libreoffice document to LaTeX/Markdown. Plenty
(well…) tools exist to help with the migration of your document
content, pandoc being the most prominent one, but one thing none
of them will do is keep your citations intact. This will not do.
If you install this CSL style in
Zotero (or modify it further and use that), Zotero will render the
in-text citations as [@citekey] when you ask Zotero to render the bibliography. If you want LaTeX, modify the
style accordingly. You can then put your document through pandoc or whatnot to get LaTeX/Markdown.
For the curious, BBT does this by patching in the citation-key
variable in the CSL processing so it can be rendered using a CSL
style. If you previously used the citeprocNoteCitekey preference,
that is now gone, so you’ll have to update the style you used.
Update: pandoc now supports docx+citations as input format and will export your word documents into pandoc-compatible markdown with citations! That should be a much smoother experience:
You can populate a collection, or tag items in your
library, from an existing paper by scanning the aux file generated
by bibtex, or a pandoc-markdown file, for referenced used. Scanning can be triggered from the Tools menu (for
tagging the cited items) or by right-clicking a collection (for
adding them to a collection). The scanner will read your AUX files
and will put entries you cited in the associated LaTeX document
into the current collection.
By default, BBT will add a note for entries cited in the LaTeX
document but which do not exist in your Zotero library, but citation
keys must be present in your library before the scan is started –
BBT will by default not create new items for citekeys it
doesn’t already know about. You can enable ‘AUX Import’ in the
preferences, and when that is on, if the scan finds citekeys not
already in your Zotero library, it will attempt to read those (but
only those) items from the bibtex file named in the aux file.
For BBT users who don’t use LaTeX directly, you can create a
custom aux file to use with the AUX scanner by hand. It is a
text file formatted like this:
\citation{CITEKEY1}
\citation{CITEKEY2}
Where CITEKEY1, CITEKEY2 etc are the citation keys
that you want to include in the collection.
For pandoc-markdown scanning, BBT needs to actually run pandoc, and for that pandoc must be in your $PATH. On MacOS, if you installed pandoc using homebrew, it will likely not be in the PATH that Zotero can see. You can enter the path manually by going into the Zotero preferences, Advanced tab, open the config editor, and create a text entry named extensions.zotero.translators.better-bibtex.path.pandoc and setting it to the full path of the pandoc binary.
Note: a number of functions below talk about the author’s lastname; you can read that as “when available”. If you have the name as a single-field name (for entities like International Business Machines or Aristoteles), Zotero doesn’t have a last name, and the full single-field name is taken instead.
The last name of the first author, and the last name of the
second author if there are two authors or "EtAl" if there are
more than two. This is similar to authEtal2. The difference
is that the authors are not separated by "." and in case of
more than 2 authors "EtAl" instead of ".etal" is appended.
parameter
value assumed when not provided
valid values
creator
kind of creator to select, * selects author first, and if not present, editor, translator or collaborator, in that order.
Corresponds to the BibTeX style "alpha". One author: First three letters of the last name. Two to four authors: First letters of last names concatenated.
More than four authors: First letters of last names of first three authors concatenated. "+" at the end.
parameter
value assumed when not provided
valid values
creator
kind of creator to select, * selects author first, and if not present, editor, translator or collaborator, in that order.
The last name if one author/editor is given; the first character
of up to three authors' last names if more than one author is
given. A plus character is added, if there are more than three
authors.
parameter
value assumed when not provided
valid values
creator
kind of creator to select, * selects author first, and if not present, editor, translator or collaborator, in that order.
creatornames(template?: string containing at least one of '%(F)s', '%(f)s', '%(g)s', '%(i)s', '%(I)s', '%(g_zh)s', '%(f_zh)s', transliterate?: boolean, space?: string)
Sets the defaults for formatting creator names
in the creator template, you can use:
%(f)s: family ("last") name
%(F)s: family ("last") name without dropping particles
%(f_zh)s: family ("last") name extracted from chinese compound names. Need jieba to be enabled
%(g)s: given ("first") name
%(g_zh)s: given ("first") name extracted from chinese compound names. Need jieba to be enabled
%(i)s: given-name initials
%(I)s: given-name initials, upper-case
parameter
value assumed when not provided
valid values
template
sprintf-template default for representing creator names. Default is '%(f)s'.
undefined
string containing at least one of '%(F)s', '%(f)s', '%(g)s', '%(i)s', '%(I)s', '%(g_zh)s', '%(f_zh)s'
transliterate
transliterate the name
undefined
boolean
space
replace spaces in the name (in case of multi-part names for example) with this string
Author/editor information.
in the creator template, you can use:
%(f)s: family ("last") name
%(F)s: family ("last") name without dropping particles
%(f_zh)s: family ("last") name extracted from chinese compound names. Need jieba to be enabled
%(g)s: given ("first") name
%(g_zh)s: given ("first") name extracted from chinese compound names. Need jieba to be enabled
%(i)s: given-name initials
%(I)s: given-name initials, upper-case
parameter
value assumed when not provided
valid values
n
select the first n creators (when passing a number) or the authors in this range (inclusive, when passing two values); negative numbers mean "from the end", default = 0 = all
undefined
number | [ number, number ]
type
select only creators of given type(s). Default: all
sprintf-js template. Available named parameters are: f (family name), F (family name without dropping particle), g (given name), i (initials)
undefined
string containing at least one of '%(F)s', '%(f)s', '%(g)s', '%(i)s', '%(I)s', '%(g_zh)s', '%(f_zh)s' | ''
etal
use this term to replace authors after n authors have been named
undefined
string
sep
use this character between authors
undefined
string
min
skip to the next pattern if there are less than min creators, 0 = ignore
undefined
number
max
skip to the next pattern if there are more than max creators, 0 = ignore
undefined
number
creatortypes(match?: RegExp)
This will return a comma-separated list of creator type information for all creators on the item
in the form <1 or 2><creator-type>, where 1 or 2 denotes a 1-part or 2-part creator, and creator-type is one of {{% citekey-formatters/creatortypes %}}, or primary for
the primary creator-type of the Zotero item under consideration. The list is prefixed by the item type, so might look like audioRecording:2performer,2performer,1composer.
parameter
value assumed when not provided
valid values
match
Regex to test the creator-type list. When passed, and the creator-type list does not match the regex, jump to the next formule. When it matches, return nothing but stay in the current formule. When no regex is passed, output the creator-type list for the item (mainly useful for debugging).
undefined
RegExp
date(format: string='%Y-%m-%d')
The date of the publication
parameter
value assumed when not provided
valid values
format
sprintf-style format template
undefined
string
extra(variable: string)
A pseudo-field from the extra field. eg if you have Original date: 1970 in your extra field, you can get it as
extra(originalDate), or tex.shortauthor: APA which you could
get with extra('tex.shortauthor'). Any tex. field will be
picked up, the other fields can be selected from this list
of key names.
parameter
value assumed when not provided
valid values
variable
extra-field line identifier
none; must be provided
string
firstpage
The number of the first page of the publication (Caution: this
will return the lowest number found in the pages field, since
BibTeX allows 7,41,73--97 or 43+.)
group(name: string)
Tests whether the item is in the given group library
parameter
value assumed when not provided
valid values
name
group name
none; must be provided
string
infix(format: string containing at least one of '%(a)s', '%(A)s', '%(n)s'='%(a)s', start: number | string=0)
a pseudo-function that sets the citekey disambiguation infix using an sprintf-js format spec
for when a key is generated that already exists. The infix charachter appears at the place of this function of the formula instead of at the and (as postfix does).
You must include exactly one of the placeholders %(n)s (number), %(a)s (alpha, lowercase) or %(A)s (alpha, uppercase).
For the rest of the disambiguator you can use things like padding and extra text as sprintf-js allows. With start set to 1 the disambiguator is always included,
even if there is no need for it when no duplicates exist. The default format is %(a)s.
in the template, you can use:
%(a)s: lower-case alphabetic disambiguator
%(A)s: upper-case alphabetic disambiguator
%(n)s: numeric disambiguator
parameter
value assumed when not provided
valid values
format
sprintf-style format template
undefined
string containing at least one of '%(a)s', '%(A)s', '%(n)s'
start
start value for postfix
undefined
number | string
inspireHep
Fetches the key from inspire-hep based on DOI or arXiv ID
returns the journal abbreviation, or, if not found, the journal title, If 'automatic journal abbreviation' is enabled in the BBT settings,
it will use the same abbreviation filter Zotero uses in the wordprocessor integration. You might want to use the abbr filter on this.
Abbreviation behavior can be specified as abbrev+auto (the default) which uses the explicit journal abbreviation if present, and tries the automatic
abbreviator if not (if auto-abbrev is enabled in the preferences), auto (skip explicit journal abbreviation even if present), abbrev
(no auto-abbrev even if it is enabled in the preferences) or full/off (no abbrevation).
The number of the last page of the publication (See the remark on firstpage)
library
Tests whether the item is in the user library
month
the month of the publication
origdate
the original date of the publication
origyear
the original year of the publication
postfix(format: string containing at least one of '%(a)s', '%(A)s', '%(n)s'='%(a)s', start: number | string=0)
a pseudo-function that sets the citekey disambiguation postfix using an sprintf-js format spec
for when a key is generated that already exists. Does not add any text to the citekey otherwise.
You must include exactly one of the placeholders %(n)s (number), %(a)s (alpha, lowercase) or %(A)s (alpha, uppercase).
For the rest of the disambiguator you can use things like padding and extra text as sprintf-js allows. With start set to 1 the disambiguator is always included,
even if there is no need for it when no duplicates exist. The default format is %(a)s.
in the template, you can use:
%(a)s: lower-case alphabetic disambiguator
%(A)s: upper-case alphabetic disambiguator
%(n)s: numeric disambiguator
parameter
value assumed when not provided
valid values
format
sprintf-style format template
undefined
string containing at least one of '%(a)s', '%(A)s', '%(n)s'
start
start value for postfix
undefined
number | string
shorttitle(n: number=3, m: number=0)
The first n (default: 3) words of the title, apply capitalization to first m (default: 0) of those.
parameter
value assumed when not provided
valid values
n
number of words to select
undefined
number
m
number of words to capitalize. 0 means no words will be capitalized. Mind that existing capitals are not removed.
undefined
number
shortyear
The last 2 digits of the publication year
title
Capitalize all the significant words of the title, and concatenate them. For example, An awesome paper on JabRef will become AnAwesomePaperJabref
Without arguments, returns the item type.
When arguments as passed, tests whether the item is of any of the given types, and skips to the next pattern if not, eg type(book) + veryshorttitle | auth + year.
The first n words of the title, apply capitalization to first m of those
parameter
value assumed when not provided
valid values
n
number of words to select
undefined
number
m
number of words to capitalize. 0 means no words will be capitalized. Mind that existing capitals are not removed.
undefined
number
year
The year of the publication
zotero
Generates citation keys as the stock Zotero Bib(La)TeX export
does. Note that this pattern inherits all the problems of the
original Zotero citekey generation -- you should really only
use this if you have existing papers that rely on this behavior.
Note: All auth... functions will fall back to editors if no authors are present on the item.
Note: The functions above used to have the clean function automatically applied to them, this is no longer the case, so if you have CJK authors/titles and you want to manipulate them (using eg. capitalize), you could have to use transliterate on them first, eg. authEtal2.transliterate.capitalize + year + shorttitle(3, 3).
Direct access to unprocessed fields (“Field functions”)
The above functions all retrieve information stored in the item’s fields and process it in some way. If you don’t want this, you can instead call field contents without any processing. To access Zotero fields, refer to them as given in the table below:
AbstractNote
AccessDate
AdminFlagJM
AdoptionDateJM
AlbumJM
ApplicationNumber
Archive
ArchiveCollectionJM
ArchiveIDZ
ArchiveLocation
ArtworkMedium
ArtworkSize
AssemblyNumberJM
Assignee
AudioFileType
AudioRecordingFormat
AuthorityZ
BillNumber
BlogTitle
BookAbbreviationJM
BookTitle
CallNumber
CaseName
Code
CodeNumber
CodePages
CodeVolume
Committee
Company
ConferenceDateJM
ConferenceName
Country
Court
DOI
Date
DateAmendedJM
DateDecided
DateEnacted
DictionaryTitle
Distributor
DivisionJM
DocketNumber
DocumentNameJM
DocumentNumber
Edition
EncyclopediaTitle
EpisodeNumber
FilingDate
FirstPage
FormatZ
ForumTitle
GazetteFlagJM
Genre
History
ISBN
ISSN
IdentifierZ
Institution
InterviewMedium
Issue
IssueDate
IssuingAuthority
JournalAbbreviation
JurisdictionJM
Label
Language
LegalStatus
LegislativeBody
LetterType
LibraryCatalog
ManuscriptType
MapType
Medium
MeetingName
MeetingNumberJM
NameOfAct
Network
NewsCaseDateJM
NumPages
Number
NumberOfVolumes
OpeningDateJM
OpusJM
OrganizationZ
OriginalDateJM
Pages
ParentTreatyJM
PatentNumber
Place
PostType
PresentationType
PriorityDateJM
PriorityNumbers
ProceedingsTitle
ProgramTitle
ProgrammingLanguage
PublicLawNumber
PublicationDateJM
PublicationNumberJM
PublicationTitle
Publisher
References
RegnalYearJM
RegulationTypeJM
RegulatoryBodyJM
ReignJM
ReleaseJM
ReportNumber
ReportType
Reporter
ReporterVolume
RepositoryZ
RepositoryLocationZ
ResolutionLabelJM
Rights
RunningTime
Scale
Section
Series
SeriesNumber
SeriesText
SeriesTitle
Session
SessionTypeJM
ShortTitle
SigningDateJM
Status
Studio
Subject
SupplementNameJM
System
ThesisType
Title
TreatyNumberJM
Type
University
Url
VersionNumber
VideoRecordingFormat
Volume
VolumeTitleJM
WebsiteTitle
WebsiteType
YearAsVolumeJM
(fields marked Z are only available in Zotero, fields marked with JM are only available in Juris-M).
Filters
.abbr(chars: number=1)
Abbreviates the text. Only the first character and subsequent characters following white space will be included.
lookup list. The list must be a CSV file and live in the Zotero/better-bibtex directory in your Zotero profile, and must use commas as the delimiter.
undefined
string
reload
reload the list for every call. When off, the list will only be read at startup of Better BibTeX. You can set this to true temporarily to live-reload a list.
undefined
boolean
passthrough
if no match is found, pass through input.
undefined
boolean
.alphanum
clears out everything but unicode alphanumeric characters (unicode character classes L and N)
.ascii
removes all non-ascii characters
.capitalize
uppercases the first letter of each word
.clean
transliterates the citation key and removes unsafe characters
.condense(sep: string='')
replaces spaces in the value passed in. You can specify what to replace it with by adding it as a
parameter, e.g .condense('_') will replace spaces with underscores. Equivalent to .replace(/\s+/g, sep).
regex or string to match. String matches are case-insensitive
none; must be provided
RegExp | string
passthrough
if no match is found, pass through input.
undefined
boolean
.formatDate(format: string='%Y-%m-%d')
formats date as by replacing y, m and d in the format
parameter
value assumed when not provided
valid values
format
sprintf-style format template
undefined
string
.ideographs
Treat ideaographs as individual words
.jieba
word segmentation for Chinese items. Uses substantial memory, and adds about 7 seconds to BBTs startup time; must be enabled under Preferences -> Better BibTeX -> Advanced -> Citekeys
.kuromoji
word segmentation for Japanese items. Uses substantial memory; must be enabled under Preferences -> Better BibTeX -> Advanced -> Citekeys
string or regex to match. String matches are case-insensitive
none; must be provided
string | RegExp
replace
literal text to replace the match with
none; must be provided
string
.select(start: number=1, n?: number)
selects words from the value passed in. The format is select(start,number) (1-based), so select(1,4) or select(n=4)
would select the first four words. If n is not given, all words from start to the end are
selected.
parameter
value assumed when not provided
valid values
start
first word to select (1-based)
undefined
number
n
number of words to select. Default is all.
undefined
number
.skipwords(nopunct: boolean=false)
filters out common words like 'of', 'the', … the list of words can be seen and changed by going into
about:config under the key extensions.zotero.translators.better-bibtex.skipWords as a comma-separated,
case-insensitive list of words.
If you want to strip words like 'Jr.' from names, you could use something like Auth.nopunct.skipwords.fold
after adding jr to the skipWords list.
Note that this filter is always applied with nopunct on if you use title (which is different from Title) or shorttitle.
parameter
value assumed when not provided
valid values
nopunct
remove punctuation from words
undefined
boolean
.substring(start: number=1, n?: number)
substring(start,n) selects n (default: all) characters starting at start
parameter
value assumed when not provided
valid values
start
starting character (counting from 1)
undefined
number
n
number of characters to select (default: remainder from start)
Forces the text inserted by the field marker to be in uppercase. For example, auth.upper expands the last name of the first author in uppercase.
Usage note: the functions condense, skipwords, capitalize and select rely on whitespaces for word handling. Most functions strip
whitespace and thereby make these filter functions sort of useless. You will in general want to use the fields from the
table above, which give you the values from Zotero without any changes. The fields with ** are only available in Juris-M.
Support
Before all else, thank you for taking the time for submitting an issue, and I’m sorry that I’ve probably
interrupted your flow.
Your report matters to me. I love hearing my software helps you, and it pains me to know that things aren’t working for
you.
If you have any questions on the use of the plugin, please do not hesitate to file a GitHub issue to ask for help.
If you’re reporting a bug in the plugin, please take a moment to glance through the Support Request Guidelines below; it will
make sure I get your problem fixed as quick as possible. The guidelines are very detailed, perhaps to the point of being off-putting, but please do not fret; these guidelines simply
express my ideal bug submission. I of course prefer very clearly documented issue reports over fuzzy ones, but I prefer
fuzzy ones over missed ones.
Submitting an issue
You can report problems with BBT by opening a new issue on github.
Unfortunately, my time is extremely limited for a number of very great reasons (you shall have to trust me on this). Because of this, I
cannot accept bug reports or support requests on anything but the latest version. By the time I get to your issue, the latest
version might have bumped up already, and you will have to upgrade (you might have auto-upgraded already however) and
re-verify that your issue still exists. Apologies for the inconvenience, but such are the breaks.
You can send off an debug report by selecting Send Better BibTeX debug report from the Help menu. Post the resulting ID
(displayed in red) in a github issue.
You can send off an debug report for a specific collection or (selection of) items that fails to export by selecting those, right-clicking
and choosing Send Better BibTeX debug report
That in itself will in many cases give me what I need. Don’t forget to copy the generated ID to paste it into the github
issue; you cannot call it up later (although you can just do it again).
For the fastest fix:
Please be around for follow-up questions and verification I’ve fixed the problem. It’s really frustrating for me to get a bug report, work feverishly to get it fixed, and then the reporter having no time to verify it is actually addressed.
Please include specifics of what doesn’t work. I use this plugin every day myself, so “it doesn’t work” is trivially
false. Please tell me what you expected and what you see happening, and the relevant difference between them.
Please don’t file a jumble of problems in one issue. Posting a slew of separate issues is much preferred, as I can
more easily tackle them one by one.
Do not hijack existing issues. You can chime in on existing issues if you’re close to certain it is the same problem,
otherwise, open a new issue. I rather have duplicate issues than issues I cannot close because they are in fact two or
more issues.
If your problem pertains to importing BibTeX files, you must put up a sample for me to reproduce the issue with.
Do not paste the sample in the issue, as the issue tracker will format it into oblivion. Instead, choose one of
these options:
Post an URL in the issue where I can download your sample, or
Put the sample in a gist and post the URL of the gist into the issue
If your problem pertains to BBT interfering with other plugins (which wouldn’t be the first time), and this interference
has something to do with importing, you must include a sample file that triggers the issue. I know it may seem
that “any file triggers it” – I need a specific file that does so I know we’re looking at the same problem.
Known problems
If Zotero stalls after installing BBT, it is often a one-time thing as the cache fills.
Add-on could not be installed because it appears to be corrupt.
You have downloaded the Better BibTeX plugin by clicking on the
download link using Firefox. As Zotero and Firefox use the same
plugin technology, Firefox think the BetterBibTeX plugin is intended
for itself, tries to install it, and then finds out it won’t work.
You need to download the plugin without installinging it into Firefox
by right-clicking the download link, choose save-as, and then install
it into Zotero using installation instructions to get started with BBT.
BBT is changing the capitalization of my titles – why?
There isn’t a straightforward one-to-one mapping for all Zotero to Bib(La)TeX
fields. For most I can make reasonable choices, but there are some things where
Better BibTeX takes a little more liberties with your items in order to get
sensible output.
Title fields in particular are a total mess. Zotero recommends having your
titles in sentence
case
because that’s what the embedded citation processor expects, but of course,
BibLaTeX expects your titles to be in Title Case… but only if they’re in
English. Nice. In order to translate the Zotero recommendation into Bib(La)TeX
best practice, BBT will title-case the titles of English items. English
items, as far as BBT is concerned, are those items that have their
language explicitly set to an English language (american counts as English for
example), and those items that have no explicit language set. To do this,
BBT uses the same title-caser that Zotero uses to produce title-cased styles
such as Chicago.
The titles so modified will then pass through your Bib(La)TeX processor, which
will in turn try to lowercase or initial-caps some words and not others – for
English items. But then sometimes, you want words that have capitals to
keep. BBT assumes that if a word has at least one capital letter (subject to
some rather complex exceptions) you meant it to be there, and you want BibTeX to
leave it alone no matter what. To do that, it wraps those (strings of) words in
those double braces. This is to let BibTeX know that ISDN may not be changed
to isdn or Isdn, regardless of the bibliography style in play.
The simplest approach would be to wrap title fields in extra braces as a whole,
and some sites will erroneously recommend doing so, but as per Mencken, for
every complex problem there is an answer that is clear, simple, and wrong; the
rules for bib(la)tex capitalization are complex, and this is one of those
answers that gets it entirely wrong, even if it will seem to work. There are
styles do need to recapitalize parts of the title (for example to selectively
downcase the titlecasing), and having the whole field so wrapped interferes with
that. So Better BibTeX wraps individual words – or strings of those words –
that have capitals in them with double braces.
For English titles BBT will Title Case and brace-protect your titles on output.
Except, those Title Cased words which BBT changed itself will not be wrapped
in double-braces, as it is OK for the styles to change casing for those,
depending on the style at play. So I like ISDN heaps better than dialup would
output to I Like {{ISDN}} Heaps Better than Dialup. Apparently non-English
titles are supposed to be in sentence case, so BBT doesn’t touch those.
You can steer this process somewhat by enclosing the parts you don’t want case
manipulation on in <span class="nocase">...</span>. Anything between those
won’t be touched by Zotero or BBT. This is formally supported by Zotero and will
work in the Word/LibreOffice plugins as well as in the BibTeX export. This will
be required for words you wish to always keep lowercase, for example. Also, if
you don’t generally use Zotero for generating bibliographies but just for BibTeX
reference management, you can turn on the hidden preference
suppressTitleCase to keep BBT
from applying title-casing, but take note that if you do this, the
bibliographies you get from Zotero and the bibliograhies you get through
Bib(La)TeX will differ, and you can’t complain about this.
Why the double braces?
But why then the double-braces ({{...}}) rather than the commonly recommended
single braces ({...})?
This is not because of some arcane aesthetic preference, but because the
Bib(La)TeX case protection rules are incredibly convoluted
(#541,
#383). For
example, here are some “interesting” cases that BBT has learned to deal with.
Did you know that
{\emph{Homo sapiens}}un-case-protects Homo sapiens? It sure was a
surprise to me. So \emph{Homo sapiens} is case-protected (will not be
recapitalized by Bib(La)TeX), but {\emph{Homo sapiens}}is not
case-protected so it will be recapitalized. So to get predictable
behavior, this is written out as {{\emph{Homo sapiens}}}.
apparently,
to make sure that Reading HLA Hart's: <i>The Concept of Law</i> renders as
expected means I have to output the astoundingly ugly {Reading {{HLA Hart}}'s: {{{\emph{The Concept}}}}{\emph{ of }}{{{\emph{Law}}}}}?
To make matters even more complex, so many people have in the past wrongly
recommended to “just wrap everything in one extra set of braces” that biblatex
now ignores exactly that pattern (see
here and
here).
The double-bracing is the only unambiguous rule I could construct that
consistently gets the rendered entries right (so far).
Bib(La)TeX provides a never-ending stream of edge cases, which BBT tries to
decide algorithmically. I try to keep the resulting file as pretty as I can (I’m
sensitive to the aesthetics myself), but the target is best described as “given
reasonable input, generate well-rendering output”, and
reasonable-to-well-rendering in the BBT case will have to include “follows
Zotero recommendations for storing items” and “prefer intent-preserving
LaTeX over pretty-looking LaTeX”.
Bib(La)TeX be crazy.
But why so many double braces?
Zotero expects titles to be entered in sentence case; bib(la)tex
expects them to be entered in Title Case. BBT converts titles to
title case to compensate for this. Zotero does allow for exceptions
to the sentence-case rule, which you can mark by surrounding them
with <span class=“nocase”> … </span>, and BBT will
take that hint and use double braces (see previous sections) to
achieve the same effect in bib(la)tex. But BBT does one thing more
– if BBT sees a word containing capital letters which is not at
the start of a (sub)sentence (such as the ISDN in I like ISDN heaps better than dialup), it will assume it is a proper noun
(otherwise why would a word mid-sentence have a capital letter),
and also brace-protect it.
Unfortunately, there is a lot of variation in how titles are offered by the sites Zotero scrapes – some sentence case, some title case – so it is not at all uncommon for title-cased titles to (incorrectly) end up in Zotero, and as a result you’ll get a lot of unnecesary braces. For example, if you (incorrectly!) have the following in Zotero:
I Like ISDN Heaps Better than Dialup
BBT will export that as
title = {I {{Like ISDN Heaps Better}} than {{Dialup}}}
which is clearly not correct. The proper way to fix this is to sentence case this in Zotero – if you generate a bibliography through Zotero itself, there are styles where this title-cased title will not render correctly. But if you have a lot of these, and you do not care about the quality of the bibliographies generated by Zotero itself, you can disable the title-casing and/or the brace protection.
Importing JabRef databases
JabRef import works generally well but has a few gotchas:
If you have dynamic (query-based) groups these will not be imported.
If you have set a default folder for the PDF files in JabRef
(Options -> Preferences -> Linked Files -> Main File Directory), the file paths in your JabRef database will be relative to that
directory, but BBT can’t read those preferences, so all attachments would
fail to import. Make imports work with JabRef’s library-specific setting Library -> Library Properties -> General File Directory.
Make sure the latter path is correct, as JabRef might continue finding files and not notify you if it contains errors.
Why Zotero + BBT instead of Mendeley?
Among the reasons to just prefer Zotero over Mendeley outright you will find:
But wrt bibtex export, I don’t think the Mendeley engineers actively use bib(la)tex:
Mendeley is still double-bracing titles – a behavior so wrong (yet unfortunately ubiquitous), biblatex started ignoring double-braced titles (see here and here).
Mendeley uses CSL, so items should be entered in sentence case (as is the case in Zotero). But bib(la)tex expects title-case, so titles should be converted to title case during export. This is difficult, so Mendeley just doesn’t bother doing it.
Verbatim fields that should per spec be exported as regular fields by Mendeley. This will get you compilation errors.
Exporting language fields in addition to langid
Zotero’s language field exports to the biblatex field langid only, not bib(la)tex language. Zotero’s language field and the biblatex langid field are supposed to contain only language tags that control formatting, e.g. capitalization of titles and hyphenation.
Biblatex’s `language" field, by contrast, which has no equivalent in Zotero, is used to generate textual output in a formatted bibliography.
Exporting Zotero’s language field to the biblatex field language would result in what are now merely language-dependent formatting instructions all of a sudden turned into textual output as well, breaking virtually every style on the biblatex side.
If you want the language field filled nonetheless, you can either use a BBT postscript, or the biblatex langid tags can still be used to selectively generate language fields that produce the output when rendered, assuming the aim is to eg have only items tagged as Japanese, i.e., containing biblatex langid fields whose contents begin with ja receive the string [in Japanese] in the formatted output.
In the following, biblatex’s \DeclareSourcemap mechanism is used to generate such language fields at runtime. Details can be found in the biblatex manual.
\documentclass{article}
\begin{filecontents}[overwrite]{tmp.bib}
@article{UseLanguage,
title = {Title of UseLanguage},
author = {A. U. Thor Language},
date = {1986},
journaltitle = {Journal of Engineering},
volume = {123},
number = {28},
pages = {1--12},
language = {japanese}
}
@article{UseLangid,
title = {Title of UseLangid},
author = {A. U. Thor Langid},
date = {1986},
journaltitle = {Journal of Engineering},
volume = {123},
number = {28},
pages = {1--12},
langid = {Japanese}
}
@article{UseLangidAbbrev,
title = {Title of UseLangidAbbrev},
author = {A. U. Thor LangidAbbrev},
date = {1986},
journaltitle = {Journal of Engineering},
volume = {123},
number = {28},
pages = {1--12},
langid = {ja-JP}
}
@article{en,
title = {Title of Something Completetly Different in English},
author = {Doe, John},
date = {2024},
journaltitle = {Journal of Whatever},
volume = {321},
number = {1},
pages = {33--77},
langid = {en}
}
\end{filecontents}
\usepackage[sorting=none]{biblatex-chicago}
%\usepackage[sorting=none]{biblatex}
\addbibresource{tmp.bib}
\DeclareSourcemap{
\maps[datatype=bibtex]{\map{
\step[fieldsource=langid, matchi=\regexp{^ja},
final]
\step[fieldset=language, fieldvalue=Japanese]
}
}
}
\begin{document}
\nocite{*}
\printbibliography
\end{document}
If you just want the bib(la)tex language field to show whatever is in your Zotero language field, you can do it with this postscript:
if (Translator.BetterTeX) { tex.add({ name: 'language', value: zotero.language }) }
If you want the language field translated (to the best of BBTs abilities) to what would otherwise show up in langid, you can use:
if (Translator.BetterTeX) { tex.add({ name: 'language', value: tex.langid() }) }
The Better BibTeX exporters are a lot slower than the standard Zotero Bib(La)TeX exporters. If you have a small library,
you will not likely notice this, but if you have several thousand items, and you are in the habit of exporting
substantial parts of your library, this gets annoying really fast.
To deal with this problem, Better BibTeX implements an extensive caching system. With a filled cache, Better BibTeX is
substantially faster than the default Zotero exporters. Specifically for automatic background exports, a filled cache is
a good thing to have.
For technical reasons, if you export the file attachments as part of your export, the cache is skipped altogether, so
this will always be slow. This is also why you cannot set up auto-exports with file exports.
TL;DR
There’s a more technical explanation below, but the TL;DR version is that you want to have a filled cache. If you want
to get it over with, export your entire library (once, no need to tick ‘Keep Updated’) using the ‘Better BibTeX’ format
and go grab coffee (or lunch, depending on the size of your library). After that, things should be much better.
Here are some numbers from a test with a library consisting of 86 items, exported 50 times in a row to middle out variances:
(attachments are not exported for this test, but they still required serialization and handling):
Exporter
Zotero BibTeX
3s
Better BibTeX, empty cache
9s
Better BibTeX, filled cache
4s
Zotero BibLaTeX
4s
Better BibLaTeX, empty cache
9s
Better BibLaTeX, filled cache
3s
note: if you have ‘Export files’ enabled during export, or set the JabRef export format to 4, the cache will not be active. If you do large (auto)exports, avoid these.
Caching
Initial state
Initially, your cache will be empty. The first export of any item using Better BibTeX will therefore be a little
over twice as slow as subsequent exports. After that, it gets pretty zippy, as the process of exporting a item
will also cache the output entry for that item for the current export settings. This means if you export once with, and once without
notes (one of the options in the export popup), you will hit an empty cache twice. If you set up an automatic export,
the export you do that registers it for auto-update will already be the first export, so if your items weren’t
cached already, they will be before subsequent auto-exports.
Cache refresh
The cache entry for a item is retained as long as you do not make any changes to that item. Any change you
make will drop all cache entries for that item (so all variants you had for different export options). The cache
for that item will be refreshed as soon as you export it again, either manually or
automatically.
Cache drop
Any change you make to the Better BibTeX preferences will drop the whole cache. The behavior of
the Better BibTeX exporters are highly configurable, and it is impossible for me to figure out which entries would be
affected specifically. Keep this in mind for large libraries; if you want to make changes to your configuration, make them all at once.
The same applies to upgrades. As the export behavior quite frequently changes between versions, Better BibTeX will drop
the cache during first startup of the newer version. This can be a nuisance if you have a large library, but it’s the only way to keep support feasible.
Translations
BBT is currently available in English, German, French and Brazilian Portuguese. You can help out by adding new translations or fixing existing ones on Crowdin.
Running the BBT test suite
Please DO NOT DO THIS without an open issue on the github tracker. I’ve been running tests this way for years, but I’d still prefer to guide you through this to prevent any risks to your citation library. The test suite has only been tested on MacOS and Linux. I doubt it’ll run on Windows, and I don’t know what will go wrong when you test. If you’re on Windows, DO NOT run this on the same account that holds your actual Zotero library.
The tests require an installed Zotero, python 3.6+, and node 12+, a working gcc, and libgit. On MacOS, that requires:
brew install libgit2
if xcode-select -p doesn’t respond with /Applications/Xcode.app/Contents/Developer: xcode-select --install (select install, not get Xcode in the popup that follows).
then a few things I’d really prefer you do before anything else. In principle the tests are safe to run on the user account that also has your own library. I’ve been doing this for years. Still, it would be good to verify rather than trust this. The next steps are all reversible if things don’t go as expected.
Make sure Zotero is not running. If you’re on a Mac, that means cmd-Q
copy the Zotero profiles to a safe place. The profiles live in ~/Library/Application\ Support/Zotero if you’re on a Mac, ~/.zotero if you’re on Linux.
mv ~/Zotero ~/Zotero.saved
touch ~/Zotero
this is all temporary, and when all is verified to be setup correctly, we’ll undo them.
~/Library/Application\ Support/Zotero / ~/.zotero holds the administration of your Zotero profiles. The test setup will add a new profile leaving your existing profile(s) untouched. But better safe than sorry, which is why we’re holding a copy.
The mv sets aside your library so that Zotero won’t be able to find it. The touch creates an empty file in its place. The tests don’t use that location, they use ~/.BBTTEST instead, but if for whatever reason that doesn’t work, Zotero will try to write to ~/Zotero/something, and since ~/Zotero is now a file instead of a directory, Zotero will complain loudly if that happens, and we know we must back out.
Now then:
make sure you’re in zotero-better-bibtex
./test/behave --tags @438
and be amazed. Zotero will pop up, load the test library, executes one test, and shuts down. The log file after the tests run will be ~/.BBTTEST.log. The tests do not touch your own library.
To restore access to your regular library so you can run either a test suite or just work with your library (but not both at the same time. always fully close Zotero between these).
rm ~/Zotero
mv ~/Zotero.saved ~/Zotero
and you can remove the copy of the profile administration you made earlier. Zotero should now start again normally opening your library.
Sponsoring BBT
While the development needs of BBT are to a large extent covered
by the generosity towards open-source developers of services such
as github, my development system does require the
occasional upgrade; also, I enjoy getting the occasional frivolous
tech-toy that I wouldn’t otherwise grant myself. While you should
feel in no way obligated to pay for BBT, anything you can spare is very much appreciated.
If you’d rather contribute a little bit each month (and a little
means a lot) so I can save up for a replacement a year or so down
the line, head on over to Patreon,
but mind that Patreon takes a fairly large cut of what you give.
Many, many thanks, also to the existing contributors – thanks to you I’ve hit my first target and have been able to replace my trusty macbook air with a newer macbook pro which has much more breathing room.