public void RefreshMuscleContractionVisibility(bool visible)
 {
     if (CurrentBest != null)
     {
         CurrentBest.RefreshMuscleContractionVisibility(visible);
     }
 }
Exemple #2
0
        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()));
        }