diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f3c3ca1d53..f4dba622ad6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -80,6 +80,7 @@ Note that this project **does not** adhere to [Semantic Versioning](http://semve - We fixed an issue where hitting enter on the search field within the preferences dialog closed the dialog. [koppor#630](https://github.com/koppor/jabref/issues/630) - We fixed a typo within a connection error message. [koppor#625](https://github.com/koppor/jabref/issues/625) - We fixed an issue where the 'close dialog' key binding was not closing the Preferences dialog. [#8888](https://github.com/jabref/jabref/issues/8888) +- We fixed an issue where journal abbreviations would not abbreviate journal titles with escaped ampersands (\\&). [#8948](https://github.com/JabRef/jabref/issues/8948) - We fixed an issue where font size preferences did not apply correctly to preference dialog window and the menu bar. [#8386](https://github.com/JabRef/jabref/issues/8386) and [#9279](https://github.com/JabRef/jabref/issues/9279) - We fixed an issue when using an unsafe character in the citation key, the auto-linking feature fails to link files. [#9267](https://github.com/JabRef/jabref/issues/9267) diff --git a/src/main/java/org/jabref/logic/journals/JournalAbbreviationRepository.java b/src/main/java/org/jabref/logic/journals/JournalAbbreviationRepository.java index 523e1323be1..825bd706e27 100644 --- a/src/main/java/org/jabref/logic/journals/JournalAbbreviationRepository.java +++ b/src/main/java/org/jabref/logic/journals/JournalAbbreviationRepository.java @@ -7,6 +7,7 @@ import java.util.Objects; import java.util.Optional; import java.util.Set; +import java.util.regex.Matcher; import java.util.stream.Collectors; import org.h2.mvstore.MVMap; @@ -48,7 +49,7 @@ private static boolean isMatchedAbbreviated(String name, Abbreviation abbreviati * Letters) or its abbreviated form (e.g. Phys. Rev. Lett.). */ public boolean isKnownName(String journalName) { - String journal = journalName.trim(); + String journal = journalName.trim().replaceAll(Matcher.quoteReplacement("\\&"), "&"); boolean isKnown = customAbbreviations.stream().anyMatch(abbreviation -> isMatched(journal, abbreviation)); if (isKnown) { @@ -75,7 +76,7 @@ public boolean isAbbreviatedName(String journalName) { * @param input The journal name (either abbreviated or full name). */ public Optional get(String input) { - String journal = input.trim(); + String journal = input.trim().replaceAll(Matcher.quoteReplacement("\\&"), "&"); Optional customAbbreviation = customAbbreviations.stream() .filter(abbreviation -> isMatched(journal, abbreviation)) diff --git a/src/test/java/org/jabref/architecture/MainArchitectureTests.java b/src/test/java/org/jabref/architecture/MainArchitectureTests.java index 25b60cea46c..86335032845 100644 --- a/src/test/java/org/jabref/architecture/MainArchitectureTests.java +++ b/src/test/java/org/jabref/architecture/MainArchitectureTests.java @@ -115,6 +115,7 @@ public static void restrictUsagesInModel(JavaClasses classes) { @ArchTest public static void restrictUsagesInLogic(JavaClasses classes) { noClasses().that().resideInAPackage(PACKAGE_ORG_JABREF_LOGIC) + .and().areNotAnnotatedWith(AllowedToUseSwing.class) .should().dependOnClassesThat().resideInAPackage(PACKAGE_JAVAX_SWING) .orShould().dependOnClassesThat().haveFullyQualifiedName(CLASS_ORG_JABREF_GLOBALS) .check(classes); diff --git a/src/test/java/org/jabref/logic/bibtex/BibEntryWriterTest.java b/src/test/java/org/jabref/logic/bibtex/BibEntryWriterTest.java index ad5f8f70ecb..9c1dc3f3aa9 100644 --- a/src/test/java/org/jabref/logic/bibtex/BibEntryWriterTest.java +++ b/src/test/java/org/jabref/logic/bibtex/BibEntryWriterTest.java @@ -856,7 +856,7 @@ static Stream testGetFormattedFieldNameData() { @MethodSource("testGetFormattedFieldNameData") void testGetFormattedFieldName(String expected, String fieldName, int indent) { Field field = FieldFactory.parseField(fieldName); - assertEquals(expected, bibEntryWriter.getFormattedFieldName(field, indent)); + assertEquals(expected, BibEntryWriter.getFormattedFieldName(field, indent)); } static Stream testGetLengthOfLongestFieldNameData() { @@ -871,6 +871,6 @@ static Stream testGetLengthOfLongestFieldNameData() { @ParameterizedTest @MethodSource("testGetLengthOfLongestFieldNameData") void testGetLengthOfLongestFieldName(int expected, BibEntry entry) { - assertEquals(expected, bibEntryWriter.getLengthOfLongestFieldName(entry)); + assertEquals(expected, BibEntryWriter.getLengthOfLongestFieldName(entry)); } } diff --git a/src/test/java/org/jabref/logic/journals/JournalAbbreviationRepositoryTest.java b/src/test/java/org/jabref/logic/journals/JournalAbbreviationRepositoryTest.java index 68071fe0089..97c6766676f 100644 --- a/src/test/java/org/jabref/logic/journals/JournalAbbreviationRepositoryTest.java +++ b/src/test/java/org/jabref/logic/journals/JournalAbbreviationRepositoryTest.java @@ -1,5 +1,16 @@ package org.jabref.logic.journals; +import javax.swing.undo.CompoundEdit; + +import org.jabref.architecture.AllowedToUseSwing; +import org.jabref.gui.journals.AbbreviationType; +import org.jabref.gui.journals.UndoableAbbreviator; +import org.jabref.gui.journals.UndoableUnabbreviator; +import org.jabref.model.database.BibDatabase; +import org.jabref.model.entry.BibEntry; +import org.jabref.model.entry.field.StandardField; +import org.jabref.model.entry.types.StandardEntryType; + import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -7,6 +18,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; +@AllowedToUseSwing("UndoableUnabbreviator and UndoableAbbreviator requires Swing Compound Edit in order test the abbreviation and unabreviation of journal titles") class JournalAbbreviationRepositoryTest { private JournalAbbreviationRepository repository; @@ -134,4 +146,61 @@ void getFromFullName() { void getFromAbbreviatedName() { assertEquals(new Abbreviation("American Journal of Public Health", "Am. J. Public Health"), repository.get("Am. J. Public Health").get()); } + + @Test + void testAbbreviationsWithEscapedAmpersand() { + assertEquals(new Abbreviation("ACS Applied Materials & Interfaces", "ACS Appl. Mater. Interfaces"), repository.get("ACS Applied Materials & Interfaces").get()); + assertEquals(new Abbreviation("ACS Applied Materials & Interfaces", "ACS Appl. Mater. Interfaces"), repository.get("ACS Applied Materials \\& Interfaces").get()); + assertEquals(new Abbreviation("Antioxidants & Redox Signaling", "Antioxid. Redox Signaling"), repository.get("Antioxidants & Redox Signaling").get()); + assertEquals(new Abbreviation("Antioxidants & Redox Signaling", "Antioxid. Redox Signaling"), repository.get("Antioxidants \\& Redox Signaling").get()); + + repository.addCustomAbbreviation(new Abbreviation("Long & Name", "L. N.", "LN")); + assertEquals(new Abbreviation("Long & Name", "L. N.", "LN"), repository.get("Long & Name").get()); + assertEquals(new Abbreviation("Long & Name", "L. N.", "LN"), repository.get("Long \\& Name").get()); + } + + @Test + void testJournalAbbreviationWithEscapedAmpersand() { + BibDatabase bibDatabase = new BibDatabase(); + JournalAbbreviationRepository journalAbbreviationRepository = JournalAbbreviationLoader.loadBuiltInRepository(); + UndoableAbbreviator undoableAbbreviator = new UndoableAbbreviator(journalAbbreviationRepository, AbbreviationType.DEFAULT); + + BibEntry entryWithEscapedAmpersandInJournal = new BibEntry(StandardEntryType.Article); + entryWithEscapedAmpersandInJournal.setField(StandardField.JOURNAL, "ACS Applied Materials \\& Interfaces"); + + undoableAbbreviator.abbreviate(bibDatabase, entryWithEscapedAmpersandInJournal, StandardField.JOURNAL, new CompoundEdit()); + BibEntry expectedAbbreviatedJournalEntry = new BibEntry(StandardEntryType.Article) + .withField(StandardField.JOURNAL, "ACS Appl. Mater. Interfaces"); + assertEquals(expectedAbbreviatedJournalEntry, entryWithEscapedAmpersandInJournal); + } + + @Test + void testJournalUnabbreviate() { + BibDatabase bibDatabase = new BibDatabase(); + JournalAbbreviationRepository journalAbbreviationRepository = JournalAbbreviationLoader.loadBuiltInRepository(); + UndoableUnabbreviator undoableUnabbreviator = new UndoableUnabbreviator(journalAbbreviationRepository); + + BibEntry abbreviatedJournalEntry = new BibEntry(StandardEntryType.Article); + abbreviatedJournalEntry.setField(StandardField.JOURNAL, "ACS Appl. Mater. Interfaces"); + + undoableUnabbreviator.unabbreviate(bibDatabase, abbreviatedJournalEntry, StandardField.JOURNAL, new CompoundEdit()); + BibEntry expectedAbbreviatedJournalEntry = new BibEntry(StandardEntryType.Article) + .withField(StandardField.JOURNAL, "ACS Applied Materials & Interfaces"); + assertEquals(expectedAbbreviatedJournalEntry, abbreviatedJournalEntry); + } + + @Test + void testJournalAbbreviateWithoutEscapedAmpersand() { + BibDatabase bibDatabase = new BibDatabase(); + JournalAbbreviationRepository journalAbbreviationRepository = JournalAbbreviationLoader.loadBuiltInRepository(); + UndoableAbbreviator undoableAbbreviator = new UndoableAbbreviator(journalAbbreviationRepository, AbbreviationType.DEFAULT); + + BibEntry entryWithoutEscapedAmpersandInJournal = new BibEntry(StandardEntryType.Article); + entryWithoutEscapedAmpersandInJournal.setField(StandardField.JOURNAL, "ACS Applied Materials & Interfaces"); + + undoableAbbreviator.abbreviate(bibDatabase, entryWithoutEscapedAmpersandInJournal, StandardField.JOURNAL, new CompoundEdit()); + BibEntry expectedAbbreviatedJournalEntry = new BibEntry(StandardEntryType.Article) + .withField(StandardField.JOURNAL, "ACS Appl. Mater. Interfaces"); + assertEquals(expectedAbbreviatedJournalEntry, entryWithoutEscapedAmpersandInJournal); + } }