diff --git a/src/main/java/net/sf/jabref/gui/actions/CleanUpAction.java b/src/main/java/net/sf/jabref/gui/actions/CleanUpAction.java
index 94cd4f0e4e7..6491ebe6d9e 100644
--- a/src/main/java/net/sf/jabref/gui/actions/CleanUpAction.java
+++ b/src/main/java/net/sf/jabref/gui/actions/CleanUpAction.java
@@ -41,6 +41,8 @@
import com.jgoodies.forms.builder.FormBuilder;
import com.jgoodies.forms.layout.FormLayout;
+import net.sf.jabref.logic.cleanup.PageNumbersCleanup;
+import net.sf.jabref.logic.formatter.FieldFormatters;
import net.sf.jabref.logic.l10n.Localization;
import net.sf.jabref.model.entry.BibtexEntry;
import net.sf.jabref.logic.util.DOI;
@@ -445,12 +447,12 @@ private static void doCleanUpMonth(BibtexEntry entry, NamedCompound ce) {
private static void doCleanUpPageNumbers(BibtexEntry entry, NamedCompound ce) {
String oldValue = entry.getField("pages");
- if (oldValue == null) {
- return;
- }
- String newValue = oldValue.replaceAll(" *(\\d+) *- *(\\d+) *", "$1--$2");
- if (!oldValue.equals(newValue)) {
- entry.setField("pages", newValue);
+ // run formatter
+ new PageNumbersCleanup(entry).cleanup();
+ // new value
+ String newValue = entry.getField("pages");
+ // undo action
+ if(!oldValue.equals(newValue)) {
ce.addEdit(new UndoableFieldChange(entry, "pages", oldValue, newValue));
}
}
diff --git a/src/main/java/net/sf/jabref/logic/cleanup/PageNumbersCleanup.java b/src/main/java/net/sf/jabref/logic/cleanup/PageNumbersCleanup.java
new file mode 100644
index 00000000000..7e7d197f1ba
--- /dev/null
+++ b/src/main/java/net/sf/jabref/logic/cleanup/PageNumbersCleanup.java
@@ -0,0 +1,30 @@
+package net.sf.jabref.logic.cleanup;
+
+import net.sf.jabref.logic.formatter.FieldFormatters;
+import net.sf.jabref.logic.formatter.PageNumbersFormatter;
+import net.sf.jabref.model.entry.BibtexEntry;
+
+/**
+ * This class includes sensible defaults for consistent formatting of BibTex page numbers.
+ */
+public class PageNumbersCleanup {
+ private BibtexEntry entry;
+
+ public PageNumbersCleanup(BibtexEntry entry) {
+ this.entry = entry;
+ }
+
+ /**
+ * Format page numbers, separated either by commas or double-hyphens.
+ * Converts the range number format of the pages field to page_number--page_number.
+ *
+ * @see{PageNumbersFormatter}
+ */
+ public void cleanup() {
+ final String field = "pages";
+
+ String value = entry.getField(field);
+ String newValue = FieldFormatters.PAGE_NUMBERS.format(value);
+ entry.setField(field, newValue);
+ }
+}
diff --git a/src/main/java/net/sf/jabref/logic/formatter/FieldFormatters.java b/src/main/java/net/sf/jabref/logic/formatter/FieldFormatters.java
new file mode 100644
index 00000000000..9957ebd5829
--- /dev/null
+++ b/src/main/java/net/sf/jabref/logic/formatter/FieldFormatters.java
@@ -0,0 +1,10 @@
+package net.sf.jabref.logic.formatter;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class FieldFormatters {
+ public static final PageNumbersFormatter PAGE_NUMBERS = new PageNumbersFormatter();
+
+ public static final List ALL = Arrays.asList(PAGE_NUMBERS);
+}
diff --git a/src/main/java/net/sf/jabref/logic/formatter/Formatter.java b/src/main/java/net/sf/jabref/logic/formatter/Formatter.java
new file mode 100644
index 00000000000..e55631184bd
--- /dev/null
+++ b/src/main/java/net/sf/jabref/logic/formatter/Formatter.java
@@ -0,0 +1,21 @@
+package net.sf.jabref.logic.formatter;
+
+/**
+ * Formatter Interface
+ */
+public interface Formatter {
+ /**
+ * Returns a human readable name of the formatter usable for e.g. in the GUI
+ *
+ * @return the name of the formatter
+ */
+ String getName();
+
+ /**
+ * Formats a field value by with a particular formatter transformation.
+ *
+ * @param value the input String
+ * @return the formatted output String
+ */
+ String format(String value);
+}
diff --git a/src/main/java/net/sf/jabref/logic/formatter/PageNumbersFormatter.java b/src/main/java/net/sf/jabref/logic/formatter/PageNumbersFormatter.java
new file mode 100644
index 00000000000..00f81e918b4
--- /dev/null
+++ b/src/main/java/net/sf/jabref/logic/formatter/PageNumbersFormatter.java
@@ -0,0 +1,51 @@
+package net.sf.jabref.logic.formatter;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * This class includes sensible defaults for consistent formatting of BibTex page numbers.
+ */
+public class PageNumbersFormatter implements Formatter {
+ @Override
+ public String getName() {
+ return "Page numbers";
+ }
+
+ /**
+ * Format page numbers, separated either by commas or double-hyphens.
+ * Converts the range number format of the pages field to page_number--page_number.
+ * Removes all literals except [0-9,-].
+ * Keeps the existing String if the resulting field does not match the expected Regex.
+ *
+ *
+ * 1-2 -> 1--2
+ * 1,2,3 -> 1,2,3
+ * {1}-{2} -> 1--2
+ * Invalid -> Invalid
+ *
+ */
+ public String format(String value) {
+ final String rejectLiterals = "[^0-9,-]";
+ final Pattern pagesPattern = Pattern.compile("\\A(\\d+)-{1,2}(\\d+)\\Z");
+ final String replace = "$1--$2";
+
+ // nothing to do
+ if (value == null || value.isEmpty()) {
+ return value;
+ }
+
+ // remove unwanted literals incl. whitespace
+ String cleanValue = value.replaceAll(rejectLiterals, "");
+ // try to find pages pattern
+ Matcher matcher = pagesPattern.matcher(cleanValue);
+ // replace
+ String newValue = matcher.replaceFirst(replace);
+ // replacement?
+ if(!newValue.equals(cleanValue)) {
+ // write field
+ return newValue;
+ }
+ return value;
+ }
+}
diff --git a/src/test/java/net/sf/jabref/logic/cleanup/PageNumbersCleanupTest.java b/src/test/java/net/sf/jabref/logic/cleanup/PageNumbersCleanupTest.java
new file mode 100644
index 00000000000..53ededba9ef
--- /dev/null
+++ b/src/test/java/net/sf/jabref/logic/cleanup/PageNumbersCleanupTest.java
@@ -0,0 +1,39 @@
+package net.sf.jabref.logic.cleanup;
+
+import junit.framework.Assert;
+import net.sf.jabref.model.entry.BibtexEntry;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class PageNumbersCleanupTest {
+ private BibtexEntry entry;
+
+ @Before
+ public void setUp() {
+ entry = new BibtexEntry();
+ }
+
+ @After
+ public void teardown() {
+ entry = null;
+ }
+
+ @Test
+ public void formatPageNumbers() {
+ entry.setField("pages", "1-2");
+ new PageNumbersCleanup(entry).cleanup();
+
+ Assert.assertEquals("1--2", entry.getField("pages"));
+ }
+
+ @Test
+ public void onlyFormatPageNumbersField() {
+ entry.setField("otherfield", "1-2");
+ new PageNumbersCleanup(entry).cleanup();
+
+ Assert.assertEquals("1-2", entry.getField("otherfield"));
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/net/sf/jabref/logic/formatter/PageNumbersFormatterTest.java b/src/test/java/net/sf/jabref/logic/formatter/PageNumbersFormatterTest.java
new file mode 100644
index 00000000000..d3decb3b106
--- /dev/null
+++ b/src/test/java/net/sf/jabref/logic/formatter/PageNumbersFormatterTest.java
@@ -0,0 +1,62 @@
+package net.sf.jabref.logic.formatter;
+
+import junit.framework.Assert;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class PageNumbersFormatterTest {
+ private PageNumbersFormatter formatter;
+
+ @Before
+ public void setUp() {
+ formatter = new PageNumbersFormatter();
+ }
+
+ @After
+ public void teardown() {
+ formatter = null;
+ }
+
+ @Test
+ public void formatPageNumbers() {
+ expectCorrect("1-2", "1--2");
+ }
+
+ @Test
+ public void formatPageNumbersCommaSeparated() {
+ expectCorrect("1,2,3", "1,2,3");
+ }
+
+ @Test
+ public void ignoreWhitespaceInPageNumbers() {
+ expectCorrect(" 1 - 2 ", "1--2");
+ }
+
+ @Test
+ public void keepCorrectlyFormattedPageNumbers() {
+ expectCorrect("1--2", "1--2");
+ }
+
+ @Test
+ public void formatPageNumbersEmptyFields() {
+ expectCorrect("", "");
+ expectCorrect(null, null);
+ }
+
+ @Test
+ public void formatPageNumbersRemoveUnexpectedLiterals() {
+ expectCorrect("{1}-{2}", "1--2");
+ }
+
+ @Test
+ public void formatPageNumbersRegexNotMatching() {
+ expectCorrect("12", "12");
+ }
+
+ private void expectCorrect(String input, String expected) {
+ Assert.assertEquals(expected, formatter.format(input));
+ }
+}
\ No newline at end of file