private void UnPackDiffedLine(HtmlTableRowGroup rowGroup, List<string> leftLines, List<string> rightLines) { if (leftLines.Count < rowGroup.Lines.Count || rightLines.Count < rowGroup.Lines.Count) { Log.Error("Interline Diff error: line count mismatch: {0} != {1}", leftLines.Count, rightLines.Count); return; } for (var idx = 0; idx < rowGroup.Lines.Count; idx++) { var line = rowGroup.Lines[idx]; var value = leftLines[idx]; if (value != line.Left.LineText && line.Left.LineText != null) { var newLine = new Line { Id = line.Left.Id, LineNum = line.Left.LineNum, LineText = value }; line.Left = newLine; } value = rightLines[idx]; if (value != line.Right.LineText && line.Right.LineText != null) { var newLine = new Line { Id = line.Right.Id, LineNum = line.Right.LineNum, LineText = value }; line.Right = newLine; } } }
private void InterlineDiff(HtmlTableRowGroup rowGroup, bool ignoreWhiteSpaces) { var baseLineInfo = new LineDiffInfo(rowGroup); var diffLineInfo = new LineDiffInfo(rowGroup, baseLineInfo); InterlineDiff(baseLineInfo, diffLineInfo, ignoreWhiteSpaces); UnPackDiffedLine(rowGroup, baseLineInfo.Lines, diffLineInfo.Lines); baseLineInfo.Dispose(); diffLineInfo.Dispose(); }
private void AddSeperators(HtmlTableRowGroup rowGroup, HtmlTable left, HtmlTable right, HtmlTable edge) { // Unchanged seperator left.AddBody("Seperator Base"); right.AddBody("Seperator Diff"); edge.AddBody("Seperator Diff"); var startLine = rowGroup.Lines.Count > 0 ? rowGroup.Lines.First() : GetEmptyLine(); var endLine = rowGroup.Lines.Count > 0 ? rowGroup.Lines.Last() : GetEmptyLine(); left.AddBodySeperator(startLine.Left.LineNum, startLine.Left.Id, string.Format("Lines {0} to {1}", startLine.Left.LineNumber, endLine.Left.LineNumber)); right.AddBodySeperator(startLine.Right.LineNum, startLine.Right.Id, string.Format("Lines {0} to {1}", startLine.Right.LineNumber, endLine.Right.LineNumber)); edge.AddEdgeSeperator(startLine.Right.LineNum, startLine.Right.Id); left.EndBody(); right.EndBody(); edge.EndBody(); }
/// <summary> /// Generates the diff view for two file revisions. /// </summary> private string GenerateFileDiffView( int baseRevision, int diffRevision, UserSettingsDto settings, StreamCombiner baseFile, int baseId, string baseHeader, StreamCombiner diffFile, int diffId, string diffHeader, StreamCombiner rawDiff, string fileName, string outputFile) { var baseEncoder = GetEncoderForFile(fileName); var diffEncoder = GetEncoderForFile(fileName); var baseFileInfo = new DiffFileInfo(baseFile, baseEncoder, baseId, BaseOrDiff.Base); var diffFileInfo = new DiffFileInfo(diffFile, diffEncoder, diffId, BaseOrDiff.Diff); // Line Stamp format var baseScriptIdPrefix = "Base-" + EncodeLinePrefix(baseRevision, diffRevision, baseId, diffId, baseId); var diffScriptIdPrefix = "Diff-" + EncodeLinePrefix(baseRevision, diffRevision, baseId, diffId, diffId); var edgePrefix = "Edge-" + EncodeLinePrefix(baseRevision, diffRevision, baseId, diffId, diffId); var rowGroups = new List<HtmlTableRowGroup>(); var lastBaseLine = "1"; var lastDiffLine = "1"; foreach (var diffItem in DiffItem.EnumerateDifferences(rawDiff)) { var atEnd = diffItem.BaseLineCount == int.MaxValue; var baseLines = new List<Line>(); for (var i = 0; i < diffItem.BaseLineCount && baseFileInfo.MoveNextLine(); ++i) baseLines.Add(new Line { LineNum = baseFileInfo.CurLineNum.ToString(CultureInfo.InvariantCulture), LineText = baseFileInfo.CurLine }); var diffLines = new List<Line>(); for (var i = 0; i < diffItem.DiffLineCount && diffFileInfo.MoveNextLine(); ++i) diffLines.Add(new Line { LineNum = diffFileInfo.CurLineNum.ToString(CultureInfo.InvariantCulture), LineText = diffFileInfo.CurLine }); var baseLinesLength = baseLines.Count(); var diffLinesLength = diffLines.Count(); // The end is the only case where the DiffInfo line counts may be incorrect. If there are in fact // zero lines then just continue, which should cause the foreach block to end and we'll continue // like the DiffItem never existed. if (atEnd && diffItem.DiffType == DiffType.Unchanged && baseLinesLength == 0 && diffLinesLength == 0) continue; var rowGroup = new HtmlTableRowGroup(diffItem.DiffType); for (var i = 0; i < Math.Max(baseLinesLength, diffLinesLength); ++i) { var line = new HtmlTableLine(); if (i < baseLinesLength) { line.Left = baseLines[i]; line.Left.LineText = baseFileInfo.Encoder.EncodeLine(baseLines[i].LineText, int.MaxValue, TabValue); lastBaseLine = line.Left.LineNum; } else { // new diff code - add entry for empty line with old line # var idx = i - baseLinesLength; line.Left = new Line { Id = lastBaseLine + '_' + idx }; } if (i < diffLinesLength) { line.Right = diffLines[i]; line.Right.LineText = diffFileInfo.Encoder.EncodeLine(diffLines[i].LineText, int.MaxValue, TabValue); lastDiffLine = line.Right.LineNum; } else { // new diff code - add entry for empty line with old line # var idx = i - diffLinesLength; line.Right = new Line { Id = lastDiffLine + '_' + idx }; } rowGroup.Lines.Add(line); } if (diffItem.DiffType == DiffType.Changed) { if (settings.diff.intraLineDiff) InterlineDiff(rowGroup, settings.diff.ignoreWhiteSpace); } rowGroups.Add(rowGroup); } baseEncoder.Dispose(); diffEncoder.Dispose(); var htmlLines = EncodeRowGroups(rowGroups, baseHeader, diffHeader, baseScriptIdPrefix, diffScriptIdPrefix, edgePrefix); if (!string.IsNullOrWhiteSpace(outputFile)) { var folder = Path.GetDirectoryName(outputFile); Directory.CreateDirectory(folder); File.WriteAllLines(outputFile, htmlLines); Log.Info("Generated {0}", outputFile); return outputFile; } else { return string.Join(Environment.NewLine, htmlLines); } }
public LineDiffInfo(HtmlTableRowGroup rowGroup, LineDiffInfo baseInfo = null) { BaseInfo = baseInfo ?? this; BaseMode = baseInfo == null; var charsList = new List<string>(); foreach (var item in rowGroup.Lines) { var line = BaseMode ? item.Left.Code : item.Right.Code; line = line ?? ""; var lineEscapes = UnEncodeLine(ref line); Escapes.Add(lineEscapes); Chars += line; var chars = line.ToCharArray(); charsList.AddRange(chars.Select(ch => ch.ToString(CultureInfo.InvariantCulture))); LinePositions.Add(line.Length); } Length = Chars.Length; File.WriteAllLines(TempFileName, charsList); }