-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* step0 : start model/openoffice, logic/openoffice/style * correction: import order * add general utilities * add UNO utilities, move CreationException, NoDocumentException * Xlint:unchecked model/openoffice/util * add ootext * add rangesort * add compareStartsUnsafe, compareStartsThenEndsUnsafe * add Tuple3 * add ootext * add rangesort * delNamesArray size correction * rangeSort update * cleanup * style additions * checkstyle on tests * add missing message * ootext changes from improve-reversibility-rebased-03 * rangesort changes from improve-reversibility-rebased-03 * rangesort update from improve-reversibility-rebased-03 add comment on RangeSet.add costs use UnoTextRange.compareXXXUnsafe * use longer lines in comments * propagate changes from improve-reversibility-rebased-03 * deleted src/main/java/org/jabref/model/openoffice/rangesort/RangeSet.java * deleted src/main/java/org/jabref/model/openoffice/rangesort/RangeSet.java * use StringUtil.isNullOrEmpty * no natural sort for ComparableMark * in response to review #7788 (review) - more use of StringUtil.isNullOrEmpty - private final XTextRangeCompare cmp; - List<V> partition = partitions.computeIfAbsent(partitionKey, _key -> new ArrayList<>()); - visualSort does not throw WrappedTargetException, NoDocumentException - set renamed to comparableMarks * use {@code }, PMD suggestions * update model/style from improve-reversibility-rebased-03 * update logic/style from improve-reversibility-rebased-03 * replaced single-character names in OOBibStyle.java (in changed part) * some longer names in OOBibStyleGetCitationMarker.java * drop normalizePageInfos, use 'preferred' and 'fallback' in getAuthorLastSeparatorInTextWithFallBack * checkstyle * use putIfAbsent * use "{}" with LOGGER * use Objects.hash and Objects.equals in CitationLookupResult * simplified CitedKey.getBibEntry * more use of "{}" in LOGGER * Citation.lookup: use streams * Citation.lookup: Optional::get before findFirst
- Loading branch information
Showing
32 changed files
with
3,942 additions
and
26 deletions.
There are no files selected for viewing
441 changes: 423 additions & 18 deletions
441
src/main/java/org/jabref/logic/openoffice/style/OOBibStyle.java
Large diffs are not rendered by default.
Oops, something went wrong.
774 changes: 774 additions & 0 deletions
774
src/main/java/org/jabref/logic/openoffice/style/OOBibStyleGetCitationMarker.java
Large diffs are not rendered by default.
Oops, something went wrong.
281 changes: 281 additions & 0 deletions
281
src/main/java/org/jabref/logic/openoffice/style/OOBibStyleGetNumCitationMarker.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,281 @@ | ||
package org.jabref.logic.openoffice.style; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.Optional; | ||
|
||
import org.jabref.model.openoffice.ootext.OOText; | ||
import org.jabref.model.openoffice.style.CitationMarkerNumericBibEntry; | ||
import org.jabref.model.openoffice.style.CitationMarkerNumericEntry; | ||
import org.jabref.model.openoffice.style.PageInfo; | ||
import org.jabref.model.openoffice.util.OOListUtil; | ||
|
||
class OOBibStyleGetNumCitationMarker { | ||
|
||
/* | ||
* The number encoding "this entry is unresolved" | ||
*/ | ||
public final static int UNRESOLVED_ENTRY_NUMBER = 0; | ||
|
||
private OOBibStyleGetNumCitationMarker() { | ||
/**/ | ||
} | ||
|
||
/** | ||
* Defines sort order for CitationMarkerNumericEntry. | ||
*/ | ||
private static int compareCitationMarkerNumericEntry(CitationMarkerNumericEntry a, | ||
CitationMarkerNumericEntry b) { | ||
int na = a.getNumber().orElse(UNRESOLVED_ENTRY_NUMBER); | ||
int nb = b.getNumber().orElse(UNRESOLVED_ENTRY_NUMBER); | ||
int res = Integer.compare(na, nb); | ||
if (res == 0) { | ||
res = PageInfo.comparePageInfo(a.getPageInfo(), b.getPageInfo()); | ||
} | ||
return res; | ||
} | ||
|
||
/** | ||
* Create a numeric marker for use in the bibliography as label for the entry. | ||
* | ||
* To support for example numbers in superscript without brackets for the text, | ||
* but "[1]" form for the bibliography, the style can provide | ||
* the optional "BracketBeforeInList" and "BracketAfterInList" strings | ||
* to be used in the bibliography instead of "BracketBefore" and "BracketAfter" | ||
* | ||
* @return "[${number}]" where | ||
* "[" stands for BRACKET_BEFORE_IN_LIST (with fallback BRACKET_BEFORE) | ||
* "]" stands for BRACKET_AFTER_IN_LIST (with fallback BRACKET_AFTER) | ||
* "${number}" stands for the formatted number. | ||
*/ | ||
public static OOText getNumCitationMarkerForBibliography(OOBibStyle style, | ||
CitationMarkerNumericBibEntry entry) { | ||
// prefer BRACKET_BEFORE_IN_LIST and BRACKET_AFTER_IN_LIST | ||
String bracketBefore = style.getBracketBeforeInListWithFallBack(); | ||
String bracketAfter = style.getBracketAfterInListWithFallBack(); | ||
StringBuilder sb = new StringBuilder(); | ||
sb.append(style.getCitationGroupMarkupBefore()); | ||
sb.append(bracketBefore); | ||
final Optional<Integer> current = entry.getNumber(); | ||
sb.append(current.isPresent() | ||
? String.valueOf(current.get()) | ||
: (OOBibStyle.UNDEFINED_CITATION_MARKER + entry.getCitationKey())); | ||
sb.append(bracketAfter); | ||
sb.append(style.getCitationGroupMarkupAfter()); | ||
return OOText.fromString(sb.toString()); | ||
} | ||
|
||
/* | ||
* emitBlock : a helper for getNumCitationMarker2 | ||
* | ||
* Given a block containing either a single entry or two or more | ||
* entries that are joinable into an "i-j" form, append to {@code sb} the | ||
* formatted text. | ||
* | ||
* Assumes: | ||
* | ||
* - block is not empty | ||
* | ||
* - For a block with a single element the element may have | ||
* pageInfo and its num part may be Optional.empty() | ||
* | ||
* - For a block with two or more elements | ||
* | ||
* - The elements do not have pageInfo and their number part is | ||
* not empty. | ||
* | ||
* - The elements number parts are consecutive positive integers, | ||
* without repetition. | ||
* | ||
*/ | ||
private static void emitBlock(List<CitationMarkerNumericEntry> block, | ||
OOBibStyle style, | ||
int minGroupingCount, | ||
StringBuilder sb) { | ||
|
||
final int blockSize = block.size(); | ||
if (blockSize == 0) { | ||
throw new IllegalArgumentException("The block is empty"); | ||
} | ||
|
||
if (blockSize == 1) { | ||
// Add single entry: | ||
CitationMarkerNumericEntry entry = block.get(0); | ||
final Optional<Integer> num = entry.getNumber(); | ||
sb.append(num.isEmpty() | ||
? (OOBibStyle.UNDEFINED_CITATION_MARKER + entry.getCitationKey()) | ||
: String.valueOf(num.get())); | ||
// Emit pageInfo | ||
Optional<OOText> pageInfo = entry.getPageInfo(); | ||
if (pageInfo.isPresent()) { | ||
sb.append(style.getPageInfoSeparator()); | ||
sb.append(OOText.toString(pageInfo.get())); | ||
} | ||
return; | ||
} | ||
|
||
if (blockSize >= 2) { | ||
|
||
/* | ||
* Check assumptions | ||
*/ | ||
|
||
if (block.stream().anyMatch(x -> x.getPageInfo().isPresent())) { | ||
throw new IllegalArgumentException("Found pageInfo in a block with more than one elements"); | ||
} | ||
|
||
if (block.stream().anyMatch(x -> x.getNumber().isEmpty())) { | ||
throw new IllegalArgumentException("Found unresolved entry in a block with more than one elements"); | ||
} | ||
|
||
for (int j = 1; j < blockSize; j++) { | ||
if ((block.get(j).getNumber().get() - block.get(j - 1).getNumber().get()) != 1) { | ||
throw new IllegalArgumentException("Numbers are not consecutive"); | ||
} | ||
} | ||
|
||
/* | ||
* Do the actual work | ||
*/ | ||
|
||
if (blockSize >= minGroupingCount) { | ||
int first = block.get(0).getNumber().get(); | ||
int last = block.get(blockSize - 1).getNumber().get(); | ||
if (last != (first + blockSize - 1)) { | ||
throw new IllegalArgumentException("blockSize and length of num range differ"); | ||
} | ||
|
||
// Emit: "first-last" | ||
sb.append(first); | ||
sb.append(style.getGroupedNumbersSeparator()); | ||
sb.append(last); | ||
} else { | ||
|
||
// Emit: first, first+1,..., last | ||
for (int j = 0; j < blockSize; j++) { | ||
if (j > 0) { | ||
sb.append(style.getCitationSeparator()); | ||
} | ||
sb.append(block.get(j).getNumber().get()); | ||
} | ||
} | ||
return; | ||
} | ||
} | ||
|
||
/** | ||
* Format a number-based citation marker for the given number or numbers. | ||
* | ||
* @param entries Provide the citation numbers. | ||
* | ||
* An Optional.empty() number means: could not look this up | ||
* in the databases. Positive integers are the valid numbers. | ||
* | ||
* Duplicate citation numbers are allowed: | ||
* | ||
* - If their pageInfos are identical, only a | ||
* single instance is emitted. | ||
* | ||
* - If their pageInfos differ, the number is emitted with each | ||
* distinct pageInfo. | ||
* | ||
* pageInfos are expected to be normalized | ||
* | ||
* @param minGroupingCount Zero and negative means never group. | ||
* Only used by tests to override the value in style. | ||
* | ||
* @return The text for the citation. | ||
* | ||
*/ | ||
public static OOText getNumCitationMarker2(OOBibStyle style, | ||
List<CitationMarkerNumericEntry> entries, | ||
int minGroupingCount) { | ||
|
||
final boolean joinIsDisabled = (minGroupingCount <= 0); | ||
final int nCitations = entries.size(); | ||
|
||
String bracketBefore = style.getBracketBefore(); | ||
String bracketAfter = style.getBracketAfter(); | ||
|
||
// Sort a copy of entries | ||
List<CitationMarkerNumericEntry> sorted = OOListUtil.map(entries, e -> e); | ||
sorted.sort(OOBibStyleGetNumCitationMarker::compareCitationMarkerNumericEntry); | ||
|
||
// "[" | ||
StringBuilder sb = new StringBuilder(bracketBefore); | ||
|
||
/* | ||
* Original: | ||
* [2,3,4] -> [2-4] | ||
* [0,1,2] -> [??,1,2] | ||
* [0,1,2,3] -> [??,1-3] | ||
* | ||
* Now we have to consider: duplicate numbers and pageInfos | ||
* [1,1] -> [1] | ||
* [1,1 "pp nn"] -> keep separate if pageInfo differs | ||
* [1 "pp nn",1 "pp nn"] -> [1 "pp nn"] | ||
*/ | ||
|
||
boolean blocksEmitted = false; | ||
List<CitationMarkerNumericEntry> currentBlock = new ArrayList<>(); | ||
List<CitationMarkerNumericEntry> nextBlock = new ArrayList<>(); | ||
|
||
for (int i = 0; i < nCitations; i++) { | ||
|
||
final CitationMarkerNumericEntry current = sorted.get(i); | ||
if (current.getNumber().isPresent() && current.getNumber().get() < 0) { | ||
throw new IllegalArgumentException("getNumCitationMarker2: found negative number"); | ||
} | ||
|
||
if (currentBlock.isEmpty()) { | ||
currentBlock.add(current); | ||
} else { | ||
CitationMarkerNumericEntry prev = currentBlock.get(currentBlock.size() - 1); | ||
if (current.getNumber().isEmpty() || prev.getNumber().isEmpty()) { | ||
nextBlock.add(current); // do not join if not found | ||
} else if (joinIsDisabled) { | ||
nextBlock.add(current); // join disabled | ||
} else if (compareCitationMarkerNumericEntry(current, prev) == 0) { | ||
// Same as prev, just forget it. | ||
} else if ((current.getNumber().get() == (prev.getNumber().get() + 1)) | ||
&& (prev.getPageInfo().isEmpty()) | ||
&& (current.getPageInfo().isEmpty())) { | ||
// Just two consecutive numbers without pageInfo: join | ||
currentBlock.add(current); | ||
} else { | ||
// do not join | ||
nextBlock.add(current); | ||
} | ||
} | ||
|
||
if (nextBlock.size() > 0) { | ||
// emit current block | ||
if (blocksEmitted) { | ||
sb.append(style.getCitationSeparator()); | ||
} | ||
emitBlock(currentBlock, style, minGroupingCount, sb); | ||
blocksEmitted = true; | ||
currentBlock = nextBlock; | ||
nextBlock = new ArrayList<>(); | ||
} | ||
|
||
} | ||
|
||
if (nextBlock.size() != 0) { | ||
throw new IllegalStateException("impossible: (nextBlock.size() != 0) after loop"); | ||
} | ||
|
||
if (currentBlock.size() > 0) { | ||
// We are emitting a block | ||
if (blocksEmitted) { | ||
sb.append(style.getCitationSeparator()); | ||
} | ||
emitBlock(currentBlock, style, minGroupingCount, sb); | ||
} | ||
|
||
// Emit: "]" | ||
sb.append(bracketAfter); | ||
return OOText.fromString(sb.toString()); | ||
} | ||
|
||
} |
Oops, something went wrong.