109 lines
2.8 KiB
Dart
109 lines
2.8 KiB
Dart
class Word {
|
|
final int start;
|
|
final int end;
|
|
final String text;
|
|
|
|
Word({required this.start, required this.end, required this.text});
|
|
}
|
|
|
|
class WordDelta {
|
|
Word? old;
|
|
Word? modified;
|
|
|
|
WordDelta({this.old, this.modified});
|
|
}
|
|
|
|
class TextDelta {
|
|
final List<WordDelta> wordDeltas = [];
|
|
}
|
|
|
|
class Utility {
|
|
static List<Word> splitToWords(String text) {
|
|
List<Word> words = [];
|
|
String currentWord = "";
|
|
for (int i = 0; i < text.length; i++) {
|
|
if (text[i] == " " ||
|
|
text[i] == "\n" ||
|
|
text[i] == "\r" ||
|
|
text[i] == "\t") {
|
|
if (currentWord.isNotEmpty) {
|
|
words.add(
|
|
Word(start: i - currentWord.length, end: i, text: currentWord));
|
|
currentWord = "";
|
|
}
|
|
} else {
|
|
currentWord += text[i];
|
|
}
|
|
}
|
|
if (currentWord.isNotEmpty) {
|
|
words.add(Word(
|
|
start: text.length - currentWord.length,
|
|
end: text.length,
|
|
text: currentWord));
|
|
}
|
|
return words;
|
|
}
|
|
|
|
static List<TextDelta> compare(String oldText, String newText) {
|
|
var oldWords = splitToWords(oldText);
|
|
var newWords = splitToWords(newText);
|
|
|
|
int oldIndex = 0;
|
|
int newIndex = 0;
|
|
|
|
List<TextDelta> textDeltas = [];
|
|
while ((oldIndex < oldWords.length) && (newIndex < newWords.length)) {
|
|
var oldWord = oldWords[oldIndex];
|
|
var newWord = newWords[newIndex];
|
|
if (oldWord.text == newWord.text) {
|
|
oldIndex++;
|
|
newIndex++;
|
|
} else {
|
|
var delta = TextDelta();
|
|
delta.wordDeltas.add(WordDelta(old: oldWord, modified: newWord));
|
|
textDeltas.add(delta);
|
|
oldIndex++;
|
|
newIndex++;
|
|
|
|
if (oldIndex < oldWords.length && newIndex < newWords.length) {
|
|
var nextOldWord = oldWords[oldIndex];
|
|
var newSubIndex = newIndex;
|
|
var oldSubIndex = oldIndex;
|
|
while (newSubIndex < newWords.length &&
|
|
newWords[newSubIndex].text != nextOldWord.text) {
|
|
WordDelta wordDelta =
|
|
WordDelta(old: nextOldWord, modified: newWords[newSubIndex]);
|
|
delta.wordDeltas.add(wordDelta);
|
|
newSubIndex++;
|
|
oldSubIndex++;
|
|
}
|
|
if (newIndex != newSubIndex) {
|
|
newIndex = newSubIndex;
|
|
oldIndex = oldSubIndex;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (newIndex < newWords.length) {
|
|
var delta = TextDelta();
|
|
while (newIndex < newWords.length) {
|
|
delta.wordDeltas.add(WordDelta(modified: newWords[newIndex]));
|
|
newIndex++;
|
|
}
|
|
textDeltas.add(delta);
|
|
}
|
|
|
|
if (oldIndex < oldWords.length) {
|
|
var delta = TextDelta();
|
|
while (oldIndex < oldWords.length) {
|
|
delta.wordDeltas.add(WordDelta(old: oldWords[oldIndex]));
|
|
oldIndex++;
|
|
}
|
|
textDeltas.add(delta);
|
|
}
|
|
|
|
return textDeltas;
|
|
}
|
|
}
|