public IEnumerable <DiffMatchPatch.Patch> MakePatch(string contentOne, string contentTwo, CompareOptions options) { var diff = new my.utils.Diff(); var changes = diff.DiffText(contentOne, contentTwo); var contentOneLines = contentOne.Split(new[] { Environment.NewLine }, StringSplitOptions.None); var contentTwoLines = contentTwo.Split(new[] { Environment.NewLine }, StringSplitOptions.None); var chunks = new HashSet <Chunk>(); Chunk currentChunk = null; for (var i = 0; i < changes.Length; i++) { var change = changes[i]; Diff.Item?nextChange = null; if (changes.Length > i + 1) { nextChange = changes.ElementAtOrDefault(i + 1); } var continuation = currentChunk != null; if (!continuation) { currentChunk = CreateChunk(change, options); chunks.Add(currentChunk); } if (change.StartA != 0 && !continuation) { // no start context needed currentChunk.start1 = change.StartA - options.ContextSize; currentChunk.start2 = change.StartB - options.ContextSize; // stick some context in var start = change.StartB - options.ContextSize; for (var j = start; j < change.StartB; j++) { currentChunk.diffs.Add(new Line(Operation.EQUAL, contentTwoLines[j])); } } if (change.deletedA > 0) { for (var j = 0; j < change.deletedA; j++) { var line = contentOneLines[j + change.StartA]; currentChunk.diffs.Add(new Line(Operation.DELETE, line)); } } if (change.insertedB > 0) { for (var j = 0; j < change.insertedB; j++) { var line = contentTwoLines[j + change.StartB]; currentChunk.diffs.Add(new Line(Operation.INSERT, line)); } } var start2 = change.StartB + change.insertedB; int end; if (nextChange.HasValue) { end = Min(start2 + options.ContextSize, contentTwoLines.Length, nextChange.Value.StartB); } else { end = Min(start2 + options.ContextSize, contentTwoLines.Length); } for (var j = start2; j < end; j++) { currentChunk.diffs.Add(new Line(Operation.EQUAL, contentTwoLines[j])); } if (nextChange.HasValue && nextChange.Value.StartB - end > 0) { // need to split the diff into multiple chunks currentChunk = null; } } foreach (var chunk in chunks) { chunk.length1 = chunk.diffs.Count(x => x.operation == Operation.EQUAL || x.operation == Operation.DELETE); chunk.length2 = chunk.diffs.Count(x => x.operation == Operation.EQUAL || x.operation == Operation.INSERT); } return(chunks); }
public IEnumerable<DiffMatchPatch.Patch> MakePatch(string contentOne, string contentTwo, CompareOptions options) { var diff = new my.utils.Diff(); var changes = diff.DiffText(contentOne, contentTwo); var contentOneLines = contentOne.Split(new[] { Environment.NewLine }, StringSplitOptions.None); var contentTwoLines = contentTwo.Split(new[] { Environment.NewLine }, StringSplitOptions.None); var chunks = new HashSet<Chunk>(); Chunk currentChunk = null; for (var i = 0; i < changes.Length; i++) { var change = changes[i]; Diff.Item? nextChange = null; if (changes.Length > i + 1) nextChange = changes.ElementAtOrDefault(i + 1); var continuation = currentChunk != null; if (!continuation) { currentChunk = CreateChunk(change, options); chunks.Add(currentChunk); } if (change.StartA != 0 && !continuation) { // no start context needed currentChunk.start1 = change.StartA - options.ContextSize; currentChunk.start2 = change.StartB - options.ContextSize; // stick some context in var start = change.StartB - options.ContextSize; for (var j = start; j < change.StartB; j++) { currentChunk.diffs.Add(new Line(Operation.EQUAL, contentTwoLines[j])); } } if (change.deletedA > 0) { for (var j = 0; j < change.deletedA; j++) { var line = contentOneLines[j + change.StartA]; currentChunk.diffs.Add(new Line(Operation.DELETE, line)); } } if (change.insertedB > 0) { for (var j = 0; j < change.insertedB; j++) { var line = contentTwoLines[j + change.StartB]; currentChunk.diffs.Add(new Line(Operation.INSERT, line)); } } var start2 = change.StartB + change.insertedB; int end; if (nextChange.HasValue) end = Min(start2 + options.ContextSize, contentTwoLines.Length, nextChange.Value.StartB); else end = Min(start2 + options.ContextSize, contentTwoLines.Length); for (var j = start2; j < end; j++) { currentChunk.diffs.Add(new Line(Operation.EQUAL, contentTwoLines[j])); } if (nextChange.HasValue && nextChange.Value.StartB - end > 0) { // need to split the diff into multiple chunks currentChunk = null; } } foreach (var chunk in chunks) { chunk.length1 = chunk.diffs.Count(x => x.operation == Operation.EQUAL || x.operation == Operation.DELETE); chunk.length2 = chunk.diffs.Count(x => x.operation == Operation.EQUAL || x.operation == Operation.INSERT); } return chunks; }