From 4cc52ec928e636b3371d3be5a40f9435dd51f035 Mon Sep 17 00:00:00 2001 From: Tom Najdek Date: Wed, 11 Jun 2025 07:03:34 +0200 Subject: [PATCH] File renaming: Add pascal case. Fix unicode handling. (#4876) --- chrome/content/zotero/xpcom/attachments.js | 6 +++- test/tests/attachmentsTest.js | 40 +++++++++++++++++++++- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/chrome/content/zotero/xpcom/attachments.js b/chrome/content/zotero/xpcom/attachments.js index 7c8aba0c75..4aa95a64d4 100644 --- a/chrome/content/zotero/xpcom/attachments.js +++ b/chrome/content/zotero/xpcom/attachments.js @@ -2423,7 +2423,11 @@ Zotero.Attachments = new function () { value = value.toLowerCase().replace(/\s+/g, '_'); break; case 'camel': - value = value.toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g, (m, chr) => chr.toUpperCase()); + value = value.toLowerCase().replace(/[^\p{L}\d]+(.)/gu, (m, chr) => chr.toUpperCase()); + break; + case 'pascal': + value = value.toLowerCase().replace(/[^\p{L}\d]+(.)/gu, (m, chr) => chr.toUpperCase()); + value = value.slice(0, 1).toUpperCase() + value.slice(1); break; } return value; diff --git a/test/tests/attachmentsTest.js b/test/tests/attachmentsTest.js index b2138036cf..5aebff446a 100644 --- a/test/tests/attachmentsTest.js +++ b/test/tests/attachmentsTest.js @@ -1377,7 +1377,7 @@ describe("Zotero.Attachments", function() { describe("#getFileBaseNameFromItem()", function () { var item, itemManyAuthors, itemPatent, itemIncomplete, itemBookSection, itemSpaces, itemSuffixes, itemKeepHyphens, - itemNoRepeatedHyphens, itemNoRepeatedUnderscores; + itemNoRepeatedHyphens, itemNoRepeatedUnderscores, itemLowerCase, itemMixedCase, itemUnicode; before(() => { item = createUnsavedDataObject('item', { title: 'Lorem Ipsum', itemType: 'journalArticle' }); @@ -1430,6 +1430,9 @@ describe("Zotero.Attachments", function() { itemNoRepeatedHyphens.setField('publicationTitle', "no- repeated- hyphens"); itemNoRepeatedUnderscores = createUnsavedDataObject('item', { title: 'no _ repeated _ underscores', itemType: 'journalArticle' }); itemNoRepeatedUnderscores.setField('publicationTitle', "no_ repeated_ underscores"); + itemLowerCase = createUnsavedDataObject('item', { title: 'lower case title', itemType: 'journalArticle' }); + itemMixedCase = createUnsavedDataObject('item', { title: 'Old MacDonald Had a Farm', itemType: 'journalArticle' }); + itemUnicode = createUnsavedDataObject('item', { title: '金毛猎犬 - Golden Retriever', itemType: 'journalArticle' }); }); it('should strip HTML tags from title', function () { @@ -1597,6 +1600,41 @@ describe("Zotero.Attachments", function() { Zotero.Attachments.getFileBaseNameFromItem(item, { formatString: '{{ publicationTitle case="snake" }}' }), 'best_publications_place' ); + assert.equal( + Zotero.Attachments.getFileBaseNameFromItem(item, { formatString: '{{ publicationTitle case="pascal" }}' }), + 'BestPublicationsPlace' + ); + assert.equal( + Zotero.Attachments.getFileBaseNameFromItem(itemLowerCase, { formatString: '{{ title case="pascal" }}' }), + 'LowerCaseTitle' + ); + assert.equal( + Zotero.Attachments.getFileBaseNameFromItem(itemMixedCase, { formatString: '{{ title case="pascal" }}' }), + 'OldMacdonaldHadAFarm' + ); + assert.equal( + Zotero.Attachments.getFileBaseNameFromItem(itemNoRepeatedHyphens, { formatString: '{{ title case="camel" }}' }), + 'noRepeatedHyphens' + ); + assert.equal( + Zotero.Attachments.getFileBaseNameFromItem(itemNoRepeatedHyphens, { formatString: '{{ title case="pascal" }}' }), + 'NoRepeatedHyphens' + ); + }); + + it('should preserve unicode characters', async function () { + assert.equal( + Zotero.Attachments.getFileBaseNameFromItem(itemUnicode, { formatString: '{{ title case="camel" }}' }), + '金毛猎犬GoldenRetriever' + ); + assert.equal( + Zotero.Attachments.getFileBaseNameFromItem(itemUnicode, { formatString: '{{ title case="pascal" }}' }), + '金毛猎犬GoldenRetriever' + ); + assert.equal( + Zotero.Attachments.getFileBaseNameFromItem(itemUnicode, { formatString: '{{ title case="hyphen" }}' }), + '金毛猎犬-golden-retriever' + ); }); it('should not create repeated characters when converting case to hyphen or snake', async function () {