commit 1f320e1f5d5fd818e2c2d532f4789e38792a77a2
parent e1e5178869bd7beea777e577f4ee5bc670d7e793
Author: Dan Stillman <dstillman@zotero.org>
Date: Thu, 1 Mar 2018 16:58:54 -0500
Be more lenient about Extra field values than citeproc-js
Allow fields like "Original Date: 2018" and convert them to
"original-date: 2018" when sending to citeproc-js.
For reference:
http://citeproc-js.readthedocs.io/en/latest/csl-json/markup.html#cheater-syntax-for-odd-fields
Diffstat:
4 files changed, 130 insertions(+), 0 deletions(-)
diff --git a/chrome/content/zotero/xpcom/cite.js b/chrome/content/zotero/xpcom/cite.js
@@ -320,6 +320,104 @@ Zotero.Cite = {
} else {
return Zotero.Items.get(id);
}
+ },
+
+ extraToCSL: function (extra) {
+ return extra.replace(/^([A-Za-z \-]+)(:\s*.+)/gm, function (_, field, value) {
+ var originalField = field;
+ var field = field.toLowerCase().replace(/ /g, '-');
+ // Fields from https://aurimasv.github.io/z2csl/typeMap.xml
+ switch (field) {
+ // Standard fields
+ case 'abstract':
+ case 'accessed':
+ case 'annote':
+ case 'archive':
+ case 'archive-place':
+ case 'author':
+ case 'authority':
+ case 'call-number':
+ case 'chapter-number':
+ case 'citation-label':
+ case 'citation-number':
+ case 'collection-editor':
+ case 'collection-number':
+ case 'collection-title':
+ case 'composer':
+ case 'container':
+ case 'container-author':
+ case 'container-title':
+ case 'container-title-short':
+ case 'dimensions':
+ case 'director':
+ case 'edition':
+ case 'editor':
+ case 'editorial-director':
+ case 'event':
+ case 'event-date':
+ case 'event-place':
+ case 'first-reference-note-number':
+ case 'genre':
+ case 'illustrator':
+ case 'interviewer':
+ case 'issue':
+ case 'issued':
+ case 'jurisdiction':
+ case 'keyword':
+ case 'language':
+ case 'locator':
+ case 'medium':
+ case 'note':
+ case 'number':
+ case 'number-of-pages':
+ case 'number-of-volumes':
+ case 'original-author':
+ case 'original-date':
+ case 'original-publisher':
+ case 'original-publisher-place':
+ case 'original-title':
+ case 'page':
+ case 'page-first':
+ case 'publisher':
+ case 'publisher-place':
+ case 'recipient':
+ case 'references':
+ case 'reviewed-author':
+ case 'reviewed-title':
+ case 'scale':
+ case 'section':
+ case 'source':
+ case 'status':
+ case 'submitted':
+ case 'title':
+ case 'title-short':
+ case 'translator':
+ case 'version':
+ case 'volume':
+ case 'year-suffix':
+ break;
+
+ // Uppercase fields
+ case 'doi':
+ case 'isbn':
+ case 'issn':
+ case 'pmcid':
+ case 'pmid':
+ case 'url':
+ field = field.toUpperCase();
+ break;
+
+ // Weirdo
+ case 'archive-location':
+ field = 'archive_location';
+ break;
+
+ // Don't change other lines
+ default:
+ field = originalField;
+ }
+ return field + value;
+ });
}
};
diff --git a/chrome/content/zotero/xpcom/data/items.js b/chrome/content/zotero/xpcom/data/items.js
@@ -1445,6 +1445,7 @@ Zotero.Items = function() {
return title.replace(/^[\[\'\"](.*)[\'\"\]]?$/, '$1')
}
+
Zotero.DataObjects.call(this);
return this;
diff --git a/chrome/content/zotero/xpcom/utilities.js b/chrome/content/zotero/xpcom/utilities.js
@@ -1581,6 +1581,9 @@ Zotero.Utilities = {
var isbn = value.match(/^(?:97[89]-?)?(?:\d-?){9}[\dx](?!-)\b/i);
if (isbn) value = isbn[0];
}
+ else if (field == 'extra') {
+ value = Zotero.Cite.extraToCSL(value);
+ }
// Strip enclosing quotes
if(value.charAt(0) == '"' && value.indexOf('"', 1) == value.length - 1) {
@@ -1753,6 +1756,9 @@ Zotero.Utilities = {
}
if(Zotero.ItemFields.isValidForType(fieldID, itemTypeID)) {
+ // TODO: Convert restrictive Extra cheater syntax ('original-date: 2018')
+ // to nicer format we allow ('Original Date: 2018'), unless we've added
+ // those fields before we get to that
if(isZoteroItem) {
item.setField(fieldID, cslItem[variable]);
} else {
diff --git a/test/tests/citeTest.js b/test/tests/citeTest.js
@@ -0,0 +1,25 @@
+describe("Zotero.Cite", function () {
+ describe("#extraToCSL()", function () {
+ it("should convert Extra field values to the more restrictive citeproc-js cheater syntax", function () {
+ var str1 = 'Original Date: 2017\n' // uppercase/spaces converted to lowercase/hyphens
+ + 'Archive-Place: New York\n' // allow hyphen even with title case
+ + 'Container title: Title\n' // mixed case
+ + 'DOI: 10.0/abc\n' // certain fields are uppercase
+ + 'Archive Location: Foo\n' // requires an underscore
+ + 'Original Publisher Place: London, UK\n' // extra space OK
+ + '\n\n'
+ + "Ignore other strings: they're not fields\n"
+ + 'This is just some text.'
+ var str2 = 'original-date: 2017\n'
+ + 'archive-place: New York\n'
+ + 'container-title: Title\n'
+ + 'DOI: 10.0/abc\n'
+ + 'archive_location: Foo\n'
+ + 'original-publisher-place: London, UK\n'
+ + '\n\n'
+ + "Ignore other strings: they're not fields\n"
+ + 'This is just some text.';
+ assert.equal(Zotero.Cite.extraToCSL(str1), str2);
+ });
+ });
+});