From 1cbd7f71cf673c48fc46b0dae5e78199d76f44fe Mon Sep 17 00:00:00 2001 From: Aurimas Vinckevicius Date: Mon, 20 Jul 2015 20:09:33 -0500 Subject: [PATCH] Parse author names in itemToCSLJSON --- chrome/content/zotero/xpcom/style.js | 7 +- chrome/content/zotero/xpcom/utilities.js | 20 +++++- test/tests/utilities.js | 84 ++++++++++++++++++++++++ 3 files changed, 109 insertions(+), 2 deletions(-) diff --git a/chrome/content/zotero/xpcom/style.js b/chrome/content/zotero/xpcom/style.js index 8fb49bf6af..6c95ba63b8 100644 --- a/chrome/content/zotero/xpcom/style.js +++ b/chrome/content/zotero/xpcom/style.js @@ -664,12 +664,17 @@ Zotero.Style.prototype.getCiteProc = function(locale, automaticJournalAbbreviati } try { - return new Zotero.CiteProc.CSL.Engine( + var citeproc = new Zotero.CiteProc.CSL.Engine( new Zotero.Cite.System(automaticJournalAbbreviations), xml, locale, overrideLocale ); + + // Don't try to parse author names. We parse them in itemToCSLJSON + citeproc.opt.development_extensions.parse_names = false; + + return citeproc; } catch(e) { Zotero.logError(e); throw e; diff --git a/chrome/content/zotero/xpcom/utilities.js b/chrome/content/zotero/xpcom/utilities.js index bde5fa0c92..23ec452f1b 100644 --- a/chrome/content/zotero/xpcom/utilities.js +++ b/chrome/content/zotero/xpcom/utilities.js @@ -1555,7 +1555,25 @@ Zotero.Utilities = { var nameObj; if (creator.lastName || creator.firstName) { - nameObj = {'family': creator.lastName, 'given': creator.firstName}; + nameObj = { + family: creator.lastName || '', + given: creator.firstName || '' + }; + + // Parse name particles + // Replicate citeproc-js logic for what should be parsed so we don't + // break current behavior. + if (nameObj.family && nameObj.given) { + // Don't parse if last name is quoted + if (nameObj.family.length > 1 + && nameObj.family.charAt(0) == '"' + && nameObj.family.charAt(nameObj.family.length - 1) == '"' + ) { + nameObj.family = nameObj.family.substr(1, nameObj.family.length - 2); + } else { + Zotero.CiteProc.CSL.parseParticles(nameObj, true); + } + } } else if (creator.name) { nameObj = {'literal': creator.name}; } diff --git a/test/tests/utilities.js b/test/tests/utilities.js index 4e2d7179cd..299a3fbb59 100644 --- a/test/tests/utilities.js +++ b/test/tests/utilities.js @@ -272,5 +272,89 @@ describe("Zotero.Utilities", function() { assert.isUndefined(cslJSON.PMID, 'field labels are case-sensitive'); }); + it("should parse particles in creator names", function() { + let creators = [ + { + // No particles + firstName: 'John', + lastName: 'Smith', + creatorType: 'author', + expect: { + given: 'John', + family: 'Smith' + } + }, + { + // dropping and non-dropping + firstName: 'Jean de', + lastName: 'la Fontaine', + creatorType: 'author', + expect: { + given: 'Jean', + "dropping-particle": 'de', + "non-dropping-particle": 'la', + family: 'Fontaine' + } + }, + { + // only non-dropping + firstName: 'Vincent', + lastName: 'van Gogh', + creatorType: 'author', + expect: { + given: 'Vincent', + "non-dropping-particle": 'van', + family: 'Gogh' + } + }, + { + // only dropping + firstName: 'Alexander von', + lastName: 'Humboldt', + creatorType: 'author', + expect: { + given: 'Alexander', + "dropping-particle": 'von', + family: 'Humboldt' + } + }, + { + // institutional author + lastName: 'Jean de la Fontaine', + creatorType: 'author', + fieldMode: 1, + expect: { + literal: 'Jean de la Fontaine' + } + }, + { + // protected last name + firstName: 'Jean de', + lastName: '"la Fontaine"', + creatorType: 'author', + expect: { + given: 'Jean de', + family: 'la Fontaine' + } + } + ]; + + let data = populateDBWithSampleData({ + item: { + itemType: 'journalArticle', + creators: creators + } + }); + + let item = Zotero.Items.get(data.item.id); + let cslCreators = Zotero.Utilities.itemToCSLJSON(item).author; + + assert.deepEqual(cslCreators[0], creators[0].expect, 'simple name is not parsed'); + assert.deepEqual(cslCreators[1], creators[1].expect, 'name with dropping and non-dropping particles is parsed'); + assert.deepEqual(cslCreators[2], creators[2].expect, 'name with only non-dropping particle is parsed'); + assert.deepEqual(cslCreators[3], creators[3].expect, 'name with only dropping particle is parsed'); + assert.deepEqual(cslCreators[4], creators[4].expect, 'institutional author is not parsed'); + assert.deepEqual(cslCreators[5], creators[5].expect, 'protected last name prevents parsing'); + }); }); });