Skip to content

Commit

Permalink
Oobranch d : apply style (JabRef#7789)
Browse files Browse the repository at this point in the history
* 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

JabRef#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
antalk2 committed Aug 2, 2021
1 parent f2617c5 commit 44a229b
Show file tree
Hide file tree
Showing 32 changed files with 3,942 additions and 26 deletions.
441 changes: 423 additions & 18 deletions src/main/java/org/jabref/logic/openoffice/style/OOBibStyle.java

Large diffs are not rendered by default.

Large diffs are not rendered by default.

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());
}

}
Loading

0 comments on commit 44a229b

Please sign in to comment.