Skip to content

Commit

Permalink
Simplify line terminator handling,
Browse files Browse the repository at this point in the history
at the expense of not preserving line terminators of inserted text.
All line terminators are now "\n".

Resolves #141.
  • Loading branch information
TomasMikula committed Sep 10, 2015
1 parent 9ee3643 commit b03e1cc
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 269 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javafx.beans.binding.Bindings;
import javafx.beans.binding.StringBinding;
Expand All @@ -36,6 +37,8 @@
final class EditableStyledDocument<S>
extends StyledDocumentBase<S, ObservableList<Paragraph<S>>> {

private static final Pattern LINE_TERMINATOR = Pattern.compile("\r\n|\r|\n");

/* ********************************************************************** *
* *
* Observables *
Expand Down Expand Up @@ -307,7 +310,7 @@ public void setStyleSpans(int from, StyleSpans<? extends S> styleSpans) {
if(q != firstPar) {
paragraphs.set(firstParIdx, q);
}
spansFrom = spansTo.offsetBy(firstPar.getLineTerminator().map(LineTerminator::length).orElse(0), Forward); // skip the newline
spansFrom = spansTo.offsetBy(1, Forward); // skip the newline

for(int i = firstParIdx + 1; i < lastParIdx; ++i) {
Paragraph<S> par = paragraphs.get(i);
Expand All @@ -316,7 +319,7 @@ public void setStyleSpans(int from, StyleSpans<? extends S> styleSpans) {
if(q != par) {
paragraphs.set(i, q);
}
spansFrom = spansTo.offsetBy(par.getLineTerminator().map(LineTerminator::length).orElse(0), Forward); // skip the newline
spansFrom = spansTo.offsetBy(1, Forward); // skip the newline
}

Paragraph<S> lastPar = paragraphs.get(lastParIdx);
Expand Down Expand Up @@ -353,7 +356,7 @@ public void setStyleSpans(int paragraph, int from, StyleSpans<? extends S> style
* ********************************************************************** */

private static <S> List<Paragraph<S>> stringToParagraphs(String str, S style) {
Matcher m = LineTerminator.regex().matcher(str);
Matcher m = LINE_TERMINATOR.matcher(str);

int n = 1;
while(m.find()) ++n;
Expand All @@ -363,8 +366,7 @@ private static <S> List<Paragraph<S>> stringToParagraphs(String str, S style) {
m.reset();
while(m.find()) {
String s = str.substring(start, m.start());
LineTerminator t = LineTerminator.from(m.group());
res.add(new Paragraph<S>(s, style).terminate(t));
res.add(new Paragraph<S>(s, style));
start = m.end();
}
String last = str.substring(start);
Expand All @@ -381,7 +383,12 @@ private void ensureValidParagraphRange(int par, int start, int end) {
if(par < 0 || par >= paragraphs.size()) {
throw new IllegalArgumentException(par + " is not a valid paragraph index. Must be from [0, " + paragraphs.size() + ")");
}
ensureValidRange(start, end, paragraphs.get(par).fullLength());
ensureValidRange(start, end, fullLength(par));
}

private int fullLength(int par) {
int n = paragraphs.size();
return paragraphs.get(par).length() + (par == n-1 ? 0 : 1);
}

private void ensureValidRange(int start, int end, int len) {
Expand All @@ -399,10 +406,9 @@ private void ensureValidRange(int start, int end, int len) {
private int terminatorLengthToSkip(Position pos) {
Paragraph<S> par = paragraphs.get(pos.getMajor());
int skipSum = 0;
while(pos.getMinor() >= par.length() && pos.getMinor() < par.fullLength()) {
int skipLen = par.fullLength() - pos.getMinor();
skipSum += skipLen;
pos = pos.offsetBy(skipLen, Forward); // will jump to the next paragraph, if not at the end
while(pos.getMinor() == par.length() && pos.getMajor() < paragraphs.size() - 1) {
skipSum += 1;
pos = pos.offsetBy(1, Forward); // will jump to the next paragraph
par = paragraphs.get(pos.getMajor());
}
return skipSum;
Expand All @@ -412,9 +418,9 @@ private int terminatorLengthToTrim(Position pos) {
int parLen = paragraphs.get(pos.getMajor()).length();
int trimSum = 0;
while(pos.getMinor() > parLen) {
int trimLen = pos.getMinor() - parLen;
trimSum += trimLen;
pos = pos.offsetBy(-trimLen, Backward); // may jump to the end of previous paragraph, if parLen was 0
assert pos.getMinor() - parLen == 1;
trimSum += 1;
pos = pos.offsetBy(-1, Backward); // may jump to the end of previous paragraph, if parLen was 0
parLen = paragraphs.get(pos.getMajor()).length();
}
return trimSum;
Expand Down Expand Up @@ -477,37 +483,18 @@ private <D extends CharSequence> void replace(
private List<Paragraph<S>> join(Paragraph<S> first, List<Paragraph<S>> middle, Paragraph<S> last) {
int m = middle.size();
if(m == 0) {
return join(first, last);
} else if(!first.isTerminated()) {
first = first.concat(middle.get(0));
middle = middle.subList(1, m);
return join(first, middle, last);
return Arrays.asList(first.concat(last));
} else if(m == 1) {
return Arrays.asList(first.concat(middle.get(0)).concat(last));
} else {
Paragraph<S> lastMiddle = middle.get(m - 1);
if(lastMiddle.isTerminated()) {
int n = 1 + m + 1;
List<Paragraph<S>> res = new ArrayList<>(n);
res.add(first);
res.addAll(middle);
res.add(last);
return res;
} else {
int n = 1 + m;
List<Paragraph<S>> res = new ArrayList<>(n);
res.add(first);
res.addAll(middle.subList(0, m - 1));
res.add(lastMiddle.concat(last));
return res;
}
List<Paragraph<S>> res = new ArrayList<>(middle.size());
res.add(first.concat(middle.get(0)));
res.addAll(middle.subList(1, m - 1));
res.add(middle.get(m-1).concat(last));
return res;
}
}

private List<Paragraph<S>> join(Paragraph<S> first, Paragraph<S> last) {
return first.isTerminated()
? Arrays.asList(first, last)
: Arrays.asList(first.concat(last));
}

// TODO: Replace with ObservableList.setAll(from, to, col) when implemented.
// See https://javafx-jira.kenai.com/browse/RT-32655.
private void setAll(int startIdx, int endIdx, Collection<Paragraph<S>> pars) {
Expand Down
49 changes: 0 additions & 49 deletions richtextfx/src/main/java/org/fxmisc/richtext/LineTerminator.java

This file was deleted.

Loading

0 comments on commit b03e1cc

Please sign in to comment.