Better BibTeX for Zotero

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.

Facilities for exporting data from Zotero

  • Highly customized exports.
  • 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.
  • Pull export from the embedded webserver.
  • Automatic journal abbreviation.

Getting started

To get started, read the installation instructions.

How does it work ?

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:

  1. In the main menu go to Tools > Add-ons
  2. Select ‘Extensions’
  3. Click on the gear in the top-right corner and choose ‘Install Add-on From File…’
  4. Choose .xpi that you’ve just downloaded, click ‘Install’
  5. If you’re using Zotero 6, restart Zotero. Installation in Zotero 7 requires no restart.

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.

Subsections of Installation

Citation keys

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” }}).

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.

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.

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 Citation keys

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

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

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. &lt;%= JSON.stringify(it.items) %&gt; 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 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.

default: using Zotero item key

OrgMode to select items in your library

Options:

  • using Zotero item key
  • using Better BibTeX citation key

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)

Abbreviation style:

default: <not set>

Select the style for auto-abbreviation. Only applicable to Juris-M; in Zotero, the style for automatic abbreviation is not configurable.

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

Retain export cache across upgrades

default: no

By default, BBT clears all caches whenever BBT or Zotero is upgraded. I can’t realistically predict whether a change in Zotero or BBT is going to affect the output generated for any given item, so to be sure you always have the latest export-affecting fixes, the caches are discarded when a new version of either is detected. If you have a very large library however, of which you regularly export significant portions, you might want to retain the cached items even if that does come with the risk that you get wrong output on export that has been fixed in the interim.

If you have this on, and you experience any problem that is not the cache getting dropped on upgrade, you must clear the cache and reproduce the problem. When you change this setting, as with any setting change, the cache will be dropped.

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:

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.

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.

patchDates

default: dateadded=dateAdded, date-added=dateAdded, datemodified=dateModified, date-modified=dateModified

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:

  1. Edit the hidden preference postscriptOverride, and set it to a filename like postscript.js
  2. 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
  3. 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:

  1. Edit the hidden preference preferencesOverride, and set it to a filename like preferences.json
  2. 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.
  3. 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.

skipWords

default: a,ab,aboard,about,above,across,after,against,al,along,amid,among,an,and,anti,around,as,at,before,behind,below,beneath,beside,besides,between,beyond,but,by,d,da,das,de,del,dell,dello,dei,degli,della,dell,delle,dem,den,der,des,despite,die,do,down,du,during,ein,eine,einem,einen,einer,eines,el,en,et,except,for,from,gli,i,il,in,inside,into,is,l,la,las,le,les,like,lo,los,near,nor,of,off,on,onto,or,over,past,per,plus,round,save,since,so,some,sur,than,the,through,to,toward,towards,un,una,unas,under,underneath,une,unlike,uno,unos,until,up,upon,versus,via,von,while,with,within,without,yet,zu,zum

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:

  1. Edit the hidden preference stringstOverride, and set it to a filename like strings.bib
  2. 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
  3. Export to that directory.

A strings override will disable caching for that export.

verbatimFields

default: url,doi,file,pdf,ids,eprint,/^verb[a-z]$/,groups,/^citeulike-linkout-[0-9]+$/, /^bdsk-url-[0-9]+$/, keywords

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.

Bundled translators

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]

Exporting items

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.

Subsections of Exporting

Automatic export

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
  • citekey pinning:
    • pro: no setup, free
    • 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:

  1. git pull
  2. Performs the export
  3. git add <your library file>
  4. git commit -m <your library file>
  5. 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.
  • download the Pandoc filter
  • optional: add some metadata to your markdown file in a YAML header:
---
# all the regular stuff you have here
zotero:
  library: <group name> # omitted to use your personal library
  scannable-cite: false # only relevant when you're compiling to scannable-cite .odt
  client: <zotero or jurism> # defaults to zotero
  author-in-text: false # when true, enabled fake author-name-only cites by replacing it with the text of the last names of the authors
  csl-style: apa # pre-fill the style
  sorted: true # sort clustered citations by author.
...

or you can specify them on the pandoc command line:

pandoc -s --lua-filter=zotero.lua --metadata=zotero_scannable_cite:true --metadata=zotero_client:jurism ...

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 OK before 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.

Pull export

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

