-
-
Notifications
You must be signed in to change notification settings - Fork 287
Scripting
You got customized. If you go into the Advanced tab of the Better BibTeX preferences you will find a text box (empty by default) where you can edit a javascript snippet which will be executed for each reference generated in the Bib(La)TeX exporter. In this code, you have access to the reference just before it will be written out and cached. There is an API to do this, and it's fairly stable, but usually you can just open a new issue and ask me to write it, and I'll add it here (it's how the examples got here). Postscripts are available in 4 of the translators:
- BetterBibLaTeX
- BetterBibTeX
- BetterCSLJSON
- BetterCSLYAML
You can (and totally should) check in which translator your postscript is running, which you can do by testing for
Translator.<id>
where <id>
is one of these four names. If you don't, you'll probably be OK, as in the
BetterBib(La)TeX
context you will typically access this
, which will be null
in the BetterCSL(JSON|YAML)
context,
and in the BetterCSL(JSON|YAML)
context, you will typically access csl
or item
, which will be null
in the
BetterBib(La)TeX
context, which will cause an error to be raised and processing to be stopped. As postscript failures
are only logged but are not fatal, this should mean you'd typically be OK having no tests. This is great because you may
have postscripts that pre-date CSL support. But please fix your postscripts.
The postscript should be a javascript
snippet. You can access the data with following objects or functions.
In BetterBibLaTeX
and BetterBibTeX
,
-
this
is the BibTeX reference you are building, and the reference has a number of fields. -
this.fields
-
this.item
is the Zotero item that's the source of the reference.e.g. access the date in zotero item
this.item.date
. -
this.has
is a dictionary of fields for output.e.g. access the year in output
this.has.year
-
this.add
is the function to add or modify keys inthis.has
. It will check check for unintentional duplicates (unless you specify explicitly withreplace: true
).e.g. change the value of year in output
this.add({name: 'year', replace: true, value: your_year_value})
In BetterCSLJSON
and BetterCSLYAML
:
-
csl
is the CSL object being built. Any changes made to this object will directly change the CSL object being output. -
item
is the Zotero reference it's being built from.
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 && this.item.itemType === 'webpage') {
if (this.item.accessDate) {
this.add({ name: 'note', value: "(accessed " + this.item.accessDate + ")" });
}
if (this.item.url) {
this.add({ name: 'howpublished', bibtex: "{\\url{" + this.enc_verbatim({value: this.item.url}) + "}}" });
}
}
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.BetterBibTeX || Translator.BetterBibLaTeX) {
this.add({ name: 'keywords', replace: true, value: this.item.tags, sep: ', ' });
}
as the default encoder knows what to do with arrays, if you give it a separator.
if ((Translator.BetterBibTeX || Translator.BetterBibLaTeX) && this.item.DOI) {
var doi = this.item.DOI;
if (doi.indexOf('doi:') != 0) { doi = 'doi:' + doi; }
this.add({ name: 'note', duplicate: true, value: '[' + doi + ']' });
}
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.BetterBibTeX || Translator.BetterBibLaTeX) && this.item.arXiv.id) {
this.add({ name: 'pages', value: this.item.arXiv.id });
if (!this.has.journaltitle) { this.add({ name: 'journaltitle', bibtex: '{}' }); }
}
Specify the ordering of the listing of fields in an exported Biblatex/Bibtex entry. Your postscript:
if (Translator.BetterBibTeX || Translator.BetterBibLaTeX) {
// the bib(la)tex fields are ordered according to this array.
// If a field is not in this list, it will show up at the end in random order.
// https://github.com/retorquere/zotero-better-bibtex/issues/512
var order = ['author', 'date', 'origdate', 'shorthand', 'title'];
this.fields.sort(function(a, b) {
var oa = order.indexOf(a.name);
var ob = order.indexOf(b.name);
if (oa < 0) { return 1; } // a is not in order, so put it at the end
if (ob < 0) { return -1; } // b is not in order, so put it at the end
return oa - ob;
});
}
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},
origdate = {1882},
shorthand = {GS},
title = {The {{Gay Science}}: {{With}} a {{Prelude}} in {{Rhymes}} and an {{Appendix}} of {{Songs}}},
keywords = {Philosophy / General,Philosophy / History Surveys / Modern},
translator = {Kaufmann, Walter},
publisher = {{Random House}},
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.