public void RefreshMuscleContractionVisibility(bool visible) { if (CurrentBest != null) { CurrentBest.RefreshMuscleContractionVisibility(visible); } }
static internal WordDiff AnalyzeWordDiff(List <string> newLines, int newLineNumber, List <string> oldLines, int oldLineNumber) { var newSplitLines = newLines .SelectMany((newLine, index) => SplitLine(newLine) .Select(text => new IndexedToken(text, index + newLineNumber))) .ToList(); var oldSplitLines = oldLines .SelectMany((oldLine, index) => SplitLine(oldLine) .Select(text => new IndexedToken(text, index + oldLineNumber))) .ToList(); // int oldI = 0; // old diff is checked up to this token int currentOldOffset = 0; int currentNewOffset = 0; var currentBest = new CurrentBest() { Diff = 0, Index = -1 }; for (int i = 0; i < newSplitLines.Count; ++i) { if (string.IsNullOrWhiteSpace(newSplitLines[i].Text) && i < newSplitLines.Count - 1) { continue; } else if (!string.IsNullOrWhiteSpace(newSplitLines[i].Text)) { var oldIndex = oldSplitLines.FindIndex(currentOldOffset, m => m.Text == newSplitLines[i].Text); if (oldIndex == -1) { // The new token was not found in the old text newSplitLines[i].Unchanged = false; if (i < newSplitLines.Count - 1) { continue; } } else { var diff = oldIndex - currentOldOffset - (i - currentNewOffset); if (diff == 0 || diff == 1) { for (int j = currentOldOffset; j < oldIndex; ++j) { oldSplitLines[j].Unchanged = string.IsNullOrWhiteSpace(oldSplitLines[j].Text); } for (int j = currentNewOffset; j < i; ++j) { newSplitLines[j].Unchanged = string.IsNullOrWhiteSpace(newSplitLines[j].Text); } currentBest.Index = -1; currentOldOffset = oldIndex + 1; currentNewOffset = i + 1; continue; } if (currentBest.Index == -1 || diff + i < currentBest.Diff + currentBest.Index) { // Better match was found. currentBest.Index = i; currentBest.Diff = diff; } } } if (currentBest.Index != -1 && (currentBest.Diff + currentBest.Index <= i + 1 || i == newSplitLines.Count - 1)) { // Accept this as similar var similarOldIndex = currentOldOffset + currentBest.Index - currentNewOffset + currentBest.Diff; for (int j = currentOldOffset; j < similarOldIndex; ++j) { oldSplitLines[j].Unchanged = string.IsNullOrWhiteSpace(oldSplitLines[j].Text); } for (int j = currentNewOffset; j < currentBest.Index; ++j) { newSplitLines[j].Unchanged = string.IsNullOrWhiteSpace(newSplitLines[j].Text); } currentOldOffset = similarOldIndex + 1; currentNewOffset = currentBest.Index + 1; i = currentBest.Index; currentBest.Index = -1; continue; } } for (int i = currentOldOffset; i < oldSplitLines.Count; ++i) { if (!string.IsNullOrWhiteSpace(oldSplitLines[i].Text)) { oldSplitLines[i].Unchanged = false; } } if (newSplitLines.Count > 1 && string.IsNullOrWhiteSpace(newSplitLines[0].Text)) { newSplitLines[0].Unchanged = newSplitLines[1].Unchanged; } for (int i = 1; i < newSplitLines.Count; ++i) { if (string.IsNullOrWhiteSpace(newSplitLines[i].Text)) { newSplitLines[i].Unchanged = newSplitLines[i - 1].Unchanged; } } if (oldSplitLines.Count > 1 && string.IsNullOrWhiteSpace(oldSplitLines[0].Text)) { oldSplitLines[0].Unchanged = oldSplitLines[1].Unchanged; } for (int i = 1; i < oldSplitLines.Count; ++i) { if (string.IsNullOrWhiteSpace(oldSplitLines[i].Text)) { oldSplitLines[i].Unchanged = oldSplitLines[i - 1].Unchanged; } } var newText = newSplitLines .GroupBy(token => token.Line, (lineNumber, tokens) => new ChangedLine(lineNumber, tokens .Select(indexedToken => new Token(indexedToken.Text, indexedToken.Unchanged)) .GroupAdjacent((first, second) => first.Unchanged == second.Unchanged, tokens => tokens .Aggregate((first, second) => new Token(first.Text + second.Text, first.Unchanged))) .ToList())); var oldText = oldSplitLines .GroupBy(token => token.Line, (lineNumber, tokens) => new ChangedLine(lineNumber, tokens .Select(indexedToken => new Token(indexedToken.Text, indexedToken.Unchanged)) .GroupAdjacent((first, second) => first.Unchanged == second.Unchanged, tokens => tokens .Aggregate((first, second) => new Token(first.Text + second.Text, first.Unchanged))) .ToList())); return(new WordDiff(newText.ToList(), oldText.ToList())); }