\addbibresource[location=remote]{http://127.0.0.1:23119/better-bibtex/collection?/0/8CV58ZVD.biblatex}

format can be:

  • biblatex for BibLaTeX
  • bibtex for BibTeX
  • json or csljson for CSL-JSON
  • yaml, yml or cslyaml for CSL-JSON in YAML format
  • jzon for BetterBibTeX JSON debug format
  • the value of translatorID taken from the header of any existing Zotero translator to get an export in that translator format

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.


  1. Replace portnumber 23119 with 24119 for Juris-M. ↩︎

Scripting

You wanted customized…

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:

  1. BetterBibLaTeX
  2. BetterBibTeX
  3. BetterCSLJSON
  4. 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 (Translator.BetterBibLaTeX) {
  ...
}

or alternately on the full name using a switch

switch (Translator.header.label) {
  case 'Better BibLaTeX':
    ...
    break;
  case 'Better BibTeX':
    ...
    break;
  case 'Better CSL JSON':
    ...
    break;
  case 'Better CSL YAML':
    ...
    break;
}

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 reference.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:

<tr>
  
    <td>annotation<sup>Z</sup></td>
  
    <td>artwork</td>
  
    <td>attachment</td>
  
    <td>audioRecording</td>
  
</tr>

<tr>
  
    <td>bill</td>
  
    <td>blogPost</td>
  
    <td>book</td>
  
    <td>bookSection</td>
  
</tr>

<tr>
  
    <td>case</td>
  
    <td>classic<sup>JM</sup></td>
  
    <td>computerProgram</td>
  
    <td>conferencePaper</td>
  
</tr>

<tr>
  
    <td>dataset<sup>Z</sup></td>
  
    <td>dictionaryEntry</td>
  
    <td>document</td>
  
    <td>email</td>
  
</tr>

<tr>
  
    <td>encyclopediaArticle</td>
  
    <td>film</td>
  
    <td>forumPost</td>
  
    <td>gazette<sup>JM</sup></td>
  
</tr>

<tr>
  
    <td>hearing</td>
  
    <td>instantMessage</td>
  
    <td>interview</td>
  
    <td>journalArticle</td>
  
</tr>

<tr>
  
    <td>legalCommentary<sup>JM</sup></td>
  
    <td>letter</td>
  
    <td>magazineArticle</td>
  
    <td>manuscript</td>
  
</tr>

<tr>
  
    <td>map</td>
  
    <td>newspaperArticle</td>
  
    <td>note</td>
  
    <td>patent</td>
  
</tr>

<tr>
  
    <td>podcast</td>
  
    <td>preprint<sup>Z</sup></td>
  
    <td>presentation</td>
  
    <td>radioBroadcast</td>
  
</tr>

<tr>
  
    <td>regulation<sup>JM</sup></td>
  
    <td>report</td>
  
    <td>standard</td>
  
    <td>statute</td>
  
</tr>

<tr>
  
    <td>thesis</td>
  
    <td>treaty<sup>JM</sup></td>
  
    <td>tvBroadcast</td>
  
    <td>videoRecording</td>
  
</tr>

<tr>
  
    <td>webpage</td>
  
    <td></td>
  
    <td></td>
  
    <td></td>
  
</tr>

Other fields on the zotero object are:

<tr>
  
    <td>DOI</td>
  
    <td>ISBN</td>
  
    <td>ISSN</td>
  
    <td>abstractNote</td>
  
</tr>

<tr>
  
    <td>accessDate</td>
  
    <td>adminFlag<sup>JM</sup></td>
  
    <td>adoptionDate<sup>JM</sup></td>
  
    <td>album<sup>JM</sup></td>
  
</tr>

<tr>
  
    <td>applicationNumber</td>
  
    <td>archive</td>
  
    <td>archiveCollection<sup>JM</sup></td>
  
    <td>archiveID<sup>Z</sup></td>
  
</tr>

<tr>
  
    <td>archiveLocation</td>
  
    <td>artworkMedium</td>
  
    <td>artworkSize</td>
  
    <td>assemblyNumber<sup>JM</sup></td>
  
</tr>

<tr>
  
    <td>assignee</td>
  
    <td>audioFileType</td>
  
    <td>audioRecordingFormat</td>
  
    <td>authority<sup>Z</sup></td>
  
</tr>

<tr>
  
    <td>billNumber</td>
  
    <td>blogTitle</td>
  
    <td>bookAbbreviation<sup>JM</sup></td>
  
    <td>bookTitle</td>
  
</tr>

<tr>
  
    <td>callNumber</td>
  
    <td>caseName</td>
  
    <td>code</td>
  
    <td>codeNumber</td>
  
</tr>

<tr>
  
    <td>codePages</td>
  
    <td>codeVolume</td>
  
    <td>committee</td>
  
    <td>company</td>
  
</tr>

<tr>
  
    <td>conferenceDate<sup>JM</sup></td>
  
    <td>conferenceName</td>
  
    <td>country</td>
  
    <td>court</td>
  
</tr>

<tr>
  
    <td>date</td>
  
    <td>dateAmended<sup>JM</sup></td>
  
    <td>dateDecided</td>
  
    <td>dateEnacted</td>
  
</tr>

<tr>
  
    <td>dictionaryTitle</td>
  
    <td>distributor</td>
  
    <td>division<sup>JM</sup></td>
  
    <td>docketNumber</td>
  
</tr>

<tr>
  
    <td>documentName<sup>JM</sup></td>
  
    <td>documentNumber</td>
  
    <td>edition</td>
  
    <td>encyclopediaTitle</td>
  
</tr>

<tr>
  
    <td>episodeNumber</td>
  
    <td>filingDate</td>
  
    <td>firstPage</td>
  
    <td>format<sup>Z</sup></td>
  
</tr>

<tr>
  
    <td>forumTitle</td>
  
    <td>gazetteFlag<sup>JM</sup></td>
  
    <td>genre</td>
  
    <td>history</td>
  
</tr>

<tr>
  
    <td>identifier<sup>Z</sup></td>
  
    <td>institution</td>
  
    <td>interviewMedium</td>
  
    <td>issue</td>
  
</tr>

<tr>
  
    <td>issueDate</td>
  
    <td>issuingAuthority</td>
  
    <td>journalAbbreviation</td>
  
    <td>jurisdiction<sup>JM</sup></td>
  
</tr>

<tr>
  
    <td>label</td>
  
    <td>language</td>
  
    <td>legalStatus</td>
  
    <td>legislativeBody</td>
  
</tr>

<tr>
  
    <td>letterType</td>
  
    <td>libraryCatalog</td>
  
    <td>manuscriptType</td>
  
    <td>mapType</td>
  
</tr>

<tr>
  
    <td>medium</td>
  
    <td>meetingName</td>
  
    <td>meetingNumber<sup>JM</sup></td>
  
    <td>nameOfAct</td>
  
</tr>

<tr>
  
    <td>network</td>
  
    <td>newsCaseDate<sup>JM</sup></td>
  
    <td>numPages</td>
  
    <td>number</td>
  
</tr>

<tr>
  
    <td>numberOfVolumes</td>
  
    <td>openingDate<sup>JM</sup></td>
  
    <td>opus<sup>JM</sup></td>
  
    <td>organization<sup>Z</sup></td>
  
</tr>

<tr>
  
    <td>originalDate<sup>JM</sup></td>
  
    <td>pages</td>
  
    <td>parentTreaty<sup>JM</sup></td>
  
    <td>patentNumber</td>
  
</tr>

<tr>
  
    <td>place</td>
  
    <td>postType</td>
  
    <td>presentationType</td>
  
    <td>priorityDate<sup>JM</sup></td>
  
</tr>

<tr>
  
    <td>priorityNumbers</td>
  
    <td>proceedingsTitle</td>
  
    <td>programTitle</td>
  
    <td>programmingLanguage</td>
  
</tr>

<tr>
  
    <td>publicLawNumber</td>
  
    <td>publicationDate<sup>JM</sup></td>
  
    <td>publicationNumber<sup>JM</sup></td>
  
    <td>publicationTitle</td>
  
</tr>

<tr>
  
    <td>publisher</td>
  
    <td>references</td>
  
    <td>regnalYear<sup>JM</sup></td>
  
    <td>regulationType<sup>JM</sup></td>
  
</tr>

<tr>
  
    <td>regulatoryBody<sup>JM</sup></td>
  
    <td>reign<sup>JM</sup></td>
  
    <td>release<sup>JM</sup></td>
  
    <td>reportNumber</td>
  
</tr>

<tr>
  
    <td>reportType</td>
  
    <td>reporter</td>
  
    <td>reporterVolume</td>
  
    <td>repository<sup>Z</sup></td>
  
</tr>

<tr>
  
    <td>repositoryLocation<sup>Z</sup></td>
  
    <td>resolutionLabel<sup>JM</sup></td>
  
    <td>rights</td>
  
    <td>runningTime</td>
  
</tr>

<tr>
  
    <td>scale</td>
  
    <td>section</td>
  
    <td>series</td>
  
    <td>seriesNumber</td>
  
</tr>

<tr>
  
    <td>seriesText</td>
  
    <td>seriesTitle</td>
  
    <td>session</td>
  
    <td>sessionType<sup>JM</sup></td>
  
</tr>

<tr>
  
    <td>shortTitle</td>
  
    <td>signingDate<sup>JM</sup></td>
  
    <td>status</td>
  
    <td>studio</td>
  
</tr>

<tr>
  
    <td>subject</td>
  
    <td>supplementName<sup>JM</sup></td>
  
    <td>system</td>
  
    <td>thesisType</td>
  
</tr>

<tr>
  
    <td>title</td>
  
    <td>treatyNumber<sup>JM</sup></td>
  
    <td>type</td>
  
    <td>university</td>
  
</tr>

<tr>
  
    <td>url</td>
  
    <td>versionNumber</td>
  
    <td>videoRecordingFormat</td>
  
    <td>volume</td>
  
</tr>

<tr>
  
    <td>volumeTitle<sup>JM</sup></td>
  
    <td>websiteTitle</td>
  
    <td>websiteType</td>
  
    <td>yearAsVolume<sup>JM</sup></td>
  
</tr>

(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:

if (Translator.BetterTeX) {
  tex.add({ name: 'keywords', value: zotero.tags, sep: ', ', enc: 'tags' });
}

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) {
  var doi = 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

  const front = ['author', 'date', 'title', 'publisher']
  const order = front.filter(field => tex.has[field]).concat(Object.keys(tex.has).filter(field => !front.includes(field)))
  for (const [field, value] of order.map(f => [f, tex.has[f]])) {
    delete tex.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}
}

Further details Export to Biblatex/Bibtex. Custom field order. #512.

Case-protect italicized text

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
  const note = ['annotation', 'note'].find(field => tex.has[field])

  if (note) {
    let notes = 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 (const creator of zotero.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

if you then apply a postscript such as

if (Translator.BetterBibLaTeX) {
  // biblatex-mla
  if (zotero.archive && zotero.archiveLocation) {
    tex.add({ name: 'type', value: tex.entrytype })
    tex.entrytype = 'unpublished'
    tex.add({ name: 'library', value: zotero.archive})
    tex.add({ name: 'number', value: zotero.archiveLocation })
  }
}

you get

@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'

Export season for BibTeX

if (Translator.BetterBibTeX && tex.date.type === 'season') {
  tex.add({ name: 'month', value: ['', 'spring', 'summer', 'fall', 'winter'][tex.date.season] })
}

Adding rights field in BibLaTeX

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 (const att of zotero.attachments) {
    if (att.localPath) {
      att.localPath = att.localPath.replace(RegExp("^\/.*?\/.*?\/"), "~/")
    }
  }
  tex.add({ name: 'file', value: zotero.attachments, enc: 'attachments' })
  return { cache: false }
}

From discussion here.

Adding file field for CSL JSON export

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) {
	entry.file = item.attachments.map(a => a.localPath).join(";");
}

Convert Windows attachment paths to Unix

if (Translator.BetterTeX && !Translator.options.exportFileData && item.attachments && Translator.exportPath.includes('\\\\')) {
  if (item.attachments) {
    reference.add({ name: 'file', bibtex: reference.enc_attachments({ value: item.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.

label type zotero/jurism csl
access date date accessDate accessed
admin flag text adminFlag¹ admin-flag¹
adoption date date adoptionDate¹
application number text applicationNumber
archive collection text archiveCollection¹ archive_collection¹
archive id text number number
archive location text archiveLocation archive_location
archive place text archive-place
artwork medium text medium
artwork size text artworkSize
assembly number text assemblyNumber¹ / seriesNumber
attorney agent name attorneyAgent attorneyAgent
audio file type text medium
audio recording format text medium
bill number text number number
blog title text publicationTitle
book abbreviation text journalAbbreviation container-title-short
book author name bookAuthor container-author
book title text publicationTitle
call number text callNumber call-number
case name text title title
cast member name castMember castMember
chapter number text session chapter-number
citation key text citationKey²
code number text codeNumber
code pages text pages page
code volume text volume
collection editor name seriesEditor collection-editor
collection number text assemblyNumber¹ / regnalYear¹ / seriesNumber / yearAsVolume¹ collection-number
collection title text parentTreaty¹ / series / seriesTitle collection-title
conference date date conferenceDate¹
conference name text conferenceName
container author name bookAuthor container-author
container title text code / publicationTitle / reporter container-title
container title short text journalAbbreviation container-title-short
csl type text csl-type
date amended date dateAmended¹
date decided date date issued
date enacted date date issued
dictionary title text publicationTitle
docket number text number number
document name text documentName¹ document-name¹
document number text documentNumber¹ / number document-number¹
editorial director name editorial-director
encyclopedia title text publicationTitle
episode number text number number
event date date conferenceDate¹ / dateAmended¹ / signingDate¹ event-date
event place text event-place
event title text event-title²
filing date date filingDate submitted
first page text pages page
forum title text publicationTitle
gazette flag text gazetteFlag¹ gazette-flag¹
interview medium text medium
issue date date date issued
issuing authority text authority² / issuingAuthority¹
journal abbreviation text journalAbbreviation container-title-short
legal status text legalStatus¹ / status status
legislative body text authority² / legislativeBody¹
letter type text type
library catalog text libraryCatalog source
manuscript type text type
map type text type
meeting name text meetingName
meeting number text meetingNumber¹
name of act text title title
news case date date newsCaseDate¹
num pages text numPages number-of-pages
number of pages text numPages number-of-pages
number of volumes text numberOfVolumes number-of-volumes
opening date date openingDate¹ opening-date¹
original author name original-author
original date date originalDate¹ original-date
original publisher text original-publisher
original publisher place text original-publisher-place
original title text original-title
parent treaty text parentTreaty¹
patent number text number number
post type text type
presentation type text type
priority date date priorityDate¹
priority numbers text priorityNumbers
proceedings title text publicationTitle
program title text publicationTitle
programming language text programmingLanguage
public law number text number number
publication date date publicationDate¹ publication-date¹
publication number text publicationNumber¹ publication-number¹
publication title text publicationTitle
publisher place text publisher-place
regnal year text regnalYear¹
regulation type text regulationType¹ / type
regulatory body text legislativeBody¹ / regulatoryBody¹
report number text number number
report type text type
reporter volume text volume
repository location text place event-place / publisher-place
resolution label text resolutionLabel¹
reviewed author name reviewedAuthor reviewed-author
reviewed title text reviewed-title
running time text runningTime
script writer name scriptwriter script-writer²
series editor name seriesEditor collection-editor
series number text seriesNumber
series text text seriesText
series title text seriesTitle
session type text sessionType¹ / type
short title text shortTitle title-short
signing date date signingDate¹
supplement name text supplementName¹ supplement¹
testimony by name testimonyBy¹ testimonyBy¹
thesis type text type
title short text shortTitle title-short
treaty number text number number
version number text versionNumber version
video recording format text medium
volume title text volumeTitle¹ volume-title¹
website title text publicationTitle
website type text type
words by name wordsBy wordsBy
year as volume text yearAsVolume¹

¹ only supported in Juris-M

Unicode

LaTeX en unicode

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:

wasysym

character text math character text math character text math character text math
\pisces \pisces \rightmoon \leftmoon

unicode-math

character text math character text math character text math character text math
\euro ̀ \grave ́ \acute ̃ \tilde
̆ \breve ̇ \dot ̈ \ddot ̉ \ovhook
̌ \check ̐ \candra ̒ \oturnedcomma ̕ \ocommatopright
̚ \droang ͍ \underleftrightarrow Α \mupAlpha Β \mupBeta
Γ \mupGamma Δ \mupDelta Ε \mupEpsilon Ζ \mupZeta
Η \mupEta Θ \mupTheta Ι \mupIota Κ \mupKappa
Λ \mupLambda Μ \mupMu Ν \mupNu Ο \mupOmicron
Ρ \mupRho Τ \mupTau Χ \mupChi ο \mupomicron
ϐ \varbeta ϰ \varkappa ϶ \upbackepsilon 𝐀 \mbfA
𝐁 \mbfB 𝐂 \mbfC 𝐃 \mbfD 𝐄 \mbfE
𝐅 \mbfF 𝐆 \mbfG 𝐇 \mbfH 𝐈 \mbfI
𝐉 \mbfJ 𝐊 \mbfK 𝐋 \mbfL 𝐌 \mbfM
𝐍 \mbfN 𝐎 \mbfO 𝐏 \mbfP 𝐐 \mbfQ
𝐑 \mbfR 𝐒 \mbfS 𝐓 \mbfT 𝐔 \mbfU
𝐕 \mbfV 𝐖 \mbfW 𝐗 \mbfX 𝐘 \mbfY
𝐙 \mbfZ 𝐚 \mbfa 𝐛 \mbfb 𝐜 \mbfc
𝐝 \mbfd 𝐞 \mbfe 𝐟 \mbff 𝐠 \mbfg
𝐡 \mbfh 𝐢 \mbfi 𝐣 \mbfj 𝐤 \mbfk
𝐥 \mbfl 𝐦 \mbfm 𝐧 \mbfn 𝐨 \mbfo
𝐩 \mbfp 𝐪 \mbfq 𝐫 \mbfr 𝐬 \mbfs
𝐭 \mbft 𝐮 \mbfu 𝐯 \mbfv 𝐰 \mbfw
𝐱 \mbfx 𝐲 \mbfy 𝐳 \mbfz 𝐴 \mitA
𝐵 \mitB 𝐶 \mitC 𝐷 \mitD 𝐸 \mitE
𝐹 \mitF 𝐺 \mitG 𝐻 \mitH 𝐼 \mitI
𝐽 \mitJ 𝐾 \mitK 𝐿 \mitL 𝑀 \mitM
𝑁 \mitN 𝑂 \mitO 𝑃 \mitP 𝑄 \mitQ
𝑅 \mitR 𝑆 \mitS 𝑇 \mitT 𝑈 \mitU
𝑉 \mitV 𝑊 \mitW 𝑋 \mitX 𝑌 \mitY
𝑍 \mitZ 𝑎 \mita 𝑏 \mitb 𝑐 \mitc
𝑑 \mitd 𝑒 \mite 𝑓 \mitf 𝑔 \mitg
𝑖 \miti 𝑗 \mitj 𝑘 \mitk 𝑙 \mitl
𝑚 \mitm 𝑛 \mitn 𝑜 \mito 𝑝 \mitp
𝑞 \mitq 𝑟 \mitr 𝑠 \mits 𝑡 \mitt
𝑢 \mitu 𝑣 \mitv 𝑤 \mitw 𝑥 \mitx
𝑦 \mity 𝑧 \mitz 𝑨 \mbfitA 𝑩 \mbfitB
𝑪 \mbfitC 𝑫 \mbfitD 𝑬 \mbfitE 𝑭 \mbfitF
𝑮 \mbfitG 𝑯 \mbfitH 𝑰 \mbfitI 𝑱 \mbfitJ
𝑲 \mbfitK 𝑳 \mbfitL 𝑴 \mbfitM 𝑵 \mbfitN
𝑶 \mbfitO 𝑷 \mbfitP 𝑸 \mbfitQ 𝑹 \mbfitR
𝑺 \mbfitS 𝑻 \mbfitT 𝑼 \mbfitU 𝑽 \mbfitV
𝑾 \mbfitW 𝑿 \mbfitX 𝒀 \mbfitY 𝒁 \mbfitZ
𝒂 \mbfita 𝒃 \mbfitb 𝒄 \mbfitc 𝒅 \mbfitd
𝒆 \mbfite 𝒇 \mbfitf 𝒈 \mbfitg 𝒉 \mbfith
𝒊 \mbfiti 𝒋 \mbfitj 𝒌 \mbfitk 𝒍 \mbfitl
𝒎 \mbfitm 𝒏 \mbfitn 𝒐 \mbfito 𝒑 \mbfitp
𝒒 \mbfitq 𝒓 \mbfitr 𝒔 \mbfits 𝒕 \mbfitt
𝒖 \mbfitu 𝒗 \mbfitv 𝒘 \mbfitw 𝒙 \mbfitx
𝒚 \mbfity 𝒛 \mbfitz 𝒜 \mscrA 𝒞 \mscrC
𝒟 \mscrD 𝒢 \mscrG 𝒥 \mscrJ 𝒦 \mscrK
𝒩 \mscrN 𝒪 \mscrO 𝒫 \mscrP 𝒬 \mscrQ
𝒮 \mscrS 𝒯 \mscrT 𝒰 \mscrU 𝒱 \mscrV
𝒲 \mscrW 𝒳 \mscrX 𝒴 \mscrY 𝒵 \mscrZ
𝒶 \mscra 𝒷 \mscrb 𝒸 \mscrc 𝒹 \mscrd
𝒻 \mscrf 𝒽 \mscrh 𝒾 \mscri 𝒿 \mscrj
𝓀 \mscrk 𝓁 \mscrl 𝓂 \mscrm 𝓃 \mscrn
𝓅 \mscrp 𝓆 \mscrq 𝓇 \mscrr 𝓈 \mscrs
𝓉 \mscrt 𝓊 \mscru 𝓋 \mscrv 𝓌 \mscrw
𝓍 \mscrx 𝓎 \mscry 𝓏 \mscrz 𝓐 \mbfscrA
𝓑 \mbfscrB 𝓒 \mbfscrC 𝓓 \mbfscrD 𝓔 \mbfscrE
𝓕 \mbfscrF 𝓖 \mbfscrG 𝓗 \mbfscrH 𝓘 \mbfscrI
𝓙 \mbfscrJ 𝓚 \mbfscrK 𝓛 \mbfscrL 𝓜 \mbfscrM
𝓝 \mbfscrN 𝓞 \mbfscrO 𝓟 \mbfscrP 𝓠 \mbfscrQ
𝓡 \mbfscrR 𝓢 \mbfscrS 𝓣 \mbfscrT 𝓤 \mbfscrU
𝓥 \mbfscrV 𝓦 \mbfscrW 𝓧 \mbfscrX 𝓨 \mbfscrY
𝓩 \mbfscrZ 𝓪 \mbfscra 𝓫 \mbfscrb 𝓬 \mbfscrc
𝓭 \mbfscrd 𝓮 \mbfscre 𝓯 \mbfscrf 𝓰 \mbfscrg
𝓱 \mbfscrh 𝓲 \mbfscri 𝓳 \mbfscrj 𝓴 \mbfscrk
𝓵 \mbfscrl 𝓶 \mbfscrm 𝓷 \mbfscrn 𝓸 \mbfscro
𝓹 \mbfscrp 𝓺 \mbfscrq 𝓻 \mbfscrr 𝓼 \mbfscrs
𝓽 \mbfscrt 𝓾 \mbfscru 𝓿 \mbfscrv 𝔀 \mbfscrw
𝔁 \mbfscrx 𝔂 \mbfscry 𝔃 \mbfscrz 𝔄 \mfrakA
𝔅 \mfrakB 𝔇 \mfrakD 𝔈 \mfrakE 𝔉 \mfrakF
𝔊 \mfrakG 𝔍 \mfrakJ 𝔎 \mfrakK 𝔏 \mfrakL
𝔐 \mfrakM 𝔑 \mfrakN 𝔒 \mfrakO 𝔓 \mfrakP
𝔔 \mfrakQ 𝔖 \mfrakS 𝔗 \mfrakT 𝔘 \mfrakU
𝔙 \mfrakV 𝔚 \mfrakW 𝔛 \mfrakX 𝔜 \mfrakY
𝔞 \mfraka 𝔟 \mfrakb 𝔠 \mfrakc 𝔡 \mfrakd
𝔢 \mfrake 𝔣 \mfrakf 𝔤 \mfrakg 𝔥 \mfrakh
𝔦 \mfraki 𝔧 \mfrakj 𝔨 \mfrakk 𝔩 \mfrakl
𝔪 \mfrakm 𝔫 \mfrakn 𝔬 \mfrako 𝔭 \mfrakp
𝔮 \mfrakq 𝔯 \mfrakr 𝔰 \mfraks 𝔱 \mfrakt
𝔲 \mfraku 𝔳 \mfrakv 𝔴 \mfrakw 𝔵 \mfrakx
𝔶 \mfraky 𝔷 \mfrakz 𝔸 \BbbA 𝔹 \BbbB
𝔻 \BbbD 𝔼 \BbbE 𝔽 \BbbF 𝔾 \BbbG
𝕀 \BbbI 𝕁 \BbbJ 𝕂 \BbbK 𝕃 \BbbL
𝕄 \BbbM 𝕆 \BbbO 𝕊 \BbbS 𝕋 \BbbT
𝕌 \BbbU 𝕍 \BbbV 𝕎 \BbbW 𝕏 \BbbX
𝕐 \BbbY 𝕒 \Bbba 𝕓 \Bbbb 𝕔 \Bbbc
𝕕 \Bbbd 𝕖 \Bbbe 𝕗 \Bbbf 𝕘 \Bbbg
𝕙 \Bbbh 𝕚 \Bbbi 𝕛 \Bbbj 𝕜 \Bbbk
𝕝 \Bbbl 𝕞 \Bbbm 𝕟 \Bbbn 𝕠 \Bbbo
𝕡 \Bbbp 𝕢 \Bbbq 𝕣 \Bbbr 𝕤 \Bbbs
𝕥 \Bbbt 𝕦 \Bbbu 𝕧 \Bbbv 𝕨 \Bbbw
𝕩 \Bbbx 𝕪 \Bbby 𝕫 \Bbbz 𝕬 \mbffrakA
𝕭 \mbffrakB 𝕮 \mbffrakC 𝕯 \mbffrakD 𝕰 \mbffrakE
𝕱 \mbffrakF 𝕲 \mbffrakG 𝕳 \mbffrakH 𝕴 \mbffrakI
𝕵 \mbffrakJ 𝕶 \mbffrakK 𝕷 \mbffrakL 𝕸 \mbffrakM
𝕹 \mbffrakN 𝕺 \mbffrakO 𝕻 \mbffrakP 𝕼 \mbffrakQ
𝕽 \mbffrakR 𝕾 \mbffrakS 𝕿 \mbffrakT 𝖀 \mbffrakU
𝖁 \mbffrakV 𝖂 \mbffrakW 𝖃 \mbffrakX 𝖄 \mbffrakY
𝖅 \mbffrakZ 𝖆 \mbffraka 𝖇 \mbffrakb 𝖈 \mbffrakc
𝖉 \mbffrakd 𝖊 \mbffrake 𝖋 \mbffrakf 𝖌 \mbffrakg
𝖍 \mbffrakh 𝖎 \mbffraki 𝖏 \mbffrakj 𝖐 \mbffrakk
𝖑 \mbffrakl 𝖒 \mbffrakm 𝖓 \mbffrakn 𝖔 \mbffrako
𝖕 \mbffrakp 𝖖 \mbffrakq 𝖗 \mbffrakr 𝖘 \mbffraks
𝖙 \mbffrakt 𝖚 \mbffraku 𝖛 \mbffrakv 𝖜 \mbffrakw
𝖝 \mbffrakx 𝖞 \mbffraky 𝖟 \mbffrakz 𝖠 \msansA
𝖡 \msansB 𝖢 \msansC 𝖣 \msansD 𝖤 \msansE
𝖥 \msansF 𝖦 \msansG 𝖧 \msansH 𝖨 \msansI
𝖩 \msansJ 𝖪 \msansK 𝖫 \msansL 𝖬 \msansM
𝖭 \msansN 𝖮 \msansO 𝖯 \msansP 𝖰 \msansQ
𝖱 \msansR 𝖲 \msansS 𝖳 \msansT 𝖴 \msansU
𝖵 \msansV 𝖶 \msansW 𝖷 \msansX 𝖸 \msansY
𝖹 \msansZ 𝖺 \msansa 𝖻 \msansb 𝖼 \msansc
𝖽 \msansd 𝖾 \msanse 𝖿 \msansf 𝗀 \msansg
𝗁 \msansh 𝗂 \msansi 𝗃 \msansj 𝗄 \msansk
𝗅 \msansl 𝗆 \msansm 𝗇 \msansn 𝗈 \msanso
𝗉 \msansp 𝗊 \msansq 𝗋 \msansr 𝗌 \msanss
𝗍 \msanst 𝗎 \msansu 𝗏 \msansv 𝗐 \msansw
𝗑 \msansx 𝗒 \msansy 𝗓 \msansz 𝗔 \mbfsansA
𝗕 \mbfsansB 𝗖 \mbfsansC 𝗗 \mbfsansD 𝗘 \mbfsansE
𝗙 \mbfsansF 𝗚 \mbfsansG 𝗛 \mbfsansH 𝗜 \mbfsansI
𝗝 \mbfsansJ 𝗞 \mbfsansK 𝗟 \mbfsansL 𝗠 \mbfsansM
𝗡 \mbfsansN 𝗢 \mbfsansO 𝗣 \mbfsansP 𝗤 \mbfsansQ
𝗥 \mbfsansR 𝗦 \mbfsansS 𝗧 \mbfsansT 𝗨 \mbfsansU
𝗩 \mbfsansV 𝗪 \mbfsansW 𝗫 \mbfsansX 𝗬 \mbfsansY
𝗭 \mbfsansZ 𝗮 \mbfsansa 𝗯 \mbfsansb 𝗰 \mbfsansc
𝗱 \mbfsansd 𝗲 \mbfsanse 𝗳 \mbfsansf 𝗴 \mbfsansg
𝗵 \mbfsansh 𝗶 \mbfsansi 𝗷 \mbfsansj 𝗸 \mbfsansk
𝗹 \mbfsansl 𝗺 \mbfsansm 𝗻 \mbfsansn 𝗼 \mbfsanso
𝗽 \mbfsansp 𝗾 \mbfsansq 𝗿 \mbfsansr 𝘀 \mbfsanss
𝘁 \mbfsanst 𝘂 \mbfsansu 𝘃 \mbfsansv 𝘄 \mbfsansw
𝘅 \mbfsansx 𝘆 \mbfsansy 𝘇 \mbfsansz 𝘈 \mitsansA
𝘉 \mitsansB 𝘊 \mitsansC 𝘋 \mitsansD 𝘌 \mitsansE
𝘍 \mitsansF 𝘎 \mitsansG 𝘏 \mitsansH 𝘐 \mitsansI
𝘑 \mitsansJ 𝘒 \mitsansK 𝘓 \mitsansL 𝘔 \mitsansM
𝘕 \mitsansN 𝘖 \mitsansO 𝘗 \mitsansP 𝘘 \mitsansQ
𝘙 \mitsansR 𝘚 \mitsansS 𝘛 \mitsansT 𝘜 \mitsansU
𝘝 \mitsansV 𝘞 \mitsansW 𝘟 \mitsansX 𝘠 \mitsansY
𝘡 \mitsansZ 𝘢 \mitsansa 𝘣 \mitsansb 𝘤 \mitsansc
𝘥 \mitsansd 𝘦 \mitsanse 𝘧 \mitsansf 𝘨 \mitsansg
𝘩 \mitsansh 𝘪 \mitsansi 𝘫 \mitsansj 𝘬 \mitsansk
𝘭 \mitsansl 𝘮 \mitsansm 𝘯 \mitsansn 𝘰 \mitsanso
𝘱 \mitsansp 𝘲 \mitsansq 𝘳 \mitsansr 𝘴 \mitsanss
𝘵 \mitsanst 𝘶 \mitsansu 𝘷 \mitsansv 𝘸 \mitsansw
𝘹 \mitsansx 𝘺 \mitsansy 𝘻 \mitsansz 𝘼 \mbfitsansA
𝘽 \mbfitsansB 𝘾 \mbfitsansC 𝘿 \mbfitsansD 𝙀 \mbfitsansE
𝙁 \mbfitsansF 𝙂 \mbfitsansG 𝙃 \mbfitsansH 𝙄 \mbfitsansI
𝙅 \mbfitsansJ 𝙆 \mbfitsansK 𝙇 \mbfitsansL 𝙈 \mbfitsansM
𝙉 \mbfitsansN 𝙊 \mbfitsansO 𝙋 \mbfitsansP 𝙌 \mbfitsansQ
𝙍 \mbfitsansR 𝙎 \mbfitsansS 𝙏 \mbfitsansT 𝙐 \mbfitsansU
𝙑 \mbfitsansV 𝙒 \mbfitsansW 𝙓 \mbfitsansX 𝙔 \mbfitsansY
𝙕 \mbfitsansZ 𝙖 \mbfitsansa 𝙗 \mbfitsansb 𝙘 \mbfitsansc
𝙙 \mbfitsansd 𝙚 \mbfitsanse 𝙛 \mbfitsansf 𝙜 \mbfitsansg
𝙝 \mbfitsansh 𝙞 \mbfitsansi 𝙟 \mbfitsansj 𝙠 \mbfitsansk
𝙡 \mbfitsansl 𝙢 \mbfitsansm 𝙣 \mbfitsansn 𝙤 \mbfitsanso
𝙥 \mbfitsansp 𝙦 \mbfitsansq 𝙧 \mbfitsansr 𝙨 \mbfitsanss
𝙩 \mbfitsanst 𝙪 \mbfitsansu 𝙫 \mbfitsansv 𝙬 \mbfitsansw
𝙭 \mbfitsansx 𝙮 \mbfitsansy 𝙯 \mbfitsansz 𝙰 \mttA
𝙱 \mttB 𝙲 \mttC 𝙳 \mttD 𝙴 \mttE
𝙵 \mttF 𝙶 \mttG 𝙷 \mttH 𝙸 \mttI
𝙹 \mttJ 𝙺 \mttK 𝙻 \mttL 𝙼 \mttM
𝙽 \mttN 𝙾 \mttO 𝙿 \mttP 𝚀 \mttQ
𝚁 \mttR 𝚂 \mttS 𝚃 \mttT 𝚄 \mttU
𝚅 \mttV 𝚆 \mttW 𝚇 \mttX 𝚈 \mttY
𝚉 \mttZ 𝚊 \mtta 𝚋 \mttb 𝚌 \mttc
𝚍 \mttd 𝚎 \mtte 𝚏 \mttf 𝚐 \mttg
𝚑 \mtth 𝚒 \mtti 𝚓 \mttj 𝚔 \mttk
𝚕 \mttl 𝚖 \mttm 𝚗 \mttn 𝚘 \mtto
𝚙 \mttp 𝚚 \mttq 𝚛 \mttr 𝚜 \mtts
𝚝 \mttt 𝚞 \mttu 𝚟 \mttv 𝚠 \mttw
𝚡 \mttx 𝚢 \mtty 𝚣 \mttz 𝚤 \imath
𝚥 \jmath 𝚨 \mbfAlpha 𝚩 \mbfBeta 𝚪 \mbfGamma
𝚫 \mbfDelta 𝚬 \mbfEpsilon 𝚭 \mbfZeta 𝚮 \mbfEta
𝚯 \mbfTheta 𝚰 \mbfIota 𝚱 \mbfKappa 𝚲 \mbfLambda
𝚳 \mbfMu 𝚴 \mbfNu 𝚵 \mbfXi 𝚶 \mbfOmicron
𝚷 \mbfPi 𝚸 \mbfRho 𝚹 \mbfvarTheta 𝚺 \mbfSigma
𝚻 \mbfTau 𝚼 \mbfUpsilon 𝚽 \mbfPhi 𝚾 \mbfChi
𝚿 \mbfPsi 𝛀 \mbfOmega 𝛁 \mbfnabla 𝛂 \mbfalpha
𝛃 \mbfbeta 𝛄 \mbfgamma 𝛅 \mbfdelta 𝛆 \mbfvarepsilon
𝛇 \mbfzeta 𝛈 \mbfeta 𝛉 \mbftheta 𝛊 \mbfiota
𝛋 \mbfkappa 𝛌 \mbflambda 𝛍 \mbfmu 𝛎 \mbfnu
𝛏 \mbfxi 𝛐 \mbfomicron 𝛑 \mbfpi 𝛒 \mbfrho
𝛓 \mbfvarsigma 𝛔 \mbfsigma 𝛕 \mbftau 𝛖 \mbfupsilon
𝛗 \mbfvarphi 𝛘 \mbfchi 𝛙 \mbfpsi 𝛚 \mbfomega
𝛛 \mbfpartial 𝛜 \mbfepsilon 𝛝 \mbfvartheta 𝛞 \mbfvarkappa
𝛟 \mbfphi 𝛠 \mbfvarrho 𝛡 \mbfvarpi 𝛢 \mitAlpha
𝛣 \mitBeta 𝛤 \mitGamma 𝛥 \mitDelta 𝛦 \mitEpsilon
𝛧 \mitZeta 𝛨 \mitEta 𝛩 \mitTheta 𝛪 \mitIota
𝛫 \mitKappa 𝛬 \mitLambda 𝛭 \mitMu 𝛮 \mitNu
𝛯 \mitXi 𝛰 \mitOmicron 𝛱 \mitPi 𝛲 \mitRho
𝛳 \mitvarTheta 𝛴 \mitSigma 𝛵 \mitTau 𝛶 \mitUpsilon
𝛷 \mitPhi 𝛸 \mitChi 𝛹 \mitPsi 𝛺 \mitOmega
𝛻 \mitnabla 𝛼 \mitalpha 𝛽 \mitbeta 𝛾 \mitgamma
𝛿 \mitdelta 𝜀 \mitvarepsilon 𝜁 \mitzeta 𝜂 \miteta
𝜃 \mittheta 𝜄 \mitiota 𝜅 \mitkappa 𝜆 \mitlambda
𝜇 \mitmu 𝜈 \mitnu 𝜉 \mitxi 𝜊 \mitomicron
𝜋 \mitpi 𝜌 \mitrho 𝜍 \mitvarsigma 𝜎 \mitsigma
𝜏 \mittau 𝜐 \mitupsilon 𝜑 \mitvarphi 𝜒 \mitchi
𝜓 \mitpsi 𝜔 \mitomega 𝜕 \mitpartial 𝜖 \mitepsilon
𝜗 \mitvartheta 𝜘 \mitvarkappa 𝜙 \mitphi 𝜚 \mitvarrho
𝜛 \mitvarpi 𝜜 \mbfitAlpha 𝜝 \mbfitBeta 𝜞 \mbfitGamma
𝜟 \mbfitDelta 𝜠 \mbfitEpsilon 𝜡 \mbfitZeta 𝜢 \mbfitEta
𝜣 \mbfitTheta 𝜤 \mbfitIota 𝜥 \mbfitKappa 𝜦 \mbfitLambda
𝜧 \mbfitMu 𝜨 \mbfitNu 𝜩 \mbfitXi 𝜪 \mbfitOmicron
𝜫 \mbfitPi 𝜬 \mbfitRho 𝜭 \mbfitvarTheta 𝜮 \mbfitSigma
𝜯 \mbfitTau 𝜰 \mbfitUpsilon 𝜱 \mbfitPhi 𝜲 \mbfitChi
𝜳 \mbfitPsi 𝜴 \mbfitOmega 𝜵 \mbfitnabla 𝜶 \mbfitalpha
𝜷 \mbfitbeta 𝜸 \mbfitgamma 𝜹 \mbfitdelta 𝜺 \mbfitvarepsilon
𝜻 \mbfitzeta 𝜼 \mbfiteta 𝜽 \mbfittheta 𝜾 \mbfitiota
𝜿 \mbfitkappa 𝝀 \mbfitlambda 𝝁 \mbfitmu 𝝂 \mbfitnu
𝝃 \mbfitxi 𝝄 \mbfitomicron 𝝅 \mbfitpi 𝝆 \mbfitrho
𝝇 \mbfitvarsigma 𝝈 \mbfitsigma 𝝉 \mbfittau 𝝊 \mbfitupsilon
𝝋 \mbfitvarphi 𝝌 \mbfitchi 𝝍 \mbfitpsi 𝝎 \mbfitomega
𝝏 \mbfitpartial 𝝐 \mbfitepsilon 𝝑 \mbfitvartheta 𝝒 \mbfitvarkappa
𝝓 \mbfitphi 𝝔 \mbfitvarrho 𝝕 \mbfitvarpi 𝝖 \mbfsansAlpha
𝝗 \mbfsansBeta 𝝘 \mbfsansGamma 𝝙 \mbfsansDelta 𝝚 \mbfsansEpsilon
𝝛 \mbfsansZeta 𝝜 \mbfsansEta 𝝝 \mbfsansTheta 𝝞 \mbfsansIota
𝝟 \mbfsansKappa 𝝠 \mbfsansLambda 𝝡 \mbfsansMu 𝝢 \mbfsansNu
𝝣 \mbfsansXi 𝝤 \mbfsansOmicron 𝝥 \mbfsansPi 𝝦 \mbfsansRho
𝝧 \mbfsansvarTheta 𝝨 \mbfsansSigma 𝝩 \mbfsansTau 𝝪 \mbfsansUpsilon
𝝫 \mbfsansPhi 𝝬 \mbfsansChi 𝝭 \mbfsansPsi 𝝮 \mbfsansOmega
𝝯 \mbfsansnabla 𝝰 \mbfsansalpha 𝝱 \mbfsansbeta 𝝲 \mbfsansgamma
𝝳 \mbfsansdelta 𝝴 \mbfsansvarepsilon 𝝵 \mbfsanszeta 𝝶 \mbfsanseta
𝝷 \mbfsanstheta 𝝸 \mbfsansiota 𝝹 \mbfsanskappa 𝝺 \mbfsanslambda
𝝻 \mbfsansmu 𝝼 \mbfsansnu 𝝽 \mbfsansxi 𝝾 \mbfsansomicron
𝝿 \mbfsanspi 𝞀 \mbfsansrho 𝞁 \mbfsansvarsigma 𝞂 \mbfsanssigma
𝞃 \mbfsanstau 𝞄 \mbfsansupsilon 𝞅 \mbfsansvarphi 𝞆 \mbfsanschi
𝞇 \mbfsanspsi 𝞈 \mbfsansomega 𝞉 \mbfsanspartial 𝞊 \mbfsansepsilon
𝞋 \mbfsansvartheta 𝞌 \mbfsansvarkappa 𝞍 \mbfsansphi 𝞎 \mbfsansvarrho
𝞏 \mbfsansvarpi 𝞐 \mbfitsansAlpha 𝞑 \mbfitsansBeta 𝞒 \mbfitsansGamma
𝞓 \mbfitsansDelta 𝞔 \mbfitsansEpsilon 𝞕 \mbfitsansZeta 𝞖 \mbfitsansEta
𝞗 \mbfitsansTheta 𝞘 \mbfitsansIota 𝞙 \mbfitsansKappa 𝞚 \mbfitsansLambda
𝞛 \mbfitsansMu 𝞜 \mbfitsansNu 𝞝 \mbfitsansXi 𝞞 \mbfitsansOmicron
𝞟 \mbfitsansPi 𝞠 \mbfitsansRho 𝞡 \mbfitsansvarTheta 𝞢 \mbfitsansSigma
𝞣 \mbfitsansTau 𝞤 \mbfitsansUpsilon 𝞥 \mbfitsansPhi 𝞦 \mbfitsansChi
𝞧 \mbfitsansPsi 𝞨 \mbfitsansOmega 𝞩 \mbfitsansnabla 𝞪 \mbfitsansalpha
𝞫 \mbfitsansbeta 𝞬 \mbfitsansgamma 𝞭 \mbfitsansdelta 𝞮 \mbfitsansvarepsilon
𝞯 \mbfitsanszeta 𝞰 \mbfitsanseta 𝞱 \mbfitsanstheta 𝞲 \mbfitsansiota
𝞳 \mbfitsanskappa 𝞴 \mbfitsanslambda 𝞵 \mbfitsansmu 𝞶 \mbfitsansnu
𝞷 \mbfitsansxi 𝞸 \mbfitsansomicron 𝞹 \mbfitsanspi 𝞺 \mbfitsansrho
𝞻 \mbfitsansvarsigma 𝞼 \mbfitsanssigma 𝞽 \mbfitsanstau 𝞾 \mbfitsansupsilon
𝞿 \mbfitsansvarphi 𝟀 \mbfitsanschi 𝟁 \mbfitsanspsi 𝟂 \mbfitsansomega
𝟃 \mbfitsanspartial 𝟄 \mbfitsansepsilon 𝟅 \mbfitsansvartheta 𝟆 \mbfitsansvarkappa
𝟇 \mbfitsansphi 𝟈 \mbfitsansvarrho 𝟉 \mbfitsansvarpi 𝟊 \mbfDigamma
𝟋 \mbfdigamma 𝟎 \mbfzero 𝟏 \mbfone 𝟐 \mbftwo
𝟑 \mbfthree 𝟒 \mbffour 𝟓 \mbffive 𝟔 \mbfsix
𝟕 \mbfseven 𝟖 \mbfeight 𝟗 \mbfnine 𝟘 \Bbbzero
𝟙 \Bbbone 𝟚 \Bbbtwo 𝟛 \Bbbthree 𝟜 \Bbbfour
𝟝 \Bbbfive 𝟞 \Bbbsix 𝟟 \Bbbseven 𝟠 \Bbbeight
𝟡 \Bbbnine 𝟢 \msanszero 𝟣 \msansone 𝟤 \msanstwo
𝟥 \msansthree 𝟦 \msansfour 𝟧 \msansfive 𝟨 \msanssix
𝟩 \msansseven 𝟪 \msanseight 𝟫 \msansnine 𝟬 \mbfsanszero
𝟭 \mbfsansone 𝟮 \mbfsanstwo 𝟯 \mbfsansthree 𝟰 \mbfsansfour
𝟱 \mbfsansfive 𝟲 \mbfsanssix 𝟳 \mbfsansseven 𝟴 \mbfsanseight
𝟵 \mbfsansnine 𝟶 \mttzero 𝟷 \mttone 𝟸 \mtttwo
𝟹 \mttthree 𝟺 \mttfour 𝟻 \mttfive 𝟼 \mttsix
𝟽 \mttseven 𝟾 \mtteight 𝟿 \mttnine ữ0 \arabicmaj
ữ1 \arabichad \mathhyphen \horizbar \twolowline
\enleadertwodots \dprime \trprime \backprime
\backdprime \backtrprime \caretinsert \Exclam
\tieconcat \hyphenbullet \fracslash \Question
\closure \qprime \vertoverlay \vec
\dddot \ddddot \enclosecircle \enclosesquare
\enclosediamond \overleftrightarrow \enclosetriangle \annuity
\threeunderdot \widebridgeabove \underrightharpoondown \underleftharpoondown
\underleftarrow \underrightarrow \asteraccent \Planckconst
\hslash \mscrL \mscrR \mho
\turnediota \Finv \beth \gimel
\daleth \Game \sansLturned \sansLmirrored
\Yup \CapitalDifferentialD \PropertyLine ↚ \nleftarrow
↛ \nrightarrow \twoheadleftarrow \twoheaduparrow \twoheadrightarrow
\twoheaddownarrow \leftarrowtail \rightarrowtail \mapsfrom
\mapsup \mapsdown \updownarrowbar \looparrowleft
\looparrowright \leftrightsquigarrow ↮ \nleftrightarrow \Lsh
\Rsh \reflectbox{\carriagereturn} \Rdsh \linefeed \carriagereturn
\curvearrowleft \curvearrowright \barovernorthwestarrow \barleftarrowrightarrowbar
\circlearrowleft \upharpoonright \upharpoonleft \rightharpoondown
\downharpoonright \downharpoonleft \rightleftarrows \leftrightarrows
\leftleftarrows \upuparrows \rightrightarrows \downdownarrows
\leftrightharpoons ⇍ \nLeftarrow ⇎ \nLeftrightarrow ⇏ \nRightarrow
\Nwarrow \Nearrow \Searrow \Swarrow
\Lleftarrow \Rrightarrow \leftsquigarrow \rightsquigarrow
\nHuparrow \nHdownarrow \updasharrow \downdasharrow
\leftwhitearrow \upwhitearrow \rightwhitearrow \downwhitearrow
\whitearrowupfrombar \circleonrightarrow \rightthreearrows \nvleftarrow
\nvleftrightarrow \nVleftarrow \nVleftrightarrow \leftarrowtriangle
\rightarrowtriangle \leftrightarrowtriangle \complement ∄ \nexists
\varnothing \increment \nabla \smallin
\smallni \QED \dotplus \divslash
\sqrt \rightangle \measuredangle \sphericalangle
∤ \nmid ∦ \nparallel \lcirclerightint \therefore
\because \Colon \eqcolon \backsim
\approxeq \Bumpeq \bumpeq \fallingdotseq
\risingdotseq \coloneq \eqcirc \circeq
\arceq \veeeq \triangleq \eqdef
\measeq \questeq \Equiv \lneqq
\gneqq \between ≭ \nasymp ≴ \nlesssim
≵ \ngtrsim \lessgtr \gtrless \preccurlyeq
\succcurlyeq \subsetneq \supsetneq \cupleftarrow
\cupdot \sqsubset \sqsupset \circledcirc
\circledast \circledequal \circleddash \boxplus
\boxminus \boxtimes \boxdot \assert
\Vdash \Vvdash \VDash ⊬ \nvdash
⊭ \nvDash ⊮ \nVdash ⊯ \nVDash \prurel
\scurel \vartriangleleft \vartriangleright \trianglelefteq
\trianglerighteq \multimap \intercal \veebar
\barwedge \barvee \varlrtriangle \divideontimes
\ltimes \rtimes \leftthreetimes \rightthreetimes
\backsimeq \curlyvee \curlywedge \Subset
\Supset \Cap \Cup \pitchfork
\hash \lessdot \gtrdot \lesseqgtr
\gtreqless \eqless \eqgtr \curlyeqprec
\curlyeqsucc ⋠ \npreceq ⋡ \nsucceq \sqsubsetneq
\sqsupsetneq \lnsim \gnsim \precedesnotsimilar
\succnsim ⋬ \ntrianglelefteq ⋭ \ntrianglerighteq \disin
\varisins \isins \isindot \isinobar
\isinvb \isinE \nisd \varnis
\nis \varniobar \niobar \bagmember
\diameter \house \barwedge \varbarwedge \invneg
\profline \profsurf \viewdata \turnednot
\ulcorner \urcorner \llcorner \lrcorner
\inttop \intbottom \varhexagonlrbonds \conictaper
\topbot \obar \APLboxupcaret \APLboxquestion
\rangledownzigzagarrow \hexagon \lparenuend \lparenextender
\lparenlend \rparenuend \rparenextender \rparenlend
\lbrackuend \lbrackextender \lbracklend \rbrackuend
\rbrackextender \rbracklend \lbraceuend \lbracemid
\lbracelend \vbraceextender \rbraceuend \rbracemid
\rbracelend \intextender \harrowextender \sumtop
\sumbottom \overbracket \underbracket \bbrktbrk
\sqrtbottom \lvboxline \rvboxline \varcarriagereturn
\overparen \underparen \overbrace \underbrace
\obrbrak \ubrbrak \trapezium \benzenr
\strns \fltns \accurrent \elinters
\blanksymbol \mathvisiblespace \bdtriplevdash \blockuphalf
\blocklowhalf \blockfull \blocklefthalf \blockrighthalf
\blockqtrshaded \blockhalfshaded \blockthreeqtrshaded \mdlgblksquare
\squoval \blackinwhitesquare \squarehfill \squarevfill
\squarehvfill \squarenwsefill \squareneswfill \squarecrossfill
\smblksquare \smwhtsquare \hrectangleblack \hrectangle
\vrectangleblack \vrectangle \parallelogramblack \parallelogram
\bigblacktriangleup \bigtriangleup \blacktriangle \vartriangle
\smallblacktriangleright \smalltriangleright \blackpointerright \whitepointerright
\bigblacktriangledown \blacktriangledown \triangledown \smallblacktriangleleft
\smalltriangleleft \blackpointerleft \whitepointerleft \blackinwhitediamond
\fisheye \lozenge \dottedcircle \circlevertfill
\bullseye \circlelefthalfblack \circlerighthalfblack \circlebottomhalfblack
\circletophalfblack \circleurquadblack \blackcircleulquadwhite \blacklefthalfcircle
\blackrighthalfcircle \inversebullet \inversewhitecircle \invwhiteupperhalfcircle
\invwhitelowerhalfcircle \ularc \urarc \lrarc
\llarc \topsemicircle \botsemicircle \lrblacktriangle
\llblacktriangle \ulblacktriangle \urblacktriangle \smwhtcircle
\squareleftblack \squarerightblack \squareulblack \squarelrblack
\boxbar \trianglecdot \triangleleftblack \trianglerightblack
\squareulquad \squarellquad \squarelrquad \squareurquad
\circleulquad \circlellquad \circlelrquad \circleurquad
\ultriangle \urtriangle \lltriangle \mdwhtsquare
\mdblksquare \mdsmwhtsquare \mdsmblksquare \lrtriangle
\bigstar \bigwhitestar \danger \blacksmiley
\sun \rightmoon \leftmoon \female
\male \varspadesuit \varheartsuit \vardiamondsuit
\varclubsuit \quarternote \eighthnote \twonotes
\sixteenthnote \acidfree \dicei \diceii
\diceiii \diceiv \dicev \dicevi
\circledrightdot \circledtwodots \blackcircledrightdot \blackcircledtwodots
\Hermaphrodite \mdsmwhtcircle \neuter \checkmark
\maltese \circledstar \varstar \dingasterisk
\lbrbrak \rbrbrak \draftingarrow \threedangle
\whiteinwhitetriangle \subsetcirc \supsetcirc \veedot
\bsolhsub \suphsol \diagup \longdivision
\diagdown \wedgedot \upin \pullback
\pushout \leftouterjoin \rightouterjoin \fullouterjoin
\bigbot \bigtop \DashVDash \dashVdash
\multimapinv \vlongdash \longdashv \cirbot
\lozengeminus \concavediamond \concavediamondtickleft \concavediamondtickright
\whitesquaretickleft \whitesquaretickright \rang \Lbrbrak
\Rbrbrak \UUparrow \DDownarrow \acwgapcirclearrow
\cwgapcirclearrow \rightarrowonoplus \longmapsfrom \Longmapsfrom
\Longmapsto \longrightsquigarrow \nVtwoheadrightarrow \nvLeftarrow
\nvRightarrow \nvLeftrightarrow \twoheadmapsto \Mapsfrom
\Mapsto \downarrowbarred \uparrowbarred \Uuparrow
\Ddownarrow \leftbkarrow \rightbkarrow \leftdbkarrow
\dbkarrow \drbkarrow \rightdotarrow \nvtwoheadrightarrowtail
\nVtwoheadrightarrowtail \lefttail \righttail \leftdbltail
\rightdbltail \diamondleftarrow \rightarrowdiamond \diamondleftarrowbar
\barrightarrowdiamond \nwsearrow \neswarrow \hknwarrow
\hknearrow \hksearrow \hkswarrow \tona
\toea \tosa \towa \rdiagovfdiag
\fdiagovrdiag \seovnearrow \neovsearrow \fdiagovnearrow
\rdiagovsearrow \neovnwarrow \nwovnearrow \rightcurvedarrow
\uprightcurvearrow \downrightcurvedarrow \leftdowncurvedarrow \rightdowncurvedarrow
\cwrightarcarrow \acwleftarcarrow \acwoverarcarrow \acwunderarcarrow
\curvearrowrightminus \curvearrowleftplus \cwundercurvearrow ⤿ \ccwundercurvearrow
\rightarrowshortleftarrow \leftarrowshortrightarrow \shortrightarrowleftarrow \rightarrowplus
\leftarrowplus \rightarrowx \leftrightarrowcircle \twoheaduparrowcircle
\updownharpoonrightleft \updownharpoonleftright \leftrightharpoonupup \DownLeftRightVector
\leftrightharpoonsup \leftrightharpoonsdown \rightleftharpoonsup \rightleftharpoonsdown
\equalrightarrow \similarrightarrow \leftarrowsimilar \rightarrowsimilar
\rightarrowapprox \ltlarr \leftarrowless \gtrarr
\subrarr \leftarrowsubset \suplarr \leftfishtail
\rightfishtail \upfishtail ⥿ \downfishtail \Vvert
\spot \typecolon \lBrace \rBrace
\lParen \Elroang \limg \lbrackubar
\rbrackubar \lbrackultick \rbracklrtick \lbracklltick
\rbrackurtick \langledot \rangledot \lparenless
\rparengtr \Lparengtr \Rparenless \lblkbrbrak
\rblkbrbrak \fourvdots \vzigzag \measuredangleleft
\rightanglemdot \angles \angdnr \gtlpar
\sphericalangleup \turnangle \revangle \angleubar
\revangleubar \wideangledown \wideangleup \measanglerutone
\measanglelutonw \measanglerdtose \measangleldtosw \measangleurtone
\measangleultonw \measangledrtose \measangledltosw \revemptyset
\emptysetobar \emptysetocirc \emptysetoarr \emptysetoarrl
\circlehbar \circledvert \circledparallel \circledbslash
\operp \obot \olcross \odotslashdot
\uparrowoncircle \circledwhitebullet ⦿ \circledbullet \circledless
\circledgtr \cirscir \cirE \boxbslash
\boxast \boxcircle \boxbox \boxonbox
\triangleodot \triangleubar \triangles \triangleserifs
\rtriltri \lfbowtie \rfbowtie \fbowtie
\lftimes \rftimes \hourglass \blackhourglass
\lvzigzag \rvzigzag \Lvzigzag \Rvzigzag
\iinfin \tieinfty \nvinfty \laplac
\lrtriangleeq \shuffle \eparsl \smeparsl
\eqvparsl \gleichstark \thermod \downtriangleleftblack
\downtrianglerightblack \blackdiamonddownarrow \blacklozenge \circledownarrow
\blackcircledownarrow \errbarsquare \errbarblacksquare \errbardiamond
\errbarblackdiamond \errbarcircle \errbarblackcircle \RuleDelayed
\dsol \rsolbar \xsol \doubleplus
\tripleplus \lcurvyangle \rcurvyangle \tplus
⧿ \tminus \bigcupdot \Elxuplus \bigsqcap
\conjquant \disjquant \modtwosum \sumint
\iiiint \intbar \intBar \cirfnint
\awint \rppolint \scpolint \npolint
\pointint \intlarhk \intx \intcap
\intcup \upint \lowint \Join
\bigtriangleleft \zcmp \zpipe \zproject
\ringplus \plushat \simplus \plusdot
\plussim \plussubtwo \plustrif \commaminus
\minusdot \minusfdots \minusrdots \opluslhrim
\oplusrhrim \vectimes \dottimes \timesbar
\btimes \smashtimes \otimeslhrim \otimesrhrim
\otimeshat \Otimes \odiv \triangleplus
\triangleminus \triangletimes \intprod \intprodr
\fcmp \capdot \uminus \barcup
\barcap \capwedge \cupvee \cupovercap
\capovercup \cupbarcap \capbarcup \twocups
\twocaps \closedvarcup \closedvarcap \Sqcap
\Sqcup \closedvarcupsmashprod \wedgeodot \veeodot
\Wedge \Vee \wedgeonwedge \bigslopedvee
\bigslopedwedge \veeonwedge \wedgemidvert \veemidvert
\midbarwedge \midbarvee \wedgebar \wedgedoublebar
\varveebar \doublebarvee \veedoublebar \dsub
\rsub \eqdot \dotequiv \equivVert
\equivVvert \dotsim \simrdots \simminussim
\congdot \hatapprox \approxeqq \eqqplus
\pluseqq \eqqsim \Coloneqq \ddotseq
\equivDD \ltcir \gtcir \ltquest
\gtquest \leqslant \geqslant ⩿ \lesdot
\gesdot \lesdoto \gesdoto \lesdotor
\gesdotol \lessapprox \gtrapprox \lneq
\gneq \lnapprox \gnapprox \lesseqqgtr
\gtreqqless \lsime \gsime \lsimg
\gsiml \lgE \glE \lesges
\gesles \eqslantless \eqslantgtr \elsdot
\egsdot \eqqless \eqqgtr \eqqslantless
\eqqslantgtr \simless \simgtr \simlE
\simgE \partialmeetcontraction \glj \gla
\lescc \gescc \smt \lat
\smte \late \bumpeqq \precneq
\succneq \preceqq \succeqq \precneqq
\succneqq \precapprox \succapprox \precnapprox
\succnapprox \subsetdot \supsetdot ⪿ \subsetplus
\supsetplus \submult \supmult \subedot
\supedot \subseteqq \supseteqq \subsim
\supsim \subsetapprox \supsetapprox \subsetneqq
\supsetneqq \lsqhook \rsqhook \csub
\csup \csube \csupe \subsup
\supsub \subsub \supsup \suphsub
\supdsub \forkv \topfork \mlcp
⫝̸ \forks \forksnot \shortlefttack \shortdowntack
\shortuptack \perps \vDdash \dashV
\Dashv \DashV \varVdash \Barv
\vBar \vBarv \Vbar \Not
\bNot \revnmid \cirmid \midcir
\topcir \nhpar \parsim \interleave
\nhVvert \threedotcolon \lllnest \gggnest
\leqqslant \geqqslant \trslash \biginterleave
\talloblong ⫿ \bigtalloblong \squaretopblack \squarebotblack
\squareurblack \squarellblack \diamondleftblack \diamondrightblack
\diamondtopblack \diamondbotblack \dottedsquare \lgblksquare
\lgwhtsquare \vysmblksquare \vysmwhtsquare \pentagonblack
\pentagon \varhexagon \varhexagonblack \hexagonblack
\lgblkcircle \mdblkdiamond \mdwhtdiamond \mdblklozenge
\mdwhtlozenge \smblkdiamond \smblklozenge \smwhtlozenge
\blkhorzoval \whthorzoval \blkvertoval \whtvertoval
\circleonleftarrow \leftthreearrows \leftarrowonoplus \longleftsquigarrow
\nvtwoheadleftarrow \nVtwoheadleftarrow \twoheadmapsfrom \twoheadleftdbkarrow
\leftdotarrow \nvleftarrowtail \nVleftarrowtail \twoheadleftarrowtail
\nvtwoheadleftarrowtail \nVtwoheadleftarrowtail \leftarrowx ⬿ \leftcurvedarrow
\equalleftarrow \bsimilarleftarrow \leftarrowbackapprox \rightarrowgtr
\rightarrowsupset \LLeftarrow \RRightarrow \bsimilarrightarrow
\rightarrowbackapprox \similarleftarrow \leftarrowapprox \leftarrowbsimilar
\rightarrowbsimilar \medwhitestar \medblackstar \smwhitestar
\rightpentagonblack \rightpentagon \postalmark \hzigzag

amssymb

character text math character text math character text math character text math
ð \eth \leqslant ⩽̸ \nleqslant \geqslant
⩾̸ \ngeqslant

arevmath

character text math character text math character text math character text math
ð \eth

MinionPro

character text math character text math character text math character text math
ϐ \varbeta ϰ \varkappa

mathrsfs

character text math character text math character text math character text math
\mathscr{g} \mathscr{H} \mathscr{I} \mathscr{L}
\mathscr{R} \mathscr{B} \mathscr{e} \mathscr{E}
\mathscr{F} \mathscr{M} \mathscr{o} 𝒜 \mathscr{A}
𝒞 \mathscr{C} 𝒟 \mathscr{D} 𝒢 \mathscr{G} 𝒥 \mathscr{J}
𝒦 \mathscr{K} 𝒩 \mathscr{N} 𝒪 \mathscr{O} 𝒫 \mathscr{P}
𝒬 \mathscr{Q} 𝒮 \mathscr{S} 𝒯 \mathscr{T} 𝒰 \mathscr{U}
𝒱 \mathscr{V} 𝒲 \mathscr{W} 𝒳 \mathscr{X} 𝒴 \mathscr{Y}
𝒵 \mathscr{Z} 𝒶 \mathscr{a} 𝒷 \mathscr{b} 𝒸 \mathscr{c}
𝒹 \mathscr{d} 𝒻 \mathscr{f} 𝒽 \mathscr{h} 𝒾 \mathscr{i}
𝒿 \mathscr{j} 𝓀 \mathscr{k} 𝓁 \mathscr{l} 𝓂 \mathscr{m}
𝓃 \mathscr{n} 𝓅 \mathscr{p} 𝓆 \mathscr{q} 𝓇 \mathscr{r}
𝓈 \mathscr{s} 𝓉 \mathscr{t} 𝓊 \mathscr{u} 𝓋 \mathscr{v}
𝓌 \mathscr{w} 𝓍 \mathscr{x} 𝓎 \mathscr{y} 𝓏 \mathscr{z}

MnSymbol

character text math character text math character text math character text math
\lcirclerightint \rcirclerightint

mathabx

character text math character text math character text math character text math
\dotdiv

xecjk

character text math character text math character text math character text math
\texteqsim א \hebalef ע \hebayin ב \hebbet
ד \hebdalet ך \hebfinalkaf ם \hebfinalmem ן \hebfinalnun
ף \hebfinalpe ץ \hebfinaltsadi ג \hebgimel ה \hebhe
ח \hebhet כ \hebkaf ל \heblamed מ \hebmem
נ \hebnun פ \hebpe ק \hebqof ר \hebresh
ס \hebsamekh ש \hebshin ת \hebtav ט \hebtet
צ \hebtsadi ו \hebvav י \hebyod ז \hebzayin
ĸ \textkra

textcomp

character text math character text math character text math character text math
¢ \textcent ¤ \textcurrency ¥ \textyen ฿ \textbaht
\textcolonmonetary \textlira \textnaira \textpeseta
\textwon \textdong \textpeso ¦ \textbrokenbar
© \textcopyright ª \textordfeminine ° \textdegree \textparagraph
º \textordmasculine ð \textdh ˙ \textperiodcentered \textbullet
\textperthousand \textpertenthousand \textrecipe \texttrademark
\textuparrow \textrightarrow

inputenx

character text math character text math character text math character text math
Ħ \textmalteseH ɸ \textphi \textapproxequal

tipa

character text math character text math character text math character text math
ħ \textcrh ƕ \texthvlig ƞ \textipa{\textnrleg} ǂ \textdoublebarpipe
ɐ \textipa{\textturna} ɒ textipa{\textopeno} ɔ \textipa{O} ɖ \textrtaild
ə \textschwa ɣ \textipa{G} ɤ \textrevscripta ɸ \textphi
ʞ \textturnk ˥ \tone{55} ˦ \tone{44} ˧ \tone{33}
˨ \tone{22} ˩ \tone{11} ̀̄ \textgravemacron ̀̇ \textgravedot
́̄ \textacutemacron ́̌ \textacutewedge ̂̇ \textcircumdot ̃̇ \texttildedot
̄̀ \textgravemacron ̆̄ \textbrevemacron ̇́ \textdotacute ̇̆ \textdotbreve
̊̄ \textringmacron ̍ \textvbaraccent ̎ \textdoublevbaraccent ̐ \textdotbreve
̘ \textadvancing ̙ \textretracting ̚ \textcorner ̜ \textsublhalfring
̝ \textraising ̞ \textlowering ̟ \textsubplus ̤ \textsubumlaut
̥ \textsubring ̩ \textsyllabic ̪ \textsubbridge ̬ \textsubwedge
̯ \textsubarch ̰ \textsubtilde ̱ \textsubbar ̴ \textsuperimposetilde
̹ \textsubrhalfring ̺ \textinvsubbridge ̻ \textsubsquare ̼ \textseagull
̽ \textovercross \textsubscript{\textschwa}

ipa

character text math character text math character text math character text math
ɯ \textturnm

mathscinet

character text math character text math character text math character text math
ʿ \lasp

textalpha

character text math character text math character text math character text math
α \textalpha

graphics

character text math character text math character text math character text math
\reflectbox{\carriagereturn}

pmboxdraw

character text math character text math character text math character text math
\textSFx \pmboxdrawuni{2501} \textSFxi \pmboxdrawuni{2503}
\textSFi \pmboxdrawuni{250D} \pmboxdrawuni{250E} \pmboxdrawuni{250F}
\textSFiii \pmboxdrawuni{2511} \pmboxdrawuni{2512} \pmboxdrawuni{2513}
\textSFii \pmboxdrawuni{2515} \pmboxdrawuni{2516} \pmboxdrawuni{2517}
\textSFiv \pmboxdrawuni{2519} \pmboxdrawuni{251A} \pmboxdrawuni{251B}
\textSFviii \pmboxdrawuni{251D} \pmboxdrawuni{251E} \pmboxdrawuni{251F}
\pmboxdrawuni{2520} \pmboxdrawuni{2521} \pmboxdrawuni{2522} \pmboxdrawuni{2523}
\textSFix \pmboxdrawuni{2525} \pmboxdrawuni{2526} \pmboxdrawuni{2527}
\pmboxdrawuni{2528} \pmboxdrawuni{2529} \pmboxdrawuni{252A} \pmboxdrawuni{252B}
\textSFvi \pmboxdrawuni{252D} \pmboxdrawuni{252E} \pmboxdrawuni{252F}
\pmboxdrawuni{2530} \pmboxdrawuni{2531} \pmboxdrawuni{2532} \pmboxdrawuni{2533}
\textSFvii \pmboxdrawuni{2535} \pmboxdrawuni{2536} \pmboxdrawuni{2537}
\pmboxdrawuni{2538} \pmboxdrawuni{2539} \pmboxdrawuni{253A} \pmboxdrawuni{253B}
\textSFv \pmboxdrawuni{253D} \pmboxdrawuni{253E} \pmboxdrawuni{253F}
\pmboxdrawuni{2540} \pmboxdrawuni{2541} \pmboxdrawuni{2542} \pmboxdrawuni{2543}
\pmboxdrawuni{2544} \pmboxdrawuni{2545} \pmboxdrawuni{2546} \pmboxdrawuni{2547}
\pmboxdrawuni{2548} \pmboxdrawuni{2549} \pmboxdrawuni{254A} \pmboxdrawuni{254B}
\textSFxliii \textSFxxiv \textSFli \textSFlii
\textSFxxxix \textSFxxii \textSFxxi \textSFxxv
\textSFl \textSFxlix \textSFxxxviii \textSFxxviii
\textSFxxvii \textSFxxvi \textSFxxxvi \textSFxxxvii
\textSFxlii \textSFxix \textSFxx \textSFxxiii
\textSFxlvii \textSFxlviii \textSFxli \textSFxlv
\textSFxlvi \textSFxl \textSFliv \textSFliii
\textSFxliv \pmboxdrawuni{2574} \pmboxdrawuni{2575} \pmboxdrawuni{2576}
\pmboxdrawuni{2577} \pmboxdrawuni{2578} \pmboxdrawuni{2579} \pmboxdrawuni{257A}
\pmboxdrawuni{257B} \pmboxdrawuni{257C} \pmboxdrawuni{257D} \pmboxdrawuni{257E}
\pmboxdrawuni{257F} \textupblock \pmboxdrawuni{2581} \pmboxdrawuni{2582}
\pmboxdrawuni{2583} \textdnblock \pmboxdrawuni{2585} \pmboxdrawuni{2586}
\pmboxdrawuni{2587} \textblock \pmboxdrawuni{2589} \pmboxdrawuni{258A}
\pmboxdrawuni{258B} \textlfblock \pmboxdrawuni{258D} \pmboxdrawuni{258E}
\pmboxdrawuni{258F} \textrtblock \textltshade \textshade
\textdkshade \pmboxdrawuni{2594} \pmboxdrawuni{2595} \pmboxdrawuni{2596}
\pmboxdrawuni{2597} \pmboxdrawuni{2598} \pmboxdrawuni{2599} \pmboxdrawuni{259A}
\pmboxdrawuni{259B} \pmboxdrawuni{259C} \pmboxdrawuni{259D} \pmboxdrawuni{259E}
\pmboxdrawuni{259F}

Advanced

You are a hardcore LaTeX user

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:

curl http://localhost:23119/better-bibtex/json-rpc -X POST -H "Content-Type: application/json" -H "Accept: application/json" --data-binary '{"jsonrpc": "2.0", "method": "collection.scanAUX", "params": ["/My Library/thesis/article1", "/Users/phantom/Downloads/output.aux"] }'

The available methods are:

autoexport.add(collection, translator, path, displayOptions, replace)

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.
  • 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

returns: Collection ID of the target collection

collection.scanAUX(collection, aux)

Scan an AUX file for citekeys and populate a Zotero collection from them. The target collection will be cleared if it exists.

  • 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

item.attachments(citekey)

List attachments for an item with the given citekey

  • citekey: The citekey to search for

item.bibliography(citekeys, format)

Generate a bibliography for the given citekeys

  • citekeys: An array of citekeys
  • format: A specification of how the bibliography should be formatted

returns: A formatted bibliography

item.citationkey(item_keys)

Fetch citationkeys given item keys

  • item_keys: A list of [libraryID]:[itemKey] strings. If [libraryID] is omitted, assume ‘My Library’

item.export(citekeys, translator, libraryID)

Generate an export for a list of citekeys

  • citekeys: Array of citekeys
  • translator: BBT translator name or GUID
  • libraryID: ID of library to select the items from. When omitted, assume ‘My Library’

item.notes(citekeys)

Fetch the notes for a range of citekeys

  • citekeys: An array of citekeys

item.search(searchterms)

Quick-search for items in Zotero.

  • searchterms: Terms as typed into the search box in Zotero

user.groups()

List the libraries (also known as groups) the user has in Zotero

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.

Citation Keys

Generating citekeys for your items

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]”.

Find duplicate keys through integration with Report Customizer

The plugin will generate BibTeX comments to show whether a key conflicts and with which entry. BBT integrates with Zotero: Report Customizer to display the BibTeX key plus any conflicts between them in the zotero report.

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:

  1. “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.
  2. “field access”, direct text from the zotero item fields; these again are largely case insensitive, but they must start with an uppercase letter
  3. “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.
  4. bare strings (text quoted in single or double quotes)

There are 3 ways you can build subformulae:

  1. composition: (auth + title)
  2. alternates: (auth || title) (use the first thing that returns any text, so auth if that returns text, otherwise title).
  3. 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.

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.len('>',1) + year | auth + year

which checks whether the title output is longer than 1 character.

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

  1. last name of first author without spaces, in lowercase because of the .lower filter
  2. The first n (default: 3) words of the title, apply capitalization to first m (default: 0) of those.
  3. year of publication if any,
  4. 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 that the formula syntax has changed from a bracketed format 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. The old syntax still works but will be translated to the new format automatically.

Below you will find a full list of functions and filters you can use, in the new format only, sorry. You can still use these in the old syntax, but they support only positional parameters, where I would recommend generally to use the new syntax with named parameters.

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.

Functions

auth
parameters:
parametertypedescriptiondefault
nnumber

the number of characters to take from the name, 0 = all

0
mnumber

select the mth author

1
creatorauthor / editor / translator / collaborator / *

kind of creator to select, * selects author first, and if not present, editor, translator or collaborator, in that order.

"*"
initialsboolean

add author initials

false

The first n (default: all) characters of the mth (default: first) author's last name.

authAuthEa
parameters:
parametertypedescriptiondefault
creatorauthor / editor / translator / collaborator / *

kind of creator to select, * selects author first, and if not present, editor, translator or collaborator, in that order.

"*"
initialsboolean

add author initials

false
sepstring

use this character between authors

"."

The last name of the first two authors, and ".ea" if there are more than two.

authEtAl
parameters:
parametertypedescriptiondefault
creatorauthor / editor / translator / collaborator / *

kind of creator to select, * selects author first, and if not present, editor, translator or collaborator, in that order.

"*"
initialsboolean

add author initials

false
sepstring

use this character between authors

" "

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 auth.etal. The difference is that the authors are not separated by "." and in case of more than 2 authors "EtAl" instead of ".etal" is appended.

authEtal2
parameters:
parametertypedescriptiondefault
creatorauthor / editor / translator / collaborator / *

kind of creator to select, * selects author first, and if not present, editor, translator or collaborator, in that order.

"*"
initialsboolean

add author initials

false
sepstring

use this character between authors

"."

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.

authForeIni
parameters:
parametertypedescriptiondefault
creatorauthor / editor / translator / collaborator / *

kind of creator to select, * selects author first, and if not present, editor, translator or collaborator, in that order.

"*"

The given-name initial of the first author.

authIni
parameters:
parametertypedescriptiondefault
nnumber

the number of characters to take from the name, 0 = all

0
creatorauthor / editor / translator / collaborator / *

kind of creator to select, * selects author first, and if not present, editor, translator or collaborator, in that order.

"*"
initialsboolean

add author initials

false
sepstring

use this character between authors

"."

The beginning of each author's last name, using no more than n characters (0 = all).

authorIni
parameters:
parametertypedescriptiondefault
creatorauthor / editor / translator / collaborator / *

kind of creator to select, * selects author first, and if not present, editor, translator or collaborator, in that order.

"*"
initialsboolean

add author initials

false
sepstring

use this character between authors

"."

The first 5 characters of the first author's last name, and the last name initials of the remaining authors.

authorLast
parameters:
parametertypedescriptiondefault
creatorauthor / editor / translator / collaborator / *

kind of creator to select, * selects author first, and if not present, editor, translator or collaborator, in that order.

"*"
initialsboolean

add author initials

false

The last name of the last author

authorLastForeIni
parameters:
parametertypedescriptiondefault
creatorauthor / editor / translator / collaborator / *

kind of creator to select, * selects author first, and if not present, editor, translator or collaborator, in that order.

"*"

The given-name initial of the last author.

authorsAlpha
parameters:
parametertypedescriptiondefault
creatorauthor / editor / translator / collaborator / *

kind of creator to select, * selects author first, and if not present, editor, translator or collaborator, in that order.

"*"
initialsboolean

add author initials

false
sepstring

use this character between authors

" "

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.

authorsn
parameters:
parametertypedescriptiondefault
nnumber

the number of characters to take from the name, 0 = all

0
creatorauthor / editor / translator / collaborator / *

kind of creator to select, * selects author first, and if not present, editor, translator or collaborator, in that order.

"*"
initialsboolean

add author initials

false
sepstring

use this character between authors

" "

The last names of the first n (default: all) authors.

authshort
parameters:
parametertypedescriptiondefault
creatorauthor / editor / translator / collaborator / *

kind of creator to select, * selects author first, and if not present, editor, translator or collaborator, in that order.

"*"
initialsboolean

add author initials

false
sepstring

use this character between authors

"."

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.

creators
parameters:
parametertypedescriptiondefault
nnumber / [number, number]

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

0
typeartist / attorneyAgent / author / bookAuthor / cartographer / castMember / commenter / composer / contributor / cosponsor / counsel / director / editor / guest / interviewee / interviewer / inventor / performer / podcaster / presenter / producer / programmer / recipient / reviewedAuthor / scriptwriter / seriesEditor / sponsor / testimonyBy / translator / wordsBy / * / artist / attorneyAgent / author / bookAuthor / cartographer / castMember / commenter / composer / contributor / cosponsor / counsel / director / editor / guest / interviewee / interviewer / inventor / performer / podcaster / presenter / producer / programmer / recipient / reviewedAuthor / scriptwriter / seriesEditor / sponsor / testimonyBy / translator / wordsBy / * / artist / attorneyAgent / author / bookAuthor / cartographer / castMember / commenter / composer / contributor / cosponsor / counsel / director / editor / guest / interviewee / interviewer / inventor / performer / podcaster / presenter / producer / programmer / recipient / reviewedAuthor / scriptwriter / seriesEditor / sponsor / testimonyBy / translator / wordsBy

select only creators of given type(s). Default: all

[["primary","editor","translator","*"]]
namea creator sprintf template with one or more of the variables f (family name) / g (given name) / i (first initial) / I (all initials)

sprintf-js template. Available named parameters are: f (family name), g (given name), i (initials)

"%(f)s"
etalstring

use this term to replace authors after n authors have been named

""
sepstring

use this character between authors

" "
minnumber

skip to the next pattern if there are less than min creators, 0 = ignore

0
maxnumber

skip to the next pattern if there are more than max creators, 0 = ignore

0

Author/editor information.

creatortypes
parameters:
parametertypedescriptiondefault
matchRegExp

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).

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.

date
parameters:
parametertypedescriptiondefault
formatstring

sprintf-style format template

"%Y-%m-%d"

The date of the publication

extra
parameters:
parametertypedescriptiondefault
variablestring

extra-field line identifier

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.

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+.)

infix
parameters:
parametertypedescriptiondefault
formatstring

sprintf-style format template

"%(a)s"
startnumber

start value for postfix

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.

inspireHep

Fetches the key from inspire-hep based on DOI or arXiv ID

item
parameters:
parametertypedescriptiondefault
idid / key

'id': return itemID; 'key': return the item key

"key"

returns the internal item ID/key

journal
parameters:
parametertypedescriptiondefault
abbrevabbrev / abbrev+auto / auto / full / off

abbreviation mode

"abbrev+auto"

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).

keyword
parameters:
parametertypedescriptiondefault
nnumber

position of tag to get

Tag number n. Mostly for legacy compatibility

language
parameters:
parametertypedescriptiondefault
nameame / american / american english / americanenglish / ar / ar-ar / ar-dz / ar-eg / ar-iq / ar-jo / ar-lb / ar-ma / ar-ps / ar-sa / ar-sy / ar-tn / ara / arabic / arabic-algeria / arabic-dz / arabic-eg / arabic-egypt / arabic-iq / arabic-iraq / arabic-jo / arabic-jordan / arabic-lb / arabic-lebanon / arabic-ma / arabic-morocco / arabic-palestinianterritories / arabic-ps / arabic-sa / arabic-saudiarabia / arabic-sy / arabic-syria / arabic-tn / arabic-tunisia / australian / australian english / australianenglish / austrian / austrian german / austrian-traditional / austriangerman / austriangerman-traditional / bri / british / british english / britishenglish / canadian / canadian english / canadianenglish / chinese / chinese-hans / chinese-hans-hk / chinese-hans-mo / chinese-hans-sg / chinese-hant / chinese-hant-hk / chinese-hant-mo / chinese-simplified / chinese-simplified-hongkongsarchina / chinese-simplified-macausarchina / chinese-simplified-singapore / chinese-traditional / chinese-traditional-hongkongsarchina / chinese-traditional-macausarchina / de / de-1901 / de-1996 / de-at / de-at-1901 / de-at-1996 / de-ch / de-ch-1901 / de-ch-1996 / de-de / deutsch / en / en-au / en-ca / en-en / en-gb / en-nz / en-us / eng / english / english-au / english-australia / english-ca / english-canada / english-gb / english-newzealand / english-nz / english-unitedkingdom / english-unitedstates / english-us / ger / german / german-at / german-at-traditional / german-austria / german-austria-traditional / german-ch / german-ch-traditional / german-switzerland / german-switzerland-traditional / german-traditional / ja / ja-ja / jap / japanese / nau / naustrian / newzealand / nge / ngerman / nsw / nswissgerman / schweizer hochdeutsch / simplified chinese / swiss high german / swisshighgerman / swisshighgerman-traditional / traditional chinese / tw / ukenglish / usenglish / zh / zh-hans / zh-hans-hk / zh-hans-mo / zh-hans-sg / zh-hant / zh-hant-hk / zh-hant-mo / zh-tw / zh-zh / österreichisches deutsch / العربية / 中文 / 中文-中文 / 日本語 / 简体中文 / 繁體中文

one or more language codes

Tests whether the item has the given language set, and skips to the next pattern if not

lastpage

The number of the last page of the publication (See the remark on firstpage)

library

returns the name of the shared group library, or nothing if the item is in your personal library

month

the month of the publication

origdate

the original date of the publication

origyear

the original year of the publication

postfix
parameters:
parametertypedescriptiondefault
formata postfix sprintf template with one or more of the variables a (alpha postfix) / A (alpha postfix uppercase) / n (numeric postfix)

sprintf-style format template

"%(a)s"
startnumber

start value for postfix

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.

shorttitle
parameters:
parametertypedescriptiondefault
nnumber

number of words to select

3
mnumber

number of words to capitalize. 0 means no words will be capitalized. Mind that existing capitals are not removed. If you enable capitalization, you also get transliteration; for CJK, capitalization is not meaningful, so if you want capitalization, BBT romanizes first.

0

The first n (default: 3) words of the title, apply capitalization to first m (default: 0) of those.

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

type
parameters:
parametertypedescriptiondefault
allowedartwork / audioRecording / bill / blogPost / book / bookSection / case / computerProgram / conferencePaper / dataset / dictionaryEntry / document / email / encyclopediaArticle / film / forumPost / hearing / instantMessage / interview / journalArticle / letter / magazineArticle / manuscript / map / newspaperArticle / patent / podcast / preprint / presentation / radioBroadcast / report / standard / statute / thesis / tvBroadcast / videoRecording / webpage / classic / gazette / legalCommentary / regulation / treaty

one or more item type names

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.

veryshorttitle
parameters:
parametertypedescriptiondefault
nnumber

number of words to select

1
mnumber

number of words to capitalize. 0 means no words will be capitalized. Mind that existing capitals are not removed.

0

The first n words of the title, apply capitalization to first m of those

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.

(type names marked JM are only available in Juris-M).

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

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
parameters:
parametertypedescriptiondefault
charsnumber

number of characters to return per word

1

Abbreviates the text. Only the first character and subsequent characters following white space will be included.

acronym
parameters:
parametertypedescriptiondefault
liststring

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.

"acronyms"
reloadboolean

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.

false
passthroughboolean

if no match is found, pass through input. This is mostly for backwards compatibility, and I would encourage use of (<input>.acronym || <input>) over <input>.acronym(passthrough=true). This option will be removed at some point in the future.

false

Does an acronym lookup for the text.

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
parameters:
parametertypedescriptiondefault
sepstring

replacement character

""

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).

default
parameters:
parametertypedescriptiondefault
textstring

literal text to return

Returns the given text if no output was generated

discard

discards the input

formatDate
parameters:
parametertypedescriptiondefault
formatstring

sprintf-style format template

"%Y-%m-%d"

formats date as by replacing y, m and d in the format

ideographs

Treat ideaographs as individual words

jieba
parameters:
parametertypedescriptiondefault
modecn / hant / tw

segmentation mode

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

len
parameters:
parametertypedescriptiondefault
relation!= / < / <= / = / > / >=

comparison operator

">"
lengthnumber

value to compare length with

0

If the length of the output does not match the given number, skip to the next pattern.

localTime

transforms date/time to local time. Mainly useful for dateAdded and dateModified as it requires an ISO-formatted input.

lower

Forces the text inserted by the field marker to be in lowercase. For example, auth.lower expands to the last name of the first author in lowercase.

match
parameters:
parametertypedescriptiondefault
matchRegExp / string

regex or string to match. String matches are case-insensitive

cleanboolean

transliterates the current output and removes unsafe characters during matching

false

If the output does not match the given string/regex, skip to the next pattern.

nopunct
parameters:
parametertypedescriptiondefault
dashstring

replace dashes with given character

"-"

Removes punctuation

nopunctordash

Removes punctuation and word-connecting dashes. alias for nopunct(dash='')

numeric

returns the value if it's an integer

pinyin

transliterates the citation key to pinyin

postfix
parameters:
parametertypedescriptiondefault
postfixstring

postfix string

postfixes with its parameter, so postfix('\_') will add an underscore to the end if, and only if, the value it is supposed to postfix isn't empty

prefix
parameters:
parametertypedescriptiondefault
prefixstring

prefix string

prefixes with its parameter, so .prefix('\_') will add an underscore to the front if, and only if, the value it is supposed to prefix isn't empty.

replace
parameters:
parametertypedescriptiondefault
findstring / RegExp

string or regex to match. String matches are case-insensitive

replacestring

literal text to replace the match with

replaces text, for the text to match you can pass either: - a string: .replace('.etal','&etal') which will match case-insensitive, so will replace .EtAl with &etal. - javascript regular expression: .replace(/[.]etal/ig, '&etal')

select
parameters:
parametertypedescriptiondefault
startnumber

first word to select (1-based)

1
nnumber

number of words to select. Default is all.

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.

skipwords
parameters:
parametertypedescriptiondefault
nopunctboolean

remove punctuation from words

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.

substring
parameters:
parametertypedescriptiondefault
startnumber

starting character (1-based)

1
nnumber

number of characters to select (default: remainder from start)

substring(start,n) selects n (default: all) characters starting at start

transliterate
parameters:
parametertypedescriptiondefault
modear / arabic / chinese / de / german / ja / japanese / minimal / mn / mongolian / ru / russian / tw / uk / ukranian / zh / zh-hant

specialized translateration modes for german, japanese or chinese.

transliterates the citation key. If you don't specify a mode, the mode is derived from the item language field

upper

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.

Subsections of Citation Keys

Cite as you Write

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)
  let format = &filetype =~ '.*tex' ? 'citep' : 'pandoc'
  let api_call = 'http://127.0.0.1:23119/better-bibtex/cayw?format='.format.'&brackets=1'
  let ref = system('curl -s '.shellescape(api_call))
  return ref
endfunction

noremap <leader>z "=ZoteroCite()<CR>p
inoremap <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:

def g:ZoteroCite(): string
    # Pick a citation format based on the filetype (feel free to customize)
    var format: string
    if &filetype =~ '.*tex'
      format = 'cite'
    else
      format = 'pandoc'
    endif

    # Make the BetterBibTeX API call and return the result.
    var api_call = 'http://127.0.0.1:23119/better-bibtex/cayw?format=' .. format .. '&brackets=1'
    var citation = system('curl -s ' .. shellescape(api_call))
    return citation
enddef

inoremap <C-x><C-z> <C-r>=g:ZoteroCite()<cr>

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

Linux

  • Emma Reisz has gracefully written instructions and scripts for setting up CAYW on Linux.
  • 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
  • asciidoctor-bibtex
  • typst Generates typst citation commands
  • jupyter
  • scannable-cite for the ODF scanner
  • 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 \parencite and 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

  1. For Juris-M, the port number 23119 must be replaced with 24119↩︎

Migrating from Word/Libreoffice

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:

pandoc -f docx+citations -t markdown -i Aristotle.docx -o Aristotle.md

should do the trick!

AUX Scanner

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.

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.

Subsections of Support

Frequently Asked Questions

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}}}.
  • casing behavior over the whole entry field depends on whether there’s a slash-command at the first position of the title?
  • 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() }) }

Performance

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:

  • git clone https://github.com/retorquere/zotero-better-bibtex.git
  • cd zotero-better-bibtex
  • pip3 install -r requirements.txt

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.

My github stats My github stats

Metrics Metrics