package org.jabref.logic.msbib;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import org.jabref.model.entry.BibEntry;
import org.jabref.model.entry.FieldName;
import org.jabref.model.entry.Month;
public class BibTeXConverter {
private static final String MSBIB_PREFIX = "msbib-";
private BibTeXConverter() {
}
/**
* Converts an {@link MSBibEntry} to a {@link BibEntry} for import
* @param entry The MsBibEntry to convert
* @return The bib entry
*/
public static BibEntry convert(MSBibEntry entry) {
BibEntry result;
Map<String, String> fieldValues = new HashMap<>();
String bibTexEntryType = MSBibMapping.getBiblatexEntryType(entry.getType());
result = new BibEntry(bibTexEntryType);
// add String fields
for (Map.Entry<String, String> field : entry.fields.entrySet()) {
String msField = field.getKey();
String value = field.getValue();
if ((value != null) && (MSBibMapping.getBibTeXField(msField) != null)) {
fieldValues.put(MSBibMapping.getBibTeXField(msField), value);
}
}
// Value must be converted
if (fieldValues.containsKey(FieldName.LANGUAGE)) {
int lcid = Integer.valueOf(fieldValues.get(FieldName.LANGUAGE));
fieldValues.put(FieldName.LANGUAGE, MSBibMapping.getLanguage(lcid));
}
addAuthor(fieldValues, FieldName.AUTHOR, entry.authors);
addAuthor(fieldValues, MSBIB_PREFIX + FieldName.BOOKAUTHOR, entry.bookAuthors);
addAuthor(fieldValues, FieldName.EDITOR, entry.editors);
addAuthor(fieldValues, MSBIB_PREFIX + FieldName.TRANSLATOR, entry.translators);
addAuthor(fieldValues, MSBIB_PREFIX + "producername", entry.producerNames);
addAuthor(fieldValues, MSBIB_PREFIX + "composer", entry.composers);
addAuthor(fieldValues, MSBIB_PREFIX + "conductor", entry.conductors);
addAuthor(fieldValues, MSBIB_PREFIX + "performer", entry.performers);
addAuthor(fieldValues, MSBIB_PREFIX + "writer", entry.writers);
addAuthor(fieldValues, MSBIB_PREFIX + "director", entry.directors);
addAuthor(fieldValues, MSBIB_PREFIX + "compiler", entry.compilers);
addAuthor(fieldValues, MSBIB_PREFIX + "interviewer", entry.interviewers);
addAuthor(fieldValues, MSBIB_PREFIX + "interviewee", entry.interviewees);
addAuthor(fieldValues, MSBIB_PREFIX + "inventor", entry.inventors);
addAuthor(fieldValues, MSBIB_PREFIX + "counsel", entry.counsels);
if (entry.pages != null) {
fieldValues.put(FieldName.PAGES, entry.pages.toString("--"));
}
parseStandardNumber(entry.standardNumber, fieldValues);
if (entry.address != null) {
fieldValues.put(FieldName.LOCATION, entry.address);
}
// TODO: ConferenceName is saved as booktitle when converting from MSBIB to BibTeX
if (entry.conferenceName != null) {
fieldValues.put(FieldName.ORGANIZATION, entry.conferenceName);
}
if (entry.dateAccessed != null) {
fieldValues.put(MSBIB_PREFIX + "accessed", entry.dateAccessed);
}
if (entry.journalName != null) {
fieldValues.put(FieldName.JOURNAL, entry.journalName);
}
if (entry.month != null) {
Optional<Month> month = Month.parse(entry.month);
month.ifPresent(parsedMonth -> result.setMonth(parsedMonth));
}
if (entry.number != null) {
fieldValues.put(FieldName.NUMBER, entry.number);
}
// set all fields
result.setField(fieldValues);
return result;
}
private static void addAuthor(Map<String, String> map, String type, List<MsBibAuthor> authors) {
if (authors == null) {
return;
}
String allAuthors = authors.stream().map(MsBibAuthor::getLastFirst).collect(Collectors.joining(" and "));
map.put(type, allAuthors);
}
private static void parseSingleStandardNumber(String type, String bibtype, String standardNum,
Map<String, String> map) {
Pattern pattern = Pattern.compile(':' + type + ":(.[^:]+)");
Matcher matcher = pattern.matcher(standardNum);
if (matcher.matches()) {
map.put(bibtype, matcher.group(1));
}
}
private static void parseStandardNumber(String standardNum, Map<String, String> map) {
if (standardNum == null) {
return;
}
parseSingleStandardNumber("ISBN", FieldName.ISBN, standardNum, map);
parseSingleStandardNumber("ISSN", FieldName.ISSN, standardNum, map);
parseSingleStandardNumber("LCCN", "lccn", standardNum, map);
parseSingleStandardNumber("MRN", "mrnumber", standardNum, map);
parseSingleStandardNumber("DOI", FieldName.DOI, standardNum, map);
}
}