Skip to content

Commit 9adfd5b

Browse files
authored
Fix order of fields in bib file (#6750)
1 parent bbabd92 commit 9adfd5b

File tree

4 files changed

+45
-31
lines changed

4 files changed

+45
-31
lines changed

src/main/java/org/jabref/logic/bibtex/BibEntryWriter.java

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,13 @@
33
import java.io.IOException;
44
import java.io.StringWriter;
55
import java.io.Writer;
6+
import java.util.Collection;
67
import java.util.Comparator;
8+
import java.util.HashSet;
79
import java.util.List;
810
import java.util.Locale;
911
import java.util.Optional;
12+
import java.util.Set;
1013
import java.util.SortedSet;
1114
import java.util.TreeSet;
1215
import java.util.function.Predicate;
@@ -21,7 +24,6 @@
2124
import org.jabref.model.entry.field.BibField;
2225
import org.jabref.model.entry.field.Field;
2326
import org.jabref.model.entry.field.InternalField;
24-
import org.jabref.model.entry.field.OrFields;
2527
import org.jabref.model.strings.StringUtil;
2628

2729
public class BibEntryWriter {
@@ -91,30 +93,44 @@ public void writeWithoutPrependedNewlines(BibEntry entry, Writer out, BibDatabas
9193
*/
9294
private void writeRequiredFieldsFirstRemainingFieldsSecond(BibEntry entry, Writer out,
9395
BibDatabaseMode bibDatabaseMode) throws IOException {
94-
// Write header with type and bibtex-key.
96+
// Write header with type and bibtex-key
9597
TypedBibEntry typedEntry = new TypedBibEntry(entry, bibDatabaseMode);
9698
out.write('@' + typedEntry.getTypeForDisplay() + '{');
9799

98100
writeKeyField(entry, out);
99101

100-
TreeSet<Field> written = new TreeSet<>(Comparator.comparing(Field::getName));
102+
Set<Field> written = new HashSet<>();
101103
written.add(InternalField.KEY_FIELD);
102104
int indentation = getLengthOfLongestFieldName(entry);
103105

104106
Optional<BibEntryType> type = entryTypesManager.enrich(entry.getType(), bibDatabaseMode);
105107
if (type.isPresent()) {
106-
// Write required fields first.
107-
for (OrFields value : type.get().getRequiredFields()) {
108-
for (Field field : value) {
109-
writeField(entry, out, field, indentation);
110-
written.add(field);
111-
}
108+
// Write required fields first
109+
List<Field> requiredFields = type.get()
110+
.getRequiredFields()
111+
.stream()
112+
.flatMap(Collection::stream)
113+
.sorted(Comparator.comparing(Field::getName))
114+
.collect(Collectors.toList());
115+
116+
for (Field field : requiredFields) {
117+
writeField(entry, out, field, indentation);
112118
}
113-
// Then optional fields.
114-
for (BibField field : type.get().getOptionalFields()) {
115-
writeField(entry, out, field.getField(), indentation);
116-
written.add(field.getField());
119+
120+
// Then optional fields
121+
List<Field> optionalFields = type.get()
122+
.getOptionalFields()
123+
.stream()
124+
.map(BibField::getField)
125+
.sorted(Comparator.comparing(Field::getName))
126+
.collect(Collectors.toList());
127+
128+
for (Field field : optionalFields) {
129+
writeField(entry, out, field, indentation);
117130
}
131+
132+
written.addAll(requiredFields);
133+
written.addAll(optionalFields);
118134
}
119135
// Then write remaining fields in alphabetic order.
120136
SortedSet<Field> remainingFields = entry.getFields()

src/test/java/org/jabref/logic/bibtex/BibEntryWriterTest.java

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import org.jabref.model.util.FileUpdateMonitor;
2323

2424
import org.junit.jupiter.api.BeforeEach;
25-
import org.junit.jupiter.api.Disabled;
2625
import org.junit.jupiter.api.Test;
2726
import org.mockito.Answers;
2827

@@ -64,8 +63,8 @@ void testSerialization() throws IOException {
6463
String expected = OS.NEWLINE + "@Article{," + OS.NEWLINE +
6564
" author = {Foo Bar}," + OS.NEWLINE +
6665
" journal = {International Journal of Something}," + OS.NEWLINE +
67-
" number = {1}," + OS.NEWLINE +
6866
" note = {some note}," + OS.NEWLINE +
67+
" number = {1}," + OS.NEWLINE +
6968
"}" + OS.NEWLINE;
7069
// @formatter:on
7170

@@ -126,8 +125,8 @@ void writeEntryWithOrField() throws Exception {
126125
// @formatter:off
127126
String expected = OS.NEWLINE + "@InBook{," + OS.NEWLINE +
128127
" editor = {Foo Bar}," + OS.NEWLINE +
129-
" number = {1}," + OS.NEWLINE +
130128
" note = {some note}," + OS.NEWLINE +
129+
" number = {1}," + OS.NEWLINE +
131130
" journal = {International Journal of Something}," + OS.NEWLINE +
132131
"}" + OS.NEWLINE;
133132
// @formatter:on
@@ -156,8 +155,8 @@ void writeEntryWithOrFieldBothFieldsPresent() throws Exception {
156155
String expected = OS.NEWLINE + "@InBook{," + OS.NEWLINE +
157156
" author = {Foo Thor}," + OS.NEWLINE +
158157
" editor = {Edi Bar}," + OS.NEWLINE +
159-
" number = {1}," + OS.NEWLINE +
160158
" note = {some note}," + OS.NEWLINE +
159+
" number = {1}," + OS.NEWLINE +
161160
" journal = {International Journal of Something}," + OS.NEWLINE +
162161
"}" + OS.NEWLINE;
163162
// @formatter:on
@@ -260,8 +259,8 @@ void roundTripWithModification() throws IOException {
260259
String expected = OS.NEWLINE + "@Article{test," + OS.NEWLINE +
261260
" author = {BlaBla}," + OS.NEWLINE +
262261
" journal = {International Journal of Something}," + OS.NEWLINE +
263-
" number = {1}," + OS.NEWLINE +
264262
" note = {some note}," + OS.NEWLINE +
263+
" number = {1}," + OS.NEWLINE +
265264
"}" + OS.NEWLINE;
266265
// @formatter:on
267266
assertEquals(expected, actual);
@@ -296,8 +295,8 @@ void roundTripWithCamelCasingInTheOriginalEntryAndResultInLowerCase() throws IOE
296295
String expected = OS.NEWLINE + "@Article{test," + OS.NEWLINE +
297296
" author = {BlaBla}," + OS.NEWLINE +
298297
" journal = {International Journal of Something}," + OS.NEWLINE +
299-
" number = {1}," + OS.NEWLINE +
300298
" note = {some note}," + OS.NEWLINE +
299+
" number = {1}," + OS.NEWLINE +
301300
" howpublished = {asdf}," + OS.NEWLINE +
302301
"}" + OS.NEWLINE;
303302
// @formatter:on
@@ -332,8 +331,8 @@ void testEntryTypeChange() throws IOException {
332331
// @formatter:off
333332
String expectedNewEntry = OS.NEWLINE + "@InProceedings{test," + OS.NEWLINE +
334333
" author = {BlaBla}," + OS.NEWLINE +
335-
" number = {1}," + OS.NEWLINE +
336334
" note = {some note}," + OS.NEWLINE +
335+
" number = {1}," + OS.NEWLINE +
337336
" howpublished = {asdf}," + OS.NEWLINE +
338337
" journal = {International Journal of Something}," + OS.NEWLINE +
339338
"}" + OS.NEWLINE;
@@ -489,8 +488,8 @@ void addFieldWithLongerLength() throws IOException {
489488
String expected = OS.NEWLINE + "@Article{test," + OS.NEWLINE +
490489
" author = {BlaBla}," + OS.NEWLINE +
491490
" journal = {International Journal of Something}," + OS.NEWLINE +
492-
" number = {1}," + OS.NEWLINE +
493491
" note = {some note}," + OS.NEWLINE +
492+
" number = {1}," + OS.NEWLINE +
494493
" howpublished = {asdf}," + OS.NEWLINE +
495494
"}" + OS.NEWLINE;
496495
// @formatter:on
@@ -580,15 +579,14 @@ void roundTripWithPrecedingCommentAndModificationTest() throws IOException {
580579
"@Article{test," + OS.NEWLINE +
581580
" author = {John Doe}," + OS.NEWLINE +
582581
" journal = {International Journal of Something}," + OS.NEWLINE +
583-
" number = {1}," + OS.NEWLINE +
584582
" note = {some note}," + OS.NEWLINE +
583+
" number = {1}," + OS.NEWLINE +
585584
"}" + OS.NEWLINE;
586585
// @formatter:on
587586

588587
assertEquals(expected, actual);
589588
}
590589

591-
@Disabled("We don't have alphabetic serialization anylonger TODO")
592590
@Test
593591
void alphabeticSerialization() throws IOException {
594592
StringWriter stringWriter = new StringWriter();
@@ -616,8 +614,8 @@ void alphabeticSerialization() throws IOException {
616614
" date = {2019-10-16}," + OS.NEWLINE +
617615
" journaltitle = {International Journal of Something}," + OS.NEWLINE +
618616
" title = {Title}," + OS.NEWLINE +
619-
" number = {1}," + OS.NEWLINE +
620617
" note = {some note}," + OS.NEWLINE +
618+
" number = {1}," + OS.NEWLINE +
621619
" chapter = {chapter}," + OS.NEWLINE +
622620
" year = {2019}," + OS.NEWLINE +
623621
"}" + OS.NEWLINE;

src/test/java/org/jabref/logic/exporter/BibtexDatabaseWriterTest.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -694,7 +694,7 @@ void roundtripWithContentSelectorsAndUmlauts() throws Exception {
694694
}
695695

696696
@Test
697-
public void saveAlsoSavesSecondModification() throws Exception {
697+
void saveAlsoSavesSecondModification() throws Exception {
698698
// @formatter:off
699699
String bibtexEntry = OS.NEWLINE + "@Article{test," + OS.NEWLINE +
700700
" Author = {Foo Bar}," + OS.NEWLINE +
@@ -730,21 +730,21 @@ public void saveAlsoSavesSecondModification() throws Exception {
730730
"@Article{test," + OS.NEWLINE +
731731
" author = {Test}," + OS.NEWLINE +
732732
" journal = {International Journal of Something}," + OS.NEWLINE +
733-
" number = {1}," + OS.NEWLINE +
734733
" note = {some note}," + OS.NEWLINE +
734+
" number = {1}," + OS.NEWLINE +
735735
"}" + OS.NEWLINE +
736736
"" + OS.NEWLINE +
737737
"@Comment{jabref-meta: databaseType:bibtex;}" + OS.NEWLINE, stringWriter.toString());
738738
}
739739

740740
@Test
741-
public void saveReturnsToOriginalEntryWhenEntryIsFlaggedUnchanged() throws Exception {
741+
void saveReturnsToOriginalEntryWhenEntryIsFlaggedUnchanged() throws Exception {
742742
// @formatter:off
743743
String bibtexEntry = OS.NEWLINE + "@Article{test," + OS.NEWLINE +
744744
" Author = {Foo Bar}," + OS.NEWLINE +
745745
" Journal = {International Journal of Something}," + OS.NEWLINE +
746-
" Note = {some note}," + OS.NEWLINE +
747746
" Number = {1}," + OS.NEWLINE +
747+
" Note = {some note}," + OS.NEWLINE +
748748
"}";
749749
// @formatter:on
750750

@@ -770,7 +770,7 @@ public void saveReturnsToOriginalEntryWhenEntryIsFlaggedUnchanged() throws Excep
770770
}
771771

772772
@Test
773-
public void saveReturnsToOriginalEntryWhenEntryIsFlaggedUnchangedEvenInThePrecenseOfSavedModifications() throws Exception {
773+
void saveReturnsToOriginalEntryWhenEntryIsFlaggedUnchangedEvenInThePrecenseOfSavedModifications() throws Exception {
774774
// @formatter:off
775775
String bibtexEntry = OS.NEWLINE + "@Article{test," + OS.NEWLINE +
776776
" Author = {Foo Bar}," + OS.NEWLINE +

src/test/resources/testbib/bibWithUserCommentAndEntryChange.bib

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,11 @@ @Comment this
3232
3333
@InProceedings{1137631,
3434
author = {Mr. Author},
35-
title = {Extending XP practices to support security requirements engineering},
3635
booktitle = {SESS '06: Proceedings of the 2006 international workshop on Software engineering for secure systems},
36+
title = {Extending XP practices to support security requirements engineering},
3737
year = {2006},
38-
pages = {11--18},
3938
address = {New York, NY, USA},
39+
pages = {11--18},
4040
publisher = {ACM},
4141
bdsk-url-1 = {http://doi.acm.org/10.1145/1137627.1137631},
4242
doi = {http://doi.acm.org/10.1145/1137627.1137631},

0 commit comments

Comments
 (0)