package org.jabref.logic.cleanup;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.jabref.logic.formatter.Formatters;
import org.jabref.logic.formatter.IdentityFormatter;
import org.jabref.logic.formatter.bibtexfields.HtmlToLatexFormatter;
import org.jabref.logic.formatter.bibtexfields.HtmlToUnicodeFormatter;
import org.jabref.logic.formatter.bibtexfields.NormalizeDateFormatter;
import org.jabref.logic.formatter.bibtexfields.NormalizeMonthFormatter;
import org.jabref.logic.formatter.bibtexfields.NormalizePagesFormatter;
import org.jabref.logic.formatter.bibtexfields.OrdinalsToSuperscriptFormatter;
import org.jabref.logic.formatter.bibtexfields.UnicodeToLatexFormatter;
import org.jabref.logic.layout.format.LatexToUnicodeFormatter;
import org.jabref.model.cleanup.FieldFormatterCleanup;
import org.jabref.model.cleanup.FieldFormatterCleanups;
import org.jabref.model.cleanup.Formatter;
import org.jabref.model.entry.FieldName;
import org.jabref.model.strings.StringUtil;
public class Cleanups {
public static final FieldFormatterCleanups DEFAULT_SAVE_ACTIONS;
public static final FieldFormatterCleanups RECOMMEND_BIBTEX_ACTIONS;
public static final FieldFormatterCleanups RECOMMEND_BIBLATEX_ACTIONS;
public static List<Formatter> availableFormatters;
static {
availableFormatters = new ArrayList<>();
availableFormatters.addAll(Formatters.ALL);
List<FieldFormatterCleanup> defaultFormatters = new ArrayList<>();
defaultFormatters.add(new FieldFormatterCleanup(FieldName.PAGES, new NormalizePagesFormatter()));
defaultFormatters.add(new FieldFormatterCleanup(FieldName.DATE, new NormalizeDateFormatter()));
defaultFormatters.add(new FieldFormatterCleanup(FieldName.MONTH, new NormalizeMonthFormatter()));
DEFAULT_SAVE_ACTIONS = new FieldFormatterCleanups(false, defaultFormatters);
List<FieldFormatterCleanup> recommendedBibTeXFormatters = new ArrayList<>();
recommendedBibTeXFormatters.addAll(defaultFormatters);
recommendedBibTeXFormatters.add(new FieldFormatterCleanup(FieldName.TITLE, new HtmlToLatexFormatter()));
recommendedBibTeXFormatters.add(new FieldFormatterCleanup(FieldName.TITLE, new UnicodeToLatexFormatter()));
recommendedBibTeXFormatters.add(new FieldFormatterCleanup(FieldName.BOOKTITLE, new UnicodeToLatexFormatter()));
recommendedBibTeXFormatters.add(new FieldFormatterCleanup(FieldName.JOURNAL, new UnicodeToLatexFormatter()));
recommendedBibTeXFormatters.add(new FieldFormatterCleanup(FieldName.AUTHOR, new UnicodeToLatexFormatter()));
recommendedBibTeXFormatters.add(new FieldFormatterCleanup(FieldName.EDITOR, new UnicodeToLatexFormatter()));
recommendedBibTeXFormatters.add(new FieldFormatterCleanup(FieldName.INTERNAL_ALL_TEXT_FIELDS_FIELD, new OrdinalsToSuperscriptFormatter()));
RECOMMEND_BIBTEX_ACTIONS = new FieldFormatterCleanups(false, recommendedBibTeXFormatters);
List<FieldFormatterCleanup> recommendedBiblatexFormatters = new ArrayList<>();
recommendedBiblatexFormatters.addAll(defaultFormatters);
recommendedBiblatexFormatters.add(new FieldFormatterCleanup(FieldName.TITLE, new HtmlToUnicodeFormatter()));
recommendedBiblatexFormatters.add(new FieldFormatterCleanup(FieldName.INTERNAL_ALL_TEXT_FIELDS_FIELD, new LatexToUnicodeFormatter()));
RECOMMEND_BIBLATEX_ACTIONS = new FieldFormatterCleanups(false, recommendedBiblatexFormatters);
}
private Cleanups() {
}
public static List<Formatter> getAvailableFormatters() {
return Collections.unmodifiableList(availableFormatters);
}
public static List<FieldFormatterCleanup> parse(String formatterString) {
if ((formatterString == null) || formatterString.isEmpty()) {
// no save actions defined in the meta data
return new ArrayList<>();
}
List<FieldFormatterCleanup> actions = new ArrayList<>();
//read concrete actions
int startIndex = 0;
// first remove all newlines for easier parsing
String remainingString = formatterString;
remainingString = StringUtil.unifyLineBreaks(remainingString, "");
try {
while (startIndex < formatterString.length()) {
// read the field name
int currentIndex = remainingString.indexOf('[');
String fieldKey = remainingString.substring(0, currentIndex);
int endIndex = remainingString.indexOf(']');
startIndex += endIndex + 1;
//read each formatter
int tokenIndex = remainingString.indexOf(',');
do {
boolean doBreak = false;
if ((tokenIndex == -1) || (tokenIndex > endIndex)) {
tokenIndex = remainingString.indexOf(']');
doBreak = true;
}
String formatterKey = remainingString.substring(currentIndex + 1, tokenIndex);
actions.add(new FieldFormatterCleanup(fieldKey, getFormatterFromString(formatterKey)));
remainingString = remainingString.substring(tokenIndex + 1);
if (remainingString.startsWith("]") || doBreak) {
break;
}
tokenIndex = remainingString.indexOf(',');
currentIndex = -1;
} while (true);
}
} catch (StringIndexOutOfBoundsException ignore) {
// if this exception occurs, the remaining part of the save actions string is invalid.
// Thus we stop parsing and take what we have parsed until now
return actions;
}
return actions;
}
public static FieldFormatterCleanups parse(List<String> formatterMetaList) {
if ((formatterMetaList != null) && (formatterMetaList.size() >= 2)) {
boolean enablementStatus = FieldFormatterCleanups.ENABLED.equals(formatterMetaList.get(0));
String formatterString = formatterMetaList.get(1);
return new FieldFormatterCleanups(enablementStatus, parse(formatterString));
} else {
// return default actions
return DEFAULT_SAVE_ACTIONS;
}
}
private static Formatter getFormatterFromString(String formatterName) {
for (Formatter formatter : availableFormatters) {
if (formatterName.equals(formatter.getKey())) {
return formatter;
}
}
return new IdentityFormatter();
}
}