use of org.jabref.logic.openoffice.UndefinedBibtexEntry in project jabref by JabRef.
the class OOBibBase method insertFullReferenceAtCursor.
private void insertFullReferenceAtCursor(XTextCursor cursor, Map<BibEntry, BibDatabase> entries, OOBibStyle style, String parFormat) throws UndefinedParagraphFormatException, IllegalArgumentException, UnknownPropertyException, PropertyVetoException, WrappedTargetException {
Map<BibEntry, BibDatabase> correctEntries;
// If we don't have numbered entries, we need to sort the entries before adding them:
if (style.isSortByPosition()) {
// Use the received map directly
correctEntries = entries;
} else {
// Sort map
Map<BibEntry, BibDatabase> newMap = new TreeMap<>(entryComparator);
newMap.putAll(entries);
correctEntries = newMap;
}
int number = 1;
for (Map.Entry<BibEntry, BibDatabase> entry : correctEntries.entrySet()) {
if (entry.getKey() instanceof UndefinedBibtexEntry) {
continue;
}
OOUtil.insertParagraphBreak(text, cursor);
if (style.isNumberEntries()) {
int minGroupingCount = style.getIntCitProperty(OOBibStyle.MINIMUM_GROUPING_COUNT);
OOUtil.insertTextAtCurrentLocation(text, cursor, style.getNumCitationMarker(Collections.singletonList(number++), minGroupingCount, true), Collections.emptyList());
}
Layout layout = style.getReferenceFormat(entry.getKey().getType());
layout.setPostFormatter(POSTFORMATTER);
OOUtil.insertFullReferenceAtCurrentLocation(text, cursor, layout, parFormat, entry.getKey(), entry.getValue(), uniquefiers.get(entry.getKey().getCiteKeyOptional().orElse(null)));
}
}
use of org.jabref.logic.openoffice.UndefinedBibtexEntry in project jabref by JabRef.
the class OOBibBase method getSortedEntriesFromSortedRefMarks.
private Map<BibEntry, BibDatabase> getSortedEntriesFromSortedRefMarks(List<String> names, Map<String, BibDatabase> linkSourceBase) {
Map<BibEntry, BibDatabase> newList = new LinkedHashMap<>();
for (String name : names) {
Matcher citeMatcher = CITE_PATTERN.matcher(name);
if (citeMatcher.find()) {
String[] keys = citeMatcher.group(2).split(",");
for (String key : keys) {
BibDatabase database = linkSourceBase.get(key);
Optional<BibEntry> origEntry = Optional.empty();
if (database != null) {
origEntry = database.getEntryByKey(key);
}
if (origEntry.isPresent()) {
if (!newList.containsKey(origEntry.get())) {
newList.put(origEntry.get(), database);
}
} else {
LOGGER.info("BibTeX key not found: '" + key + "'");
LOGGER.info("Problem with reference mark: '" + name + "'");
newList.put(new UndefinedBibtexEntry(key), null);
}
}
}
}
return newList;
}
use of org.jabref.logic.openoffice.UndefinedBibtexEntry in project jabref by JabRef.
the class OOBibBase method refreshCiteMarkersInternal.
private List<String> refreshCiteMarkersInternal(List<BibDatabase> databases, OOBibStyle style) throws WrappedTargetException, IllegalArgumentException, NoSuchElementException, UndefinedCharacterFormatException, UnknownPropertyException, PropertyVetoException, CreationException, BibEntryNotFoundException {
List<String> cited = findCitedKeys();
Map<String, BibDatabase> linkSourceBase = new HashMap<>();
Map<BibEntry, BibDatabase> entries = findCitedEntries(databases, cited, linkSourceBase);
XNameAccess xReferenceMarks = getReferenceMarks();
List<String> names;
if (style.isSortByPosition()) {
// We need to sort the reference marks according to their order of appearance:
names = sortedReferenceMarks;
} else if (style.isNumberEntries()) {
// We need to sort the reference marks according to the sorting of the bibliographic
// entries:
SortedMap<BibEntry, BibDatabase> newMap = new TreeMap<>(entryComparator);
for (Map.Entry<BibEntry, BibDatabase> bibtexEntryBibtexDatabaseEntry : entries.entrySet()) {
newMap.put(bibtexEntryBibtexDatabaseEntry.getKey(), bibtexEntryBibtexDatabaseEntry.getValue());
}
entries = newMap;
// Rebuild the list of cited keys according to the sort order:
cited.clear();
for (BibEntry entry : entries.keySet()) {
cited.add(entry.getCiteKeyOptional().orElse(null));
}
names = Arrays.asList(xReferenceMarks.getElementNames());
} else {
names = sortedReferenceMarks;
}
// Remove all reference marks that don't look like JabRef citations:
List<String> tmp = new ArrayList<>();
for (String name : names) {
if (CITE_PATTERN.matcher(name).find()) {
tmp.add(name);
}
}
names = tmp;
Map<String, Integer> numbers = new HashMap<>();
int lastNum = 0;
// First compute citation markers for all citations:
String[] citMarkers = new String[names.size()];
String[][] normCitMarkers = new String[names.size()][];
String[][] bibtexKeys = new String[names.size()][];
int minGroupingCount = style.getIntCitProperty(OOBibStyle.MINIMUM_GROUPING_COUNT);
int[] types = new int[names.size()];
for (int i = 0; i < names.size(); i++) {
Matcher citeMatcher = CITE_PATTERN.matcher(names.get(i));
if (citeMatcher.find()) {
String typeStr = citeMatcher.group(1);
int type = Integer.parseInt(typeStr);
// Remember the type in case we need to uniquefy.
types[i] = type;
String[] keys = citeMatcher.group(2).split(",");
bibtexKeys[i] = keys;
BibEntry[] cEntries = new BibEntry[keys.length];
for (int j = 0; j < cEntries.length; j++) {
BibDatabase database = linkSourceBase.get(keys[j]);
Optional<BibEntry> tmpEntry = Optional.empty();
if (database != null) {
tmpEntry = database.getEntryByKey(keys[j]);
}
if (tmpEntry.isPresent()) {
cEntries[j] = tmpEntry.get();
} else {
LOGGER.info("BibTeX key not found: '" + keys[j] + '\'');
LOGGER.info("Problem with reference mark: '" + names.get(i) + '\'');
cEntries[j] = new UndefinedBibtexEntry(keys[j]);
}
}
String[] normCitMarker = new String[keys.length];
String citationMarker;
if (style.isBibtexKeyCiteMarkers()) {
StringBuilder sb = new StringBuilder();
normCitMarkers[i] = new String[keys.length];
for (int j = 0; j < keys.length; j++) {
normCitMarkers[i][j] = cEntries[j].getCiteKeyOptional().orElse(null);
sb.append(cEntries[j].getCiteKeyOptional().orElse(""));
if (j < (keys.length - 1)) {
sb.append(',');
}
}
citationMarker = sb.toString();
} else if (style.isNumberEntries()) {
if (style.isSortByPosition()) {
// We have sorted the citation markers according to their order of appearance,
// so we simply count up for each marker referring to a new entry:
List<Integer> num = new ArrayList<>(keys.length);
for (int j = 0; j < keys.length; j++) {
if (cEntries[j] instanceof UndefinedBibtexEntry) {
num.add(j, -1);
} else {
num.add(j, lastNum + 1);
if (numbers.containsKey(keys[j])) {
num.set(j, numbers.get(keys[j]));
} else {
numbers.put(keys[j], num.get(j));
lastNum = num.get(j);
}
}
}
citationMarker = style.getNumCitationMarker(num, minGroupingCount, false);
for (int j = 0; j < keys.length; j++) {
normCitMarker[j] = style.getNumCitationMarker(Collections.singletonList(num.get(j)), minGroupingCount, false);
}
} else {
// We need to find the number of the cited entry in the bibliography,
// and use that number for the cite marker:
List<Integer> num = findCitedEntryIndex(names.get(i), cited);
if (num.isEmpty()) {
throw new BibEntryNotFoundException(names.get(i), Localization.lang("Could not resolve BibTeX entry for citation marker '%0'.", names.get(i)));
} else {
citationMarker = style.getNumCitationMarker(num, minGroupingCount, false);
}
for (int j = 0; j < keys.length; j++) {
List<Integer> list = new ArrayList<>(1);
list.add(num.get(j));
normCitMarker[j] = style.getNumCitationMarker(list, minGroupingCount, false);
}
}
} else {
if (cEntries.length > 1) {
if (style.getBooleanCitProperty(OOBibStyle.MULTI_CITE_CHRONOLOGICAL)) {
Arrays.sort(cEntries, yearAuthorTitleComparator);
} else {
Arrays.sort(cEntries, entryComparator);
}
// Update key list to match the new sorting:
for (int j = 0; j < cEntries.length; j++) {
bibtexKeys[i][j] = cEntries[j].getCiteKeyOptional().orElse(null);
}
}
citationMarker = style.getCitationMarker(Arrays.asList(cEntries), entries, type == OOBibBase.AUTHORYEAR_PAR, null, null);
// We need "normalized" (in parenthesis) markers for uniqueness checking purposes:
for (int j = 0; j < cEntries.length; j++) {
normCitMarker[j] = style.getCitationMarker(Collections.singletonList(cEntries[j]), entries, true, null, new int[] { -1 });
}
}
citMarkers[i] = citationMarker;
normCitMarkers[i] = normCitMarker;
}
}
uniquefiers.clear();
if (!style.isBibtexKeyCiteMarkers() && !style.isNumberEntries()) {
// See if there are duplicate citations marks referring to different entries. If so, we need to
// use uniquefiers:
Map<String, List<String>> refKeys = new HashMap<>();
Map<String, List<Integer>> refNums = new HashMap<>();
for (int i = 0; i < citMarkers.length; i++) {
// compare normalized markers, since the actual markers can be different
String[] markers = normCitMarkers[i];
for (int j = 0; j < markers.length; j++) {
String marker = markers[j];
String currentKey = bibtexKeys[i][j];
if (refKeys.containsKey(marker)) {
// Ok, we have seen this exact marker before.
if (!refKeys.get(marker).contains(currentKey)) {
// ... but not for this entry.
refKeys.get(marker).add(currentKey);
refNums.get(marker).add(i);
}
} else {
List<String> l = new ArrayList<>(1);
l.add(currentKey);
refKeys.put(marker, l);
List<Integer> l2 = new ArrayList<>(1);
l2.add(i);
refNums.put(marker, l2);
}
}
}
// Go through the collected lists and see where we need to uniquefy:
for (Map.Entry<String, List<String>> stringListEntry : refKeys.entrySet()) {
List<String> keys = stringListEntry.getValue();
if (keys.size() > 1) {
// This marker appears for more than one unique entry:
int uniq = 'a';
for (String key : keys) {
// Update the map of uniquefiers for the benefit of both the following generation of new
// citation markers, and for the method that builds the bibliography:
uniquefiers.put(key, String.valueOf((char) uniq));
uniq++;
}
}
}
// Finally, go through all citation markers, and update those referring to entries in our current list:
int maxAuthorsFirst = style.getIntCitProperty(OOBibStyle.MAX_AUTHORS_FIRST);
Set<String> seenBefore = new HashSet<>();
for (int j = 0; j < bibtexKeys.length; j++) {
boolean needsChange = false;
int[] firstLimAuthors = new int[bibtexKeys[j].length];
String[] uniquif = new String[bibtexKeys[j].length];
BibEntry[] cEntries = new BibEntry[bibtexKeys[j].length];
for (int k = 0; k < bibtexKeys[j].length; k++) {
String currentKey = bibtexKeys[j][k];
firstLimAuthors[k] = -1;
if (maxAuthorsFirst > 0) {
if (!seenBefore.contains(currentKey)) {
firstLimAuthors[k] = maxAuthorsFirst;
}
seenBefore.add(currentKey);
}
String uniq = uniquefiers.get(currentKey);
Optional<BibEntry> tmpEntry = Optional.empty();
if (uniq == null) {
if (firstLimAuthors[k] > 0) {
needsChange = true;
BibDatabase database = linkSourceBase.get(currentKey);
if (database != null) {
tmpEntry = database.getEntryByKey(currentKey);
}
} else {
BibDatabase database = linkSourceBase.get(currentKey);
if (database != null) {
tmpEntry = database.getEntryByKey(currentKey);
}
}
uniquif[k] = "";
} else {
needsChange = true;
BibDatabase database = linkSourceBase.get(currentKey);
if (database != null) {
tmpEntry = database.getEntryByKey(currentKey);
}
uniquif[k] = uniq;
}
if (tmpEntry.isPresent()) {
cEntries[k] = tmpEntry.get();
}
}
if (needsChange) {
citMarkers[j] = style.getCitationMarker(Arrays.asList(cEntries), entries, types[j] == OOBibBase.AUTHORYEAR_PAR, uniquif, firstLimAuthors);
}
}
}
// Refresh all reference marks with the citation markers we computed:
boolean hadBibSection = getBookmarkRange(OOBibBase.BIB_SECTION_NAME) != null;
// Check if we are supposed to set a character format for citations:
boolean mustTestCharFormat = style.isFormatCitations();
for (int i = 0; i < names.size(); i++) {
Object referenceMark = xReferenceMarks.getByName(names.get(i));
XTextContent bookmark = UnoRuntime.queryInterface(XTextContent.class, referenceMark);
XTextCursor cursor = bookmark.getAnchor().getText().createTextCursorByRange(bookmark.getAnchor());
if (mustTestCharFormat) {
// If we are supposed to set character format for citations, must run a test before we
// delete old citation markers. Otherwise, if the specified character format doesn't
// exist, we end up deleting the markers before the process crashes due to a the missing
// format, with catastrophic consequences for the user.
// need to do this only once
mustTestCharFormat = false;
XPropertySet xCursorProps = UnoRuntime.queryInterface(XPropertySet.class, cursor);
String charStyle = style.getCitationCharacterFormat();
try {
xCursorProps.setPropertyValue(CHAR_STYLE_NAME, charStyle);
} catch (UnknownPropertyException | PropertyVetoException | IllegalArgumentException | WrappedTargetException ex) {
throw new UndefinedCharacterFormatException(charStyle);
}
}
text.removeTextContent(bookmark);
insertReferenceMark(names.get(i), citMarkers[i], cursor, types[i] != OOBibBase.INVISIBLE_CIT, style);
if (hadBibSection && (getBookmarkRange(OOBibBase.BIB_SECTION_NAME) == null)) {
// We have overwritten the marker for the start of the reference list.
// We need to add it again.
cursor.collapseToEnd();
OOUtil.insertParagraphBreak(text, cursor);
insertBookMark(OOBibBase.BIB_SECTION_NAME, cursor);
}
}
List<String> unresolvedKeys = new ArrayList<>();
for (BibEntry entry : entries.keySet()) {
if (entry instanceof UndefinedBibtexEntry) {
String key = ((UndefinedBibtexEntry) entry).getKey();
if (!unresolvedKeys.contains(key)) {
unresolvedKeys.add(key);
}
}
}
return unresolvedKeys;
}
use of org.jabref.logic.openoffice.UndefinedBibtexEntry in project jabref by JabRef.
the class OOBibBase method findCitedEntries.
private Map<BibEntry, BibDatabase> findCitedEntries(List<BibDatabase> databases, List<String> keys, Map<String, BibDatabase> linkSourceBase) {
Map<BibEntry, BibDatabase> entries = new LinkedHashMap<>();
for (String key : keys) {
boolean found = false;
for (BibDatabase database : databases) {
Optional<BibEntry> entry = database.getEntryByKey(key);
if (entry.isPresent()) {
entries.put(entry.get(), database);
linkSourceBase.put(key, database);
found = true;
break;
}
}
if (!found) {
entries.put(new UndefinedBibtexEntry(key), null);
}
}
return entries;
}
Aggregations