From 2b790533f9a063b0f38e4acc27586d27865d23a1 Mon Sep 17 00:00:00 2001 From: Stefan Kolb Date: Thu, 29 Oct 2015 15:05:42 +0100 Subject: [PATCH] Extract and refactor CaseChangers --- .../sf/jabref/gui/actions/CleanUpAction.java | 1 - .../logic/cleanup/PageNumbersCleanup.java | 5 +- ...atters.java => BibtexFieldFormatters.java} | 4 +- .../jabref/logic/formatter/CaseChangers.java | 324 +----------------- .../PageNumbersFormatter.java | 4 +- .../casechanger/LowerCaseChanger.java | 23 ++ .../logic/formatter/casechanger/Title.java | 44 +++ .../casechanger/TitleCaseChanger.java | 35 ++ .../formatter/casechanger/TitleParser.java | 79 +++++ .../casechanger/UpperCaseChanger.java | 23 ++ .../UpperEachFirstCaseChanger.java | 23 ++ .../casechanger/UpperFirstCaseChanger.java | 24 ++ .../logic/formatter/casechanger/Word.java | 97 ++++++ .../logic/labelPattern/LabelPatternUtil.java | 5 +- .../formatter/PageNumbersFormatterTest.java | 3 +- 15 files changed, 362 insertions(+), 332 deletions(-) rename src/main/java/net/sf/jabref/logic/formatter/{FieldFormatters.java => BibtexFieldFormatters.java} (69%) rename src/main/java/net/sf/jabref/logic/formatter/{ => bibtexfields}/PageNumbersFormatter.java (93%) create mode 100644 src/main/java/net/sf/jabref/logic/formatter/casechanger/LowerCaseChanger.java create mode 100644 src/main/java/net/sf/jabref/logic/formatter/casechanger/Title.java create mode 100644 src/main/java/net/sf/jabref/logic/formatter/casechanger/TitleCaseChanger.java create mode 100644 src/main/java/net/sf/jabref/logic/formatter/casechanger/TitleParser.java create mode 100644 src/main/java/net/sf/jabref/logic/formatter/casechanger/UpperCaseChanger.java create mode 100644 src/main/java/net/sf/jabref/logic/formatter/casechanger/UpperEachFirstCaseChanger.java create mode 100644 src/main/java/net/sf/jabref/logic/formatter/casechanger/UpperFirstCaseChanger.java create mode 100644 src/main/java/net/sf/jabref/logic/formatter/casechanger/Word.java 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 e84754fc01d..a8bb6264a80 100644 --- a/src/main/java/net/sf/jabref/gui/actions/CleanUpAction.java +++ b/src/main/java/net/sf/jabref/gui/actions/CleanUpAction.java @@ -42,7 +42,6 @@ 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; diff --git a/src/main/java/net/sf/jabref/logic/cleanup/PageNumbersCleanup.java b/src/main/java/net/sf/jabref/logic/cleanup/PageNumbersCleanup.java index 7e7d197f1ba..3eafcb050c0 100644 --- a/src/main/java/net/sf/jabref/logic/cleanup/PageNumbersCleanup.java +++ b/src/main/java/net/sf/jabref/logic/cleanup/PageNumbersCleanup.java @@ -1,7 +1,6 @@ package net.sf.jabref.logic.cleanup; -import net.sf.jabref.logic.formatter.FieldFormatters; -import net.sf.jabref.logic.formatter.PageNumbersFormatter; +import net.sf.jabref.logic.formatter.BibtexFieldFormatters; import net.sf.jabref.model.entry.BibtexEntry; /** @@ -24,7 +23,7 @@ public void cleanup() { final String field = "pages"; String value = entry.getField(field); - String newValue = FieldFormatters.PAGE_NUMBERS.format(value); + String newValue = BibtexFieldFormatters.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/BibtexFieldFormatters.java similarity index 69% rename from src/main/java/net/sf/jabref/logic/formatter/FieldFormatters.java rename to src/main/java/net/sf/jabref/logic/formatter/BibtexFieldFormatters.java index 9957ebd5829..7e937970ea6 100644 --- a/src/main/java/net/sf/jabref/logic/formatter/FieldFormatters.java +++ b/src/main/java/net/sf/jabref/logic/formatter/BibtexFieldFormatters.java @@ -1,9 +1,11 @@ package net.sf.jabref.logic.formatter; +import net.sf.jabref.logic.formatter.bibtexfields.PageNumbersFormatter; + import java.util.Arrays; import java.util.List; -public class FieldFormatters { +public class BibtexFieldFormatters { 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/CaseChangers.java b/src/main/java/net/sf/jabref/logic/formatter/CaseChangers.java index f05c1b87f6b..86ef27195c7 100644 --- a/src/main/java/net/sf/jabref/logic/formatter/CaseChangers.java +++ b/src/main/java/net/sf/jabref/logic/formatter/CaseChangers.java @@ -17,8 +17,9 @@ */ package net.sf.jabref.logic.formatter; +import net.sf.jabref.logic.formatter.casechanger.*; + import java.util.*; -import java.util.stream.Collectors; /** * Class with static methods for changing the case of strings and arrays of strings. @@ -28,330 +29,11 @@ * This can be done by starting at the letter position and moving forward and backword to see if there is a '{' and '}, respectively. */ public class CaseChangers { - - public static final Set SMALLER_WORDS; - - static { - Set smallerWords = new HashSet<>(); - // NOTE: before JabRef 2.80, it was SKIP_WORDS = {"a", "an", "the", "for", "on", "of"}; in net.sf.jabref.logic.labelPattern.LabelPatternUtil.SKIP_WORDS - - // Articles - smallerWords.addAll(Arrays.asList("a", "an", "the")); - // Prepositions - smallerWords.addAll(Arrays.asList("above", "about", "across", "against", "along", "among", "around", "at", "before", "behind", "below", "beneath", "beside", "between", "beyond", "by", "down", "during", "except", "for", "from", "in", "inside", "into", "like", "near", "of", "off", "on", "onto", "since", "to", "toward", "through", "under", "until", "up", "upon", "with", "within", "without")); - // Conjunctions - smallerWords.addAll(Arrays.asList("and", "but", "for", "nor", "or", "so", "yet")); - - // unmodifiable for thread safety - SMALLER_WORDS = Collections.unmodifiableSet(smallerWords); - } - - /** - * Represents a word in a title of a bibtex entry. - *

- * A word can have protected chars (enclosed in '{' '}') and may be a small (a, an, the, ...) word. - */ - private static final class Word { - - private final char[] chars; - private final boolean[] protectedChars; - - public Word(char[] chars, boolean[] protectedChars) { - this.chars = Objects.requireNonNull(chars); - this.protectedChars = Objects.requireNonNull(protectedChars); - - if (this.chars.length != this.protectedChars.length) { - throw new IllegalArgumentException("the chars and the protectedChars array must be of same length"); - } - } - - /** - * Only change letters of the word that are unprotected to upper case. - */ - public void toUpperCase() { - for (int i = 0; i < chars.length; i++) { - if (protectedChars[i]) { - continue; - } - - chars[i] = Character.toUpperCase(chars[i]); - } - } - - /** - * Only change letters of the word that are unprotected to lower case. - */ - public void toLowerCase() { - for (int i = 0; i < chars.length; i++) { - if (protectedChars[i]) { - continue; - } - - chars[i] = Character.toLowerCase(chars[i]); - } - } - - - public void toUpperFirst() { - for (int i = 0; i < chars.length; i++) { - if (protectedChars[i]) { - continue; - } - - if (i == 0) { - chars[i] = Character.toUpperCase(chars[i]); - } else { - chars[i] = Character.toLowerCase(chars[i]); - } - } - } - - public boolean isSmallerWord() { - // "word:" is still a small "word" - return SMALLER_WORDS.contains(this.toString().replaceAll("[:]", "").toLowerCase()); - } - - public boolean isLargerWord() { - return !isSmallerWord(); - } - - @Override - public String toString() { - return new String(chars); - } - - public boolean endsWithColon() { - return this.toString().endsWith(":"); - } - } - - /** - * Parses a title to a list of words. - */ - private static final class TitleParser { - - private StringBuffer buffer; - private int wordStart; - - public List parse(String title) { - List words = new LinkedList<>(); - - boolean[] isProtected = determineProtectedChars(title); - - reset(); - - int index = 0; - for (char c : title.toCharArray()) { - if (!Character.isWhitespace(c)) { - if (wordStart == -1) { - wordStart = index; - } - - buffer.append(c); - } else { - createWord(isProtected).ifPresent(words::add); - } - - index++; - } - createWord(isProtected).ifPresent(words::add); - - return words; - } - - private Optional createWord(boolean[] isProtected) { - if (buffer.length() <= 0) { - return Optional.empty(); - } - - char[] chars = buffer.toString().toCharArray(); - boolean[] protectedChars = new boolean[chars.length]; - - System.arraycopy(isProtected, wordStart, protectedChars, 0, chars.length); - - reset(); - - return Optional.of(new Word(chars, protectedChars)); - } - - private void reset() { - wordStart = -1; - buffer = new StringBuffer(); - } - - private static boolean[] determineProtectedChars(String title) { - boolean[] isProtected = new boolean[title.length()]; - char[] chars = title.toCharArray(); - - int brakets = 0; - for (int i = 0; i < title.length(); i++) { - if (chars[i] == '{') { - brakets++; - } else if (chars[i] == '}') { - brakets--; - } else { - isProtected[i] = brakets > 0; - } - } - - return isProtected; - } - - } - - /** - * Represents a title of a bibtex entry. - */ - private static final class Title { - - private final List words = new LinkedList<>(); - - public Title(String title) { - this.words.addAll(new TitleParser().parse(title)); - } - - public List getWords() { - return words; - } - - public Optional getFirstWord() { - if (getWords().isEmpty()) { - return Optional.empty(); - } - return Optional.of(getWords().get(0)); - } - - public Optional getLastWord() { - if (getWords().isEmpty()) { - return Optional.empty(); - } - return Optional.of(getWords().get(getWords().size() - 1)); - } - - @Override - public String toString() { - return words.stream().map(Word::toString).collect(Collectors.joining(" ")); - } - - } - - public static class LowerCaseChanger implements Formatter { - - @Override - public String getName() { - return "lower"; - } - - /** - * Converts all characters of the string to lower case, but does not change words starting with "{" - */ - @Override - public String format(String input) { - Title title = new Title(input); - - title.getWords().stream().forEach(Word::toLowerCase); - - return title.toString(); - } - } - - public static class UpperCaseChanger implements Formatter { - - @Override - public String getName() { - return "UPPER"; - } - - /** - * Converts all characters of the given string to upper case, but does not change words starting with "{" - */ - @Override - public String format(String input) { - Title title = new Title(input); - - title.getWords().stream().forEach(Word::toUpperCase); - - return title.toString(); - } - } - - public static class UpperFirstCaseChanger implements Formatter { - - @Override - public String getName() { - return "Upper first"; - } - - /** - * Converts the first character of the first word of the given string to a upper case (and the remaining characters of the first word to lower case), but does not change anything if word starts with "{" - */ - @Override - public String format(String input) { - Title title = new Title(LOWER.format(input)); - - title.getWords().stream().findFirst().ifPresent(Word::toUpperFirst); - - return title.toString(); - } - } - - public static class UpperEachFirstCaseChanger implements Formatter { - - @Override - public String getName() { - return "Upper Each First"; - } - - /** - * Converts the first character of each word of the given string to a upper case (and all others to lower case), but does not change words starting with "{" - */ - @Override - public String format(String input) { - Title title = new Title(input); - - title.getWords().stream().forEach(Word::toUpperFirst); - - return title.toString(); - } - } - - public static class TitleCaseChanger implements Formatter { - - @Override - public String getName() { - return "Title"; - } - - /** - * Converts all words to upper case, but converts articles, prepositions, and conjunctions to lower case - * Capitalizes first and last word - * Does not change words starting with "{" - */ - @Override - public String format(String input) { - Title title = new Title(input); - - title.getWords().stream().filter(Word::isSmallerWord).forEach(Word::toLowerCase); - title.getWords().stream().filter(Word::isLargerWord).forEach(Word::toUpperFirst); - - title.getFirstWord().ifPresent(Word::toUpperFirst); - title.getLastWord().ifPresent(Word::toUpperFirst); - - for (int i = 0; i < (title.getWords().size() - 2); i++) { - if (title.getWords().get(i).endsWithColon()) { - title.getWords().get(i + 1).toUpperFirst(); - } - } - - return title.toString(); - } - } - public static final LowerCaseChanger LOWER = new LowerCaseChanger(); public static final UpperCaseChanger UPPER = new UpperCaseChanger(); public static final UpperFirstCaseChanger UPPER_FIRST = new UpperFirstCaseChanger(); public static final UpperEachFirstCaseChanger UPPER_EACH_FIRST = new UpperEachFirstCaseChanger(); public static final TitleCaseChanger TITLE = new TitleCaseChanger(); - public static final List ALL = Arrays.asList(CaseChangers.LOWER, CaseChangers.UPPER, CaseChangers.UPPER_FIRST, CaseChangers.UPPER_EACH_FIRST, CaseChangers.TITLE); + public static final List ALL = Arrays.asList(LOWER, UPPER, UPPER_FIRST, UPPER_EACH_FIRST, TITLE); } diff --git a/src/main/java/net/sf/jabref/logic/formatter/PageNumbersFormatter.java b/src/main/java/net/sf/jabref/logic/formatter/bibtexfields/PageNumbersFormatter.java similarity index 93% rename from src/main/java/net/sf/jabref/logic/formatter/PageNumbersFormatter.java rename to src/main/java/net/sf/jabref/logic/formatter/bibtexfields/PageNumbersFormatter.java index 00f81e918b4..f2ec06fb228 100644 --- a/src/main/java/net/sf/jabref/logic/formatter/PageNumbersFormatter.java +++ b/src/main/java/net/sf/jabref/logic/formatter/bibtexfields/PageNumbersFormatter.java @@ -1,4 +1,6 @@ -package net.sf.jabref.logic.formatter; +package net.sf.jabref.logic.formatter.bibtexfields; + +import net.sf.jabref.logic.formatter.Formatter; import java.util.regex.Matcher; import java.util.regex.Pattern; diff --git a/src/main/java/net/sf/jabref/logic/formatter/casechanger/LowerCaseChanger.java b/src/main/java/net/sf/jabref/logic/formatter/casechanger/LowerCaseChanger.java new file mode 100644 index 00000000000..36e234ecd26 --- /dev/null +++ b/src/main/java/net/sf/jabref/logic/formatter/casechanger/LowerCaseChanger.java @@ -0,0 +1,23 @@ +package net.sf.jabref.logic.formatter.casechanger; + +import net.sf.jabref.logic.formatter.Formatter; + +public class LowerCaseChanger implements Formatter { + + @Override + public String getName() { + return "lower"; + } + + /** + * Converts all characters of the string to lower case, but does not change words starting with "{" + */ + @Override + public String format(String input) { + Title title = new Title(input); + + title.getWords().stream().forEach(Word::toLowerCase); + + return title.toString(); + } +} diff --git a/src/main/java/net/sf/jabref/logic/formatter/casechanger/Title.java b/src/main/java/net/sf/jabref/logic/formatter/casechanger/Title.java new file mode 100644 index 00000000000..7855171a520 --- /dev/null +++ b/src/main/java/net/sf/jabref/logic/formatter/casechanger/Title.java @@ -0,0 +1,44 @@ +package net.sf.jabref.logic.formatter.casechanger; + +import net.sf.jabref.logic.formatter.CaseChangers; + +import java.util.LinkedList; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +/** + * Represents a title of a bibtex entry. + */ +public final class Title { + + private final List words = new LinkedList<>(); + + public Title(String title) { + this.words.addAll(new TitleParser().parse(title)); + } + + public List getWords() { + return words; + } + + public Optional getFirstWord() { + if (getWords().isEmpty()) { + return Optional.empty(); + } + return Optional.of(getWords().get(0)); + } + + public Optional getLastWord() { + if (getWords().isEmpty()) { + return Optional.empty(); + } + return Optional.of(getWords().get(getWords().size() - 1)); + } + + @Override + public String toString() { + return words.stream().map(Word::toString).collect(Collectors.joining(" ")); + } + +} diff --git a/src/main/java/net/sf/jabref/logic/formatter/casechanger/TitleCaseChanger.java b/src/main/java/net/sf/jabref/logic/formatter/casechanger/TitleCaseChanger.java new file mode 100644 index 00000000000..6a6411fe52c --- /dev/null +++ b/src/main/java/net/sf/jabref/logic/formatter/casechanger/TitleCaseChanger.java @@ -0,0 +1,35 @@ +package net.sf.jabref.logic.formatter.casechanger; + +import net.sf.jabref.logic.formatter.Formatter; + +public class TitleCaseChanger implements Formatter { + + @Override + public String getName() { + return "Title"; + } + + /** + * Converts all words to upper case, but converts articles, prepositions, and conjunctions to lower case + * Capitalizes first and last word + * Does not change words starting with "{" + */ + @Override + public String format(String input) { + Title title = new Title(input); + + title.getWords().stream().filter(Word::isSmallerWord).forEach(Word::toLowerCase); + title.getWords().stream().filter(Word::isLargerWord).forEach(Word::toUpperFirst); + + title.getFirstWord().ifPresent(Word::toUpperFirst); + title.getLastWord().ifPresent(Word::toUpperFirst); + + for (int i = 0; i < (title.getWords().size() - 2); i++) { + if (title.getWords().get(i).endsWithColon()) { + title.getWords().get(i + 1).toUpperFirst(); + } + } + + return title.toString(); + } +} diff --git a/src/main/java/net/sf/jabref/logic/formatter/casechanger/TitleParser.java b/src/main/java/net/sf/jabref/logic/formatter/casechanger/TitleParser.java new file mode 100644 index 00000000000..c13dded1c0a --- /dev/null +++ b/src/main/java/net/sf/jabref/logic/formatter/casechanger/TitleParser.java @@ -0,0 +1,79 @@ +package net.sf.jabref.logic.formatter.casechanger; + +import java.util.LinkedList; +import java.util.List; +import java.util.Optional; + +/** + * Parses a title to a list of words. + */ +public final class TitleParser { + + private StringBuffer buffer; + private int wordStart; + + public List parse(String title) { + List words = new LinkedList<>(); + + boolean[] isProtected = determineProtectedChars(title); + + reset(); + + int index = 0; + for (char c : title.toCharArray()) { + if (!Character.isWhitespace(c)) { + if (wordStart == -1) { + wordStart = index; + } + + buffer.append(c); + } else { + createWord(isProtected).ifPresent(words::add); + } + + index++; + } + createWord(isProtected).ifPresent(words::add); + + return words; + } + + private Optional createWord(boolean[] isProtected) { + if (buffer.length() <= 0) { + return Optional.empty(); + } + + char[] chars = buffer.toString().toCharArray(); + boolean[] protectedChars = new boolean[chars.length]; + + System.arraycopy(isProtected, wordStart, protectedChars, 0, chars.length); + + reset(); + + return Optional.of(new Word(chars, protectedChars)); + } + + private void reset() { + wordStart = -1; + buffer = new StringBuffer(); + } + + private static boolean[] determineProtectedChars(String title) { + boolean[] isProtected = new boolean[title.length()]; + char[] chars = title.toCharArray(); + + int brakets = 0; + for (int i = 0; i < title.length(); i++) { + if (chars[i] == '{') { + brakets++; + } else if (chars[i] == '}') { + brakets--; + } else { + isProtected[i] = brakets > 0; + } + } + + return isProtected; + } + +} diff --git a/src/main/java/net/sf/jabref/logic/formatter/casechanger/UpperCaseChanger.java b/src/main/java/net/sf/jabref/logic/formatter/casechanger/UpperCaseChanger.java new file mode 100644 index 00000000000..858fde25f18 --- /dev/null +++ b/src/main/java/net/sf/jabref/logic/formatter/casechanger/UpperCaseChanger.java @@ -0,0 +1,23 @@ +package net.sf.jabref.logic.formatter.casechanger; + +import net.sf.jabref.logic.formatter.Formatter; + +public class UpperCaseChanger implements Formatter { + + @Override + public String getName() { + return "UPPER"; + } + + /** + * Converts all characters of the given string to upper case, but does not change words starting with "{" + */ + @Override + public String format(String input) { + Title title = new Title(input); + + title.getWords().stream().forEach(Word::toUpperCase); + + return title.toString(); + } +} diff --git a/src/main/java/net/sf/jabref/logic/formatter/casechanger/UpperEachFirstCaseChanger.java b/src/main/java/net/sf/jabref/logic/formatter/casechanger/UpperEachFirstCaseChanger.java new file mode 100644 index 00000000000..d3ae3496c1c --- /dev/null +++ b/src/main/java/net/sf/jabref/logic/formatter/casechanger/UpperEachFirstCaseChanger.java @@ -0,0 +1,23 @@ +package net.sf.jabref.logic.formatter.casechanger; + +import net.sf.jabref.logic.formatter.Formatter; + +public class UpperEachFirstCaseChanger implements Formatter { + + @Override + public String getName() { + return "Upper Each First"; + } + + /** + * Converts the first character of each word of the given string to a upper case (and all others to lower case), but does not change words starting with "{" + */ + @Override + public String format(String input) { + Title title = new Title(input); + + title.getWords().stream().forEach(Word::toUpperFirst); + + return title.toString(); + } +} diff --git a/src/main/java/net/sf/jabref/logic/formatter/casechanger/UpperFirstCaseChanger.java b/src/main/java/net/sf/jabref/logic/formatter/casechanger/UpperFirstCaseChanger.java new file mode 100644 index 00000000000..68ed95a54a0 --- /dev/null +++ b/src/main/java/net/sf/jabref/logic/formatter/casechanger/UpperFirstCaseChanger.java @@ -0,0 +1,24 @@ +package net.sf.jabref.logic.formatter.casechanger; + +import net.sf.jabref.logic.formatter.CaseChangers; +import net.sf.jabref.logic.formatter.Formatter; + +public class UpperFirstCaseChanger implements Formatter { + + @Override + public String getName() { + return "Upper first"; + } + + /** + * Converts the first character of the first word of the given string to a upper case (and the remaining characters of the first word to lower case), but does not change anything if word starts with "{" + */ + @Override + public String format(String input) { + Title title = new Title(CaseChangers.LOWER.format(input)); + + title.getWords().stream().findFirst().ifPresent(Word::toUpperFirst); + + return title.toString(); + } +} diff --git a/src/main/java/net/sf/jabref/logic/formatter/casechanger/Word.java b/src/main/java/net/sf/jabref/logic/formatter/casechanger/Word.java new file mode 100644 index 00000000000..c98f638b35f --- /dev/null +++ b/src/main/java/net/sf/jabref/logic/formatter/casechanger/Word.java @@ -0,0 +1,97 @@ +package net.sf.jabref.logic.formatter.casechanger; + +import java.util.*; + +/** + * Represents a word in a title of a bibtex entry. + *

+ * A word can have protected chars (enclosed in '{' '}') and may be a small (a, an, the, ...) word. + */ +public final class Word { + public static final Set SMALLER_WORDS; + + static { + Set smallerWords = new HashSet<>(); + + // Articles + smallerWords.addAll(Arrays.asList("a", "an", "the")); + // Prepositions + smallerWords.addAll(Arrays.asList("above", "about", "across", "against", "along", "among", "around", "at", "before", "behind", "below", "beneath", "beside", "between", "beyond", "by", "down", "during", "except", "for", "from", "in", "inside", "into", "like", "near", "of", "off", "on", "onto", "since", "to", "toward", "through", "under", "until", "up", "upon", "with", "within", "without")); + // Conjunctions + smallerWords.addAll(Arrays.asList("and", "but", "for", "nor", "or", "so", "yet")); + + // unmodifiable for thread safety + SMALLER_WORDS = Collections.unmodifiableSet(smallerWords); + } + + private final char[] chars; + private final boolean[] protectedChars; + + public Word(char[] chars, boolean[] protectedChars) { + this.chars = Objects.requireNonNull(chars); + this.protectedChars = Objects.requireNonNull(protectedChars); + + if (this.chars.length != this.protectedChars.length) { + throw new IllegalArgumentException("the chars and the protectedChars array must be of same length"); + } + } + + /** + * Only change letters of the word that are unprotected to upper case. + */ + public void toUpperCase() { + for (int i = 0; i < chars.length; i++) { + if (protectedChars[i]) { + continue; + } + + chars[i] = Character.toUpperCase(chars[i]); + } + } + + /** + * Only change letters of the word that are unprotected to lower case. + */ + public void toLowerCase() { + for (int i = 0; i < chars.length; i++) { + if (protectedChars[i]) { + continue; + } + + chars[i] = Character.toLowerCase(chars[i]); + } + } + + + public void toUpperFirst() { + for (int i = 0; i < chars.length; i++) { + if (protectedChars[i]) { + continue; + } + + if (i == 0) { + chars[i] = Character.toUpperCase(chars[i]); + } else { + chars[i] = Character.toLowerCase(chars[i]); + } + } + } + + public boolean isSmallerWord() { + // "word:" is still a small "word" + return SMALLER_WORDS.contains(this.toString().replaceAll("[:]", "").toLowerCase()); + } + + public boolean isLargerWord() { + return !isSmallerWord(); + } + + @Override + public String toString() { + return new String(chars); + } + + public boolean endsWithColon() { + return this.toString().endsWith(":"); + } +} diff --git a/src/main/java/net/sf/jabref/logic/labelPattern/LabelPatternUtil.java b/src/main/java/net/sf/jabref/logic/labelPattern/LabelPatternUtil.java index 3282139b5e4..d7241c3826a 100644 --- a/src/main/java/net/sf/jabref/logic/labelPattern/LabelPatternUtil.java +++ b/src/main/java/net/sf/jabref/logic/labelPattern/LabelPatternUtil.java @@ -24,6 +24,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +import net.sf.jabref.logic.formatter.casechanger.Word; import net.sf.jabref.model.entry.AuthorList; import net.sf.jabref.model.database.BibtexDatabase; import net.sf.jabref.model.entry.BibtexEntry; @@ -32,7 +33,6 @@ import net.sf.jabref.*; import net.sf.jabref.exporter.layout.format.RemoveLatexCommands; -import net.sf.jabref.logic.formatter.CaseChangers; import net.sf.jabref.util.Util; /** @@ -830,7 +830,6 @@ static String getTitleWords(int number, String title) { && ss.charAt(piv) != '-') { current.append(ss.charAt(piv)); piv++; - //System.out.println(".. "+piv+" '"+current.toString()+"'"); } piv++; // Check if it is ok: @@ -838,7 +837,7 @@ static String getTitleWords(int number, String title) { if (word.isEmpty()) { continue; } - for (String smallWord: CaseChangers.SMALLER_WORDS) { + for (String smallWord: Word.SMALLER_WORDS) { if (word.equalsIgnoreCase(smallWord)) { continue mainl; } diff --git a/src/test/java/net/sf/jabref/logic/formatter/PageNumbersFormatterTest.java b/src/test/java/net/sf/jabref/logic/formatter/PageNumbersFormatterTest.java index d3decb3b106..e48dcd982a0 100644 --- a/src/test/java/net/sf/jabref/logic/formatter/PageNumbersFormatterTest.java +++ b/src/test/java/net/sf/jabref/logic/formatter/PageNumbersFormatterTest.java @@ -1,12 +1,11 @@ package net.sf.jabref.logic.formatter; import junit.framework.Assert; +import net.sf.jabref.logic.formatter.bibtexfields.PageNumbersFormatter; import org.junit.After; import org.junit.Before; import org.junit.Test; -import static org.junit.Assert.*; - public class PageNumbersFormatterTest { private PageNumbersFormatter formatter;