From 89aaa10504ddc4bb2f0c03fd70f5cc455257d562 Mon Sep 17 00:00:00 2001 From: Abe Jellinek Date: Tue, 26 Apr 2022 01:11:29 -0700 Subject: [PATCH] Sort LC call numbers better, sort integers as integers (#2569) * Update utilities submodule after https://github.com/zotero/utilities/pull/8 * Extract and add tests --- chrome/content/zotero/itemTree.jsx | 20 +----------- chrome/content/zotero/xpcom/utilities | 2 +- test/tests/utilities_itemTest.js | 46 +++++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 20 deletions(-) diff --git a/chrome/content/zotero/itemTree.jsx b/chrome/content/zotero/itemTree.jsx index 3b8551ffa2..55da4a43cc 100644 --- a/chrome/content/zotero/itemTree.jsx +++ b/chrome/content/zotero/itemTree.jsx @@ -1354,25 +1354,7 @@ var ItemTree = class ItemTree extends LibraryTree { } if (sortField == 'callNumber') { - let deweyRe = /^(\d{3})(?:\.(\d+))?(?:\/([a-zA-Z]{3}))?$/; - let splitA = fieldA.toLowerCase().replace(/\s/g, '').match(deweyRe); - let splitB = fieldB.toLowerCase().replace(/\s/g, '').match(deweyRe); - if (splitA && splitB) { - // Looks like Dewey Decimal, so we'll compare by parts - let i; - for (i = 1; i < splitA.length && i < splitB.length; i++) { - if (splitA[i] < splitB[i]) { - return -1; - } - else if (splitA[i] > splitB[i]) { - return 1; - } - } - return (i < splitA.length) ? 1 : (i < splitB.length) ? -1 : 0; - } - else { - return (fieldA > fieldB) ? 1 : (fieldA < fieldB) ? -1 : 0; - } + return Zotero.Utilities.Item.compareCallNumbers(fieldA, fieldB); } return collation.compareString(1, fieldA, fieldB); diff --git a/chrome/content/zotero/xpcom/utilities b/chrome/content/zotero/xpcom/utilities index df2dda23b7..2d6e330e28 160000 --- a/chrome/content/zotero/xpcom/utilities +++ b/chrome/content/zotero/xpcom/utilities @@ -1 +1 @@ -Subproject commit df2dda23b7787215762d41fc654a8ab7fb99056a +Subproject commit 2d6e330e28f1c46482b93a37e8ceee53af74996c diff --git a/test/tests/utilities_itemTest.js b/test/tests/utilities_itemTest.js index 95eaf6c306..f5580f7c9d 100644 --- a/test/tests/utilities_itemTest.js +++ b/test/tests/utilities_itemTest.js @@ -279,4 +279,50 @@ describe("Zotero.Utilities.Item", function() { assert.equal(title, 'Annotations'); }); }); + + + describe("#compareCallNumbers()", function () { + function checkSort(numbersInOrder) { + let numbersResorted = [...numbersInOrder] + .sort(() => Math.random() - 0.5) // First shuffle + .sort(Zotero.Utilities.Item.compareCallNumbers); // Then re-sort + assert.deepEqual(numbersResorted, numbersInOrder); + } + + it("should correctly order integer call numbers", function () { + let numbersInOrder = [ + '1', + '2', + '12', + '20', + '21', + '100', + '101', + ]; + checkSort(numbersInOrder); + }); + + it("should correctly order Dewey Decimal call numbers", function () { + let numbersInOrder = [ + '641.5/Cor', + '641.5/wol', + '641.55541/Ray', + '641.594/Mun', + '641.5945/Foo', + '641.596/Mon', + '642.000/ABC', + ]; + checkSort(numbersInOrder); + }); + + it("should correctly order LC call numbers", function () { + let numbersInOrder = [ + 'PJ403.B64 C666', + 'PJ3930.S49 A53 2015', + 'PJ4519 .B9798 A58 1999', + 'PJ4519 .B99 A65 1976', + ]; + checkSort(numbersInOrder); + }); + }); });