Skip to content

Commit

Permalink
[WIP] Add "Convert to BibTeX format" cleanup (#3541)
Browse files Browse the repository at this point in the history
* Add "Convert to BibTeX format" cleanup

* Add round-trip tests

* Fix tests

* Make conversations modal
  • Loading branch information
tobiasdiez authored Jan 18, 2018
1 parent 731a743 commit beb6ee0
Show file tree
Hide file tree
Showing 17 changed files with 263 additions and 71 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ For more details refer to the [field mapping help page](http://help.jabref.org/e
- We increased the relative size of the "abstract" field in the entry editor. [Feature request in the forum](http://discourse.jabref.org/t/entry-preview-in-version-4/827)
- Crossreferenced entries are now used when a BibTex key is generated for an entry with empty fields. [#2811](https://github.com/JabRef/jabref/issues/2811)
- We now set the `WM_CLASS` of the UI to org-jabref-JabRefMain to allow certain Un*x window managers to properly identify its windows
- We added an option to convert entries in the biblatex format to BibTeX so that you can again collaborate with these nostalgic diehards. [Feature request in the forum](http://discourse.jabref.org/t/convert-back-from-biblatex-to-bib/)
- We changed the default paths for the OpenOffice/LibreOffice binaries to the default path for LibreOffice
- File annotation tab now removes newlines and hyphens before newlines from content and displays an empty String instead of N/A if no contents are found. [#3280](https://github.com/JabRef/jabref/issues/3280)
- We moved the groups field from the "Other fields" tab to "General" (you may have to reset your editor preferences under Options > Set up general fields)
Expand Down
22 changes: 17 additions & 5 deletions src/main/java/org/jabref/gui/cleanup/CleanupPresetPanel.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import java.util.Optional;
import java.util.Set;

import javax.swing.ButtonGroup;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
Expand Down Expand Up @@ -33,6 +34,7 @@ public class CleanupPresetPanel {
private JCheckBox cleanUpRenamePDFonlyRelativePaths;
private JCheckBox cleanUpUpgradeExternalLinks;
private JCheckBox cleanUpBiblatex;
private JCheckBox cleanUpBibtex;
private FieldFormatterCleanupsPanel cleanUpFormatters;

private JPanel panel;
Expand Down Expand Up @@ -72,14 +74,19 @@ private void init() {
Localization.lang("Upgrade external PDF/PS links to use the '%0' field.", FieldName.FILE));
cleanUpBiblatex = new JCheckBox(Localization.lang(
"Convert to biblatex format (for example, move the value of the 'journal' field to 'journaltitle')"));
cleanUpBibtex = new JCheckBox(Localization.lang(
"Convert to BibTeX format (for example, move the value of the 'journaltitle' field to 'journal')"));
ButtonGroup biblatexConversion = new ButtonGroup(); // Only make "to Biblatex" or "to BibTeX" selectable
biblatexConversion.add(cleanUpBiblatex);
biblatexConversion.add(cleanUpBibtex);

cleanUpFormatters = new FieldFormatterCleanupsPanel(Localization.lang("Run field formatter:"),
Cleanups.DEFAULT_SAVE_ACTIONS);

updateDisplay(cleanupPreset);

FormLayout layout = new FormLayout("left:15dlu, fill:pref:grow",
"pref, pref, pref, pref, pref, fill:pref:grow, pref,pref, pref,190dlu, fill:pref:grow,");
"pref, pref, pref, pref, pref, fill:pref:grow, pref,pref, pref, pref,190dlu, fill:pref:grow,");

FormBuilder builder = FormBuilder.create().layout(layout);
builder.add(cleanUpDOI).xyw(1, 1, 2);
Expand All @@ -91,9 +98,10 @@ private void init() {
currentPattern = currentPattern.concat(Globals.prefs.get(JabRefPreferences.IMPORT_FILENAMEPATTERN));
builder.add(new JLabel(currentPattern)).xy(2, 6);
builder.add(cleanUpRenamePDFonlyRelativePaths).xy(2, 7);
builder.add(cleanUpBiblatex).xyw(1, 8, 2);
builder.add(cleanUpISSN).xyw(1, 9, 2);
builder.add(cleanUpFormatters).xyw(1, 10, 2);
builder.add(cleanUpBibtex).xyw(1, 8, 2);
builder.add(cleanUpBiblatex).xyw(1, 9, 2);
builder.add(cleanUpISSN).xyw(1, 10, 2);
builder.add(cleanUpFormatters).xyw(1, 11, 2);
panel = builder.build();
scrollPane = new JScrollPane(panel);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
Expand All @@ -112,7 +120,8 @@ private void updateDisplay(CleanupPreset preset) {
cleanUpRenamePDFonlyRelativePaths.setEnabled(cleanUpRenamePDF.isSelected());
cleanUpUpgradeExternalLinks.setSelected(preset.isCleanUpUpgradeExternalLinks());
cleanUpBiblatex.setSelected(preset.isConvertToBiblatex());
cleanUpBiblatex.setSelected(preset.isCleanUpISSN());
cleanUpBibtex.setSelected(preset.isConvertToBibtex());
cleanUpISSN.setSelected(preset.isCleanUpISSN());
cleanUpFormatters.setValues(preset.getFormatterCleanups());
}

Expand Down Expand Up @@ -150,6 +159,9 @@ public CleanupPreset getCleanupPreset() {
if (cleanUpBiblatex.isSelected()) {
activeJobs.add(CleanupPreset.CleanupStep.CONVERT_TO_BIBLATEX);
}
if (cleanUpBibtex.isSelected()) {
activeJobs.add(CleanupPreset.CleanupStep.CONVERT_TO_BIBTEX);
}

activeJobs.add(CleanupPreset.CleanupStep.FIX_FILE_LINKS);

Expand Down
12 changes: 12 additions & 0 deletions src/main/java/org/jabref/logic/cleanup/CleanupPreset.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ public static CleanupPreset loadFromPreferences(JabRefPreferences preferences) {
if (preferences.getBoolean(JabRefPreferences.CLEANUP_CONVERT_TO_BIBLATEX)) {
activeJobs.add(CleanupStep.CONVERT_TO_BIBLATEX);
}
if (preferences.getBoolean(JabRefPreferences.CLEANUP_CONVERT_TO_BIBTEX)) {
activeJobs.add(CleanupStep.CONVERT_TO_BIBTEX);
}
if (preferences.getBoolean(JabRefPreferences.CLEANUP_FIX_FILE_LINKS)) {
activeJobs.add(CleanupStep.FIX_FILE_LINKS);
}
Expand Down Expand Up @@ -102,6 +105,10 @@ public boolean isConvertToBiblatex() {
return isActive(CleanupStep.CONVERT_TO_BIBLATEX);
}

public boolean isConvertToBibtex() {
return isActive(CleanupStep.CONVERT_TO_BIBTEX);
}

public boolean isRenamePdfOnlyRelativePaths() {
return isActive(CleanupStep.RENAME_PDF_ONLY_RELATIVE_PATHS);
}
Expand All @@ -117,6 +124,7 @@ public void storeInPreferences(JabRefPreferences preferences) {
preferences.putBoolean(JabRefPreferences.CLEANUP_UPGRADE_EXTERNAL_LINKS,
isActive(CleanupStep.CLEAN_UP_UPGRADE_EXTERNAL_LINKS));
preferences.putBoolean(JabRefPreferences.CLEANUP_CONVERT_TO_BIBLATEX, isActive(CleanupStep.CONVERT_TO_BIBLATEX));
preferences.putBoolean(JabRefPreferences.CLEANUP_CONVERT_TO_BIBTEX, isActive(CleanupStep.CONVERT_TO_BIBTEX));
preferences.putBoolean(JabRefPreferences.CLEANUP_FIX_FILE_LINKS, isActive(CleanupStep.FIX_FILE_LINKS));

preferences.putStringList(JabRefPreferences.CLEANUP_FORMATTERS, formatterCleanups.getAsStringList(OS.NEWLINE));
Expand Down Expand Up @@ -146,6 +154,10 @@ public enum CleanupStep {
* Converts to biblatex format
*/
CONVERT_TO_BIBLATEX,
/**
* Converts to bibtex format
*/
CONVERT_TO_BIBTEX,
MOVE_PDF,
FIX_FILE_LINKS,
CLEAN_UP_ISSN
Expand Down
5 changes: 4 additions & 1 deletion src/main/java/org/jabref/logic/cleanup/CleanupWorker.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,10 @@ private List<CleanupJob> determineCleanupActions(CleanupPreset preset) {
List<CleanupJob> jobs = new ArrayList<>();

if (preset.isConvertToBiblatex()) {
jobs.add(new BiblatexCleanup());
jobs.add(new ConvertToBiblatexCleanup());
}
if (preset.isConvertToBibtex()) {
jobs.add(new ConvertToBibtexCleanup());
}
if (preset.getFormatterCleanups().isEnabled()) {
jobs.addAll(preset.getFormatterCleanups().getConfiguredActions());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
/**
* Converts the entry to biblatex format.
*/
public class BiblatexCleanup implements CleanupJob {
public class ConvertToBiblatexCleanup implements CleanupJob {

@Override
public List<FieldChange> cleanup(BibEntry entry) {
Expand Down
52 changes: 52 additions & 0 deletions src/main/java/org/jabref/logic/cleanup/ConvertToBibtexCleanup.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package org.jabref.logic.cleanup;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.jabref.model.FieldChange;
import org.jabref.model.cleanup.CleanupJob;
import org.jabref.model.entry.BibEntry;
import org.jabref.model.entry.EntryConverter;
import org.jabref.model.entry.FieldName;
import org.jabref.model.strings.StringUtil;

/**
* Converts the entry to biblatex format.
*/
public class ConvertToBibtexCleanup implements CleanupJob {

@Override
public List<FieldChange> cleanup(BibEntry entry) {
List<FieldChange> changes = new ArrayList<>();

// Dates: get date and fill year and month
// If there already exists a non blank/empty value for the field, then it is not overwritten
entry.getPublicationDate().ifPresent(date -> {
if (StringUtil.isBlank(entry.getField(FieldName.YEAR))) {
date.getYear().flatMap(year -> entry.setField(FieldName.YEAR, year.toString())).ifPresent(changes::add);
}

if (StringUtil.isBlank(entry.getField(FieldName.MONTH))) {
date.getMonth().flatMap(month -> entry.setField(FieldName.MONTH, month.getJabRefFormat())).ifPresent(changes::add);
}

if (changes.size() > 0) {
entry.clearField(FieldName.DATE).ifPresent(changes::add);
}
});

for (Map.Entry<String, String> alias : EntryConverter.FIELD_ALIASES_TEX_TO_LTX.entrySet()) {
String oldFieldName = alias.getValue();
String newFieldName = alias.getKey();
entry.getField(oldFieldName).ifPresent(oldValue -> {
if (!oldValue.isEmpty() && (!entry.getField(newFieldName).isPresent())) {
// There is content in the old field and no value in the new, so just copy
entry.setField(newFieldName, oldValue).ifPresent(changes::add);
entry.clearField(oldFieldName).ifPresent(changes::add);
}
});
}
return changes;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,10 @@ public List<BibEntry> parseEntries(String bibtexString) throws ParseException {
return parseEntries(new StringReader(bibtexString));
}

public Optional<BibEntry> parseSingleEntry(String bibtexString) throws ParseException {
return parseEntries(bibtexString).stream().findFirst();
}

/**
* Will parse the BibTex-Data found when reading from reader. Ignores any encoding supplied in the file by
* "Encoding: myEncoding".
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/jabref/logic/xmp/XMPUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -636,7 +636,7 @@ private static void writeToDCSchema(XMPSchemaDublinCore dcSchema, BibEntry entry
*
* Bibtex-Fields used: year, month
*/
entry.getPublicationDate()
entry.getFieldOrAlias(FieldName.DATE)
.ifPresent(publicationDate -> dcSchema.addSequenceValue("dc:date", publicationDate));
continue;
}
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/org/jabref/model/entry/BibEntry.java
Original file line number Diff line number Diff line change
Expand Up @@ -591,8 +591,8 @@ public Optional<String> getTitle() {
*
* @return will return the publication date of the entry or null if no year was found.
*/
public Optional<String> getPublicationDate() {
return getFieldOrAlias(FieldName.DATE);
public Optional<Date> getPublicationDate() {
return getFieldOrAlias(FieldName.DATE).flatMap(Date::parse);
}

public String getParsedSerialization() {
Expand Down
12 changes: 12 additions & 0 deletions src/main/java/org/jabref/model/entry/Date.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,18 @@ public class Date {

private final TemporalAccessor date;

public Date(int year, int month, int dayOfMonth) {
this(LocalDate.of(year, month, dayOfMonth));
}

public Date(int year, int month) {
this(YearMonth.of(year, month));
}

public Date(int year) {
this(Year.of(year));
}

public Date(TemporalAccessor date) {
this.date = date;
}
Expand Down
5 changes: 4 additions & 1 deletion src/main/java/org/jabref/preferences/JabRefPreferences.java
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,7 @@ public class JabRefPreferences implements PreferencesService {
public static final String CLEANUP_RENAME_PDF_ONLY_RELATIVE_PATHS = "CleanUpRenamePDFonlyRelativePaths";
public static final String CLEANUP_UPGRADE_EXTERNAL_LINKS = "CleanUpUpgradeExternalLinks";
public static final String CLEANUP_CONVERT_TO_BIBLATEX = "CleanUpConvertToBiblatex";
public static final String CLEANUP_CONVERT_TO_BIBTEX = "CleanUpConvertToBibtex";
public static final String CLEANUP_FIX_FILE_LINKS = "CleanUpFixFileLinks";
public static final String CLEANUP_FORMATTERS = "CleanUpFormatters";
public static final String IMPORT_DEFAULT_PDF_IMPORT_STYLE = "importDefaultPDFimportStyle";
Expand Down Expand Up @@ -913,7 +914,8 @@ private static void insertDefaultCleanupPreset(Map<String, Object> storage) {
CleanupPreset.CleanupStep.CLEAN_UP_UPGRADE_EXTERNAL_LINKS,
CleanupPreset.CleanupStep.MOVE_PDF,
CleanupPreset.CleanupStep.RENAME_PDF_ONLY_RELATIVE_PATHS,
CleanupPreset.CleanupStep.CONVERT_TO_BIBLATEX);
CleanupPreset.CleanupStep.CONVERT_TO_BIBLATEX,
CleanupPreset.CleanupStep.CONVERT_TO_BIBTEX);

CleanupPreset preset = new CleanupPreset(EnumSet.complementOf(deactivatedJobs), Cleanups.DEFAULT_SAVE_ACTIONS);

Expand All @@ -925,6 +927,7 @@ private static void insertDefaultCleanupPreset(Map<String, Object> storage) {
storage.put(CLEANUP_RENAME_PDF_ONLY_RELATIVE_PATHS, preset.isRenamePdfOnlyRelativePaths());
storage.put(CLEANUP_UPGRADE_EXTERNAL_LINKS, preset.isCleanUpUpgradeExternalLinks());
storage.put(CLEANUP_CONVERT_TO_BIBLATEX, preset.isConvertToBiblatex());
storage.put(CLEANUP_CONVERT_TO_BIBTEX, preset.isConvertToBibtex());
storage.put(CLEANUP_FIX_FILE_LINKS, preset.isFixFileLinks());
storage.put(CLEANUP_FORMATTERS, convertListToString(preset.getFormatterCleanups().getAsStringList(OS.NEWLINE)));
}
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/l10n/JabRef_en.properties
Original file line number Diff line number Diff line change
Expand Up @@ -1876,6 +1876,7 @@ value=value
Show\ preferences=Show preferences
Save\ actions=Save actions
Enable\ save\ actions=Enable save actions
Convert\ to\ BibTeX\ format\ (for\ example,\ move\ the\ value\ of\ the\ 'journaltitle'\ field\ to\ 'journal')=Convert to BibTeX format (for example, move the value of the 'journaltitle' field to 'journal')

Other\ fields=Other fields
Show\ remaining\ fields=Show remaining fields
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package org.jabref.logic.cleanup;

import org.jabref.model.entry.BibEntry;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

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

class BibtexBiblatexRoundtripTest {
private BibEntry bibtex;
private BibEntry biblatex;

@BeforeEach
void setUp() {
bibtex = new BibEntry("article");
bibtex.setField("author", "Frame, J. S. and Robinson, G. de B. and Thrall, R. M.");
bibtex.setField("title", "The hook graphs of the symmetric groups");
bibtex.setField("journal", "Canadian J. Math.");
bibtex.setField("fjournal", "Canadian Journal of Mathematics. Journal Canadien de Math\\'ematiques");
bibtex.setField("volume", "6");
bibtex.setField("year", "1954");
bibtex.setField("pages", "316--324");
bibtex.setField("issn", "0008-414X");
bibtex.setField("mrclass", "20.0X");
bibtex.setField("mrnumber", "0062127");
bibtex.setField("mrreviewer", "D. E. Littlewood");

biblatex = new BibEntry("article");
biblatex.setField("author", "Frame, J. S. and Robinson, G. de B. and Thrall, R. M.");
biblatex.setField("title", "The hook graphs of the symmetric groups");
biblatex.setField("journaltitle", "Canadian J. Math.");
biblatex.setField("fjournal", "Canadian Journal of Mathematics. Journal Canadien de Math\\'ematiques");
biblatex.setField("volume", "6");
biblatex.setField("date", "1954");
biblatex.setField("pages", "316--324");
biblatex.setField("issn", "0008-414X");
biblatex.setField("mrclass", "20.0X");
biblatex.setField("mrnumber", "0062127");
biblatex.setField("mrreviewer", "D. E. Littlewood");
}

@Test
void roundTripBibtexToBiblatexIsIdentity() {
BibEntry clone = (BibEntry) bibtex.clone();
new ConvertToBiblatexCleanup().cleanup(clone);
assertEquals(biblatex, clone);
new ConvertToBibtexCleanup().cleanup(clone);

assertEquals(bibtex, clone);
}

@Test
void roundTripBiblatexToBibtexIsIdentity() {
BibEntry clone = (BibEntry) biblatex.clone();
new ConvertToBibtexCleanup().cleanup(clone);
assertEquals(bibtex, clone);
new ConvertToBiblatexCleanup().cleanup(clone);

assertEquals(biblatex, clone);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,37 +9,49 @@
import org.junit.Before;
import org.junit.Test;

public class BiblatexCleanupTest {
public class ConvertToBiblatexCleanupTest {

private BiblatexCleanup worker;
private ConvertToBiblatexCleanup worker;

@Before
public void setUp() {
worker = new BiblatexCleanup();
worker = new ConvertToBiblatexCleanup();
}

@Test
public void convertToBiblatexMovesYearMonthToDate() {
public void cleanupMovesYearMonthToDate() {
BibEntry entry = new BibEntry();
entry.setField("year", "2011");
entry.setField("month", "#jan#");

worker.cleanup(entry);

Assert.assertEquals(Optional.empty(), entry.getField(FieldName.YEAR));
Assert.assertEquals(Optional.empty(), entry.getField(FieldName.MONTH));
Assert.assertEquals(Optional.of("2011-01"), entry.getField(FieldName.DATE));
}

@Test
public void convertToBiblatexDateAlreadyPresent() {
public void cleanupWithDateAlreadyPresentDoesNothing() {
BibEntry entry = new BibEntry();
entry.setField("year", "2011");
entry.setField("month", "#jan#");
entry.setField("date", "2012");

worker.cleanup(entry);

Assert.assertEquals(Optional.of("2011"), entry.getField(FieldName.YEAR));
Assert.assertEquals(Optional.of("#jan#"), entry.getField(FieldName.MONTH));
Assert.assertEquals(Optional.of("2012"), entry.getField(FieldName.DATE));
}

@Test
public void cleanupMovesJournalToJournaltitle() {
BibEntry entry = new BibEntry().withField("journal", "Best of JabRef");

worker.cleanup(entry);

Assert.assertEquals(Optional.empty(), entry.getField(FieldName.JOURNAL));
Assert.assertEquals(Optional.of("Best of JabRef"), entry.getField(FieldName.JOURNALTITLE));
}
}
Loading

0 comments on commit beb6ee0

Please sign in to comment.