Skip to content

Commit 99d49ca

Browse files
authored
Fix: fallback conversion from BibTeX year field to biblatex date field (#13040)
* Add fallback logic to ConvertToBiblatexCleanup for parsing ISO-style dates in BibTeX `year` field * Add fallback logic to ConvertToBiblatexCleanup for parsing ISO-style dates in BibTeX `year` field * Add changelog entry * changelog * test: replace setField with withField * apply suggestions for concise changelog and remove redundant trim in ConvertToBiblatexCleanup * use List instead of Collection in applyDateFallback * use hasField for date check * fix: Trim input in Date.parse and apply style review feedback #13040 * fix: Trim input in Date.parse and apply style review feedback #13040
1 parent d9ea011 commit 99d49ca

File tree

5 files changed

+56
-0
lines changed

5 files changed

+56
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ Note that this project **does not** adhere to [Semantic Versioning](https://semv
1919

2020
### Fixed
2121

22+
- We added a fallback for the "Convert to biblatex" cleanup when it failed to populate the `date` field if `year` contained a full date in ISO format (e.g., `2011-11-11`). [#11868](https://github.com/JabRef/jabref/issues/11868)
2223
- We fixed an issue where directory check for relative path was not handled properly under library properties. [#13017](https://github.com/JabRef/jabref/issues/13017)
2324
- We fixed an issue where the option for which method to use when parsing plaintext citations was unavailable in the 'Create New Entry' tool. [#8808](https://github.com/JabRef/jabref/issues/8808)
2425

jablib/src/main/java/org/jabref/logic/cleanup/ConvertToBiblatexCleanup.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,30 @@ public List<FieldChange> cleanup(BibEntry entry) {
5353
}
5454
});
5555
}
56+
// If still no 'date' field, try fallback logic
57+
if (!entry.hasField(StandardField.DATE)) {
58+
changes.addAll(applyDateFallback(entry));
59+
}
60+
61+
return changes;
62+
}
63+
64+
private List<FieldChange> applyDateFallback(BibEntry entry) {
65+
Optional<String> yearValue = entry.getFieldOrAlias(StandardField.YEAR);
66+
if (yearValue.isEmpty()) {
67+
return List.of();
68+
}
69+
70+
String yearText = yearValue.get();
71+
if (Date.parse(yearText).isEmpty()) {
72+
return List.of();
73+
}
74+
75+
List<FieldChange> changes = new ArrayList<>();
76+
// If year was a full date, move it from year to date field.
77+
entry.setField(StandardField.DATE, yearText).ifPresent(changes::add);
78+
entry.clearField(StandardField.YEAR).ifPresent(changes::add);
79+
5680
return changes;
5781
}
5882
}

jablib/src/main/java/org/jabref/model/entry/Date.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ public Date(TemporalAccessor date, Season season) {
130130
public static Optional<Date> parse(String dateString) {
131131
Objects.requireNonNull(dateString);
132132

133+
dateString = dateString.strip();
134+
133135
if (dateString.isEmpty()) {
134136
return Optional.empty();
135137
}

jablib/src/test/java/org/jabref/logic/cleanup/ConvertToBiblatexCleanupTest.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
import org.junit.jupiter.api.BeforeEach;
99
import org.junit.jupiter.api.Test;
10+
import org.junit.jupiter.params.ParameterizedTest;
11+
import org.junit.jupiter.params.provider.ValueSource;
1012

1113
import static org.junit.jupiter.api.Assertions.assertEquals;
1214

@@ -97,4 +99,22 @@ void cleanupMovesJournalToJournaltitle() {
9799
assertEquals(Optional.empty(), entry.getField(StandardField.JOURNAL));
98100
assertEquals(Optional.of("Best of JabRef"), entry.getField(StandardField.JOURNALTITLE));
99101
}
102+
103+
@ParameterizedTest
104+
@ValueSource(strings = {
105+
"2011-11",
106+
"2011-11-11",
107+
"2010/2011",
108+
"0030 BC",
109+
"-0876",
110+
"2004-22"
111+
})
112+
void fallbackDateParsing_shouldAcceptTypicalBibLatexValues(String fakeYear) {
113+
BibEntry entry = new BibEntry().withField(StandardField.YEAR, fakeYear);
114+
115+
worker.cleanup(entry);
116+
117+
assertEquals(Optional.of(fakeYear), entry.getField(StandardField.DATE));
118+
assertEquals(Optional.empty(), entry.getField(StandardField.YEAR));
119+
}
100120
}

jablib/src/test/java/org/jabref/model/entry/DateTest.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,4 +123,13 @@ void parseZonedTime() {
123123
void parseDateNull() {
124124
assertThrows(NullPointerException.class, () -> Date.parse(null));
125125
}
126+
127+
// Date.parse() has been updated to defensively strip surrounding whitespace from input strings.
128+
@Test
129+
void parseShouldTrimValidDate() {
130+
assertEquals(
131+
Date.parse("2025-05-02"),
132+
Date.parse(" 2025-05-02 ")
133+
);
134+
}
126135
}

0 commit comments

Comments
 (0)