private Paragraph RenderDiffWords(DiffPiece line) { var paragraph = new Paragraph(); foreach (var word in line.SubPieces) { if (word.Type == ChangeType.Imaginary) { continue; } var run = new Run(word.Text); switch (word.Type) { case ChangeType.Deleted: run.Background = _deletedWordFillColor; break; case ChangeType.Inserted: run.Background = _insertedWordFillColor; break; default: run.Background = _unchangedWordFillColor; break; } paragraph.Inlines.Add(run); } return(paragraph); }
public DifferLineVm ReadModel(DiffPiece line) { Position = line.Position?.ToString() ?? ""; Text = line.Text; ChangeType = line.Type; return(this); }
private void InsertAndColor(RichTextBox TextBox, DiffPiece Line) { int selectStart = TextBox.Text.Length; string lineMarker = string.Format("{0,3:0}| ", Line.Position); string inputText = lineMarker + Line.Text; // Hack to force background coloring on the entire line for (int i = 0; i < 200; i++) { inputText += " "; } TextBox.AppendText(inputText + Environment.NewLine); TextBox.SelectionStart = selectStart + lineMarker.Length; TextBox.SelectionLength = inputText.Length - lineMarker.Length; switch (Line.Type) { case ChangeType.Deleted: TextBox.SelectionBackColor = Color.OrangeRed; break; case ChangeType.Inserted: TextBox.SelectionBackColor = Color.LightGreen; break; case ChangeType.Modified: TextBox.SelectionBackColor = Color.LightBlue; break; default: // Do nothing break; } }
public static void DiffHighlighting(SideBySideDiffBuilder diffBuilder, RichTextBox masterRB, RichTextBox prodRB) { if (Config.FileType != FileType.Templates) { SideBySideDiffModel diff = diffBuilder.BuildDiffModel(prodRB.Text, masterRB.Text); //4 possibilities: //1. Both Unchanged //2. Both Modified //3. New=Inserted, Old=Imaginary a line that is in master but not in prod //4. New=Imaginary Old=Deleted a line that is in prod but not in master //If it's imaginary, the line doesn't exist in the richtextbox (the way it is displayed in this program) //Master int rBLineNo = 0; for (int lineNo = 0; lineNo < diff.NewText.Lines.Count(); lineNo++) { DiffPiece diffLine = diff.NewText.Lines[lineNo]; DiffHighlightLine(masterRB, diffLine, ref rBLineNo); } //PROD rBLineNo = 0; for (int lineNo = 0; lineNo < diff.OldText.Lines.Count(); lineNo++) { DiffPiece diffLine = diff.OldText.Lines[lineNo]; DiffHighlightLine(prodRB, diffLine, ref rBLineNo); } } }
private static string FormatText(DiffPiece diffPiece) { return(new StringBuilder(diffPiece.Text) .Replace(' ', '·') .Replace("\t", "→ ") .ToString()); }
private void RenderDiffWords(Grid grid, TextBox textBox, DiffPiece line, int lineNumber) { var charPos = 0; var characterWidth = CharacterWidthOverride ?? currentFont.CharacterWidth; var leftOffset = LeftOffsetOverride ?? currentFont.LeftOffset; foreach (var word in line.SubPieces) { SolidColorBrush fillColor; if (word.Type == ChangeType.Deleted) { fillColor = new SolidColorBrush(Color.FromArgb(255, 255, 170, 170)); } else if (word.Type == ChangeType.Inserted) { fillColor = new SolidColorBrush(Color.FromArgb(255, 170, 255, 170)); } else if (word.Type == ChangeType.Imaginary) { continue; } else { fillColor = new SolidColorBrush(Colors.Transparent); } var left = characterWidth * charPos + leftOffset; var wordWidth = characterWidth * word.Text.Length; PlaceRectangleInGrid(textBox, grid, lineNumber, fillColor, left, wordWidth); charPos += word.Text.Replace("\t", " ").Length; } }
/// <summary> /// Add text to a rich text box, styling items as needed. /// </summary> /// <param name="box">Rich Text Box to add the text to.</param> /// <param name="piece">Piece of content. Could be an entire line if it's unchanged, or a subpiece in a line.</param> private void AddText(RichTextBox box, DiffPiece piece) { switch (piece.Type) { case ChangeType.Unchanged: box.AppendText(piece.Text); break; case ChangeType.Deleted: box.AppendText(piece.Text, Color.Red); break; case ChangeType.Inserted: box.AppendText(piece.Text, Color.Blue); break; case ChangeType.Imaginary: box.AppendText(String.Empty); break; case ChangeType.Modified: box.AppendText(piece.Text, Color.Green); break; default: box.AppendText(piece.Text, Color.Purple); break; } }
public static CodeChangeType ModifiedLineType(DiffPiece oldLine, DiffPiece newLine) { var tokens1 = containsTokens(oldLine); var tokens2 = containsTokens(newLine); return(classifyChangeType(tokens1) | classifyChangeType(tokens2)); }
//manually coloring the ListboxItems depending on their diff state //compare https://github.com/SciGit/scigit-client/blob/master/DiffPlex/SilverlightDiffer/TextBoxDiffRenderer.cs private SolidColorBrush GetBGColor(DiffPiece diffPiece) { var fillColor = new SolidColorBrush(Colors.Transparent); switch (diffPiece.Type) { case ChangeType.Deleted: fillColor = new SolidColorBrush(Color.FromArgb(255, 255, 200, 100)); break; case ChangeType.Inserted: fillColor = new SolidColorBrush(Color.FromArgb(255, 255, 255, 0)); break; case ChangeType.Unchanged: fillColor = new SolidColorBrush(Colors.White); break; case ChangeType.Modified: fillColor = new SolidColorBrush(Color.FromArgb(255, 220, 220, 255)); break; case ChangeType.Imaginary: fillColor = new SolidColorBrush(Color.FromArgb(255, 200, 200, 200)); break; } return(fillColor); }
static void WritePiece(StringBuilder html, DiffPiece piece) { if (piece.Type == DiffPlex.DiffBuilder.Model.ChangeType.Unchanged) { WriteSpan(html, "diff-unchanged", piece.Text); } else if (piece.Type == DiffPlex.DiffBuilder.Model.ChangeType.Inserted) { WriteSpan(html, "diff-inserted", piece.Text); } else if (piece.Type == DiffPlex.DiffBuilder.Model.ChangeType.Deleted) { WriteSpan(html, "diff-deleted", piece.Text); } else if (piece.Type == DiffPlex.DiffBuilder.Model.ChangeType.Modified) { html.Append("<span class=\"diff-modified\">"); foreach (var subpiece in piece.SubPieces) { WritePiece(html, subpiece); } html.Append("</span>"); } }
internal static string LineDiff(DiffPiece Line) { StringBuilder DR = new StringBuilder(); foreach (DiffPiece Word in Line.SubPieces) { switch (Word.Type) { case ChangeType.Deleted: DR.Append(@"\highlight2 "); DR.Append(Tools.RtfSafe(Word.Text)); DR.Append(@" \highlight0 "); break; case ChangeType.Inserted: DR.Append(@"\highlight1 "); DR.Append(Tools.RtfSafe(Word.Text)); DR.Append(@" \highlight0 "); break; case ChangeType.Imaginary: break; case ChangeType.Unchanged: DR.Append(Tools.RtfSafe(Word.Text)); break; case ChangeType.Modified: DR.Append(Tools.RtfSafe(Word.Text)); break; } } return(DR.ToString()); }
void WriteDiffLine(TextWriter writer, DiffPiece line) { if (line == null) { writer.Write("@@ ↕ "); writer.Write(new string ('-', maxLineWidth + maxLineNumberDigits)); writer.WriteLine(" ↕ @@"); return; } var lineNumber = line.Position == null ? string.Empty : line.Position.Value.ToString(CultureInfo.InvariantCulture); switch (line.Type) { case ChangeType.Unchanged: writer.Write(' '); break; case ChangeType.Inserted: writer.Write('+'); break; case ChangeType.Deleted: writer.Write('-'); break; } writer.Write(' '); writer.Write(lineNumber.PadLeft(maxLineNumberDigits)); writer.Write(" | "); writer.WriteLine(line.Text); }
private static string RenderDiffWords(DiffPiece line) { StringBuilder result = new StringBuilder(); ChangeType lastAction = ChangeType.Unchanged; foreach (var word in line.SubPieces) { if (word.Type == ChangeType.Imaginary) { continue; } if (word.Type == ChangeType.Modified) { result.Append(RenderDiffCharacter(word, ref lastAction)); } else { if (lastAction != ChangeType.Unchanged && lastAction != word.Type) { result.Append(PangoEnd); } result.Append(StartSpan(word.Type, lastAction)).Append(word.Text); lastAction = word.Type; } } if (lastAction != ChangeType.Unchanged) { result.Append(PangoEnd); } return(result.ToString()); }
private TextBlock Format(DiffPiece diffPiece) { return(new TextBlock() { Text = FormatText(diffPiece), TextWrapping = TextWrapping.NoWrap, Background = GetLineBackgroundBrush(diffPiece.Type) }); }
private string BuildBlock(DiffPiece leftPiece, DiffPiece rightPiece) { var leftSet = BuildTableCells(leftPiece); var rightSet = BuildTableCells(rightPiece); var html = WrapRow(leftSet + rightSet); return(html); }
/// <summary> /// Determine if a line from old text should be used in the inline diff. /// Disregards any lines that haven't changed. /// </summary> /// <param name="piece">The piece to evaluate.</param> /// <returns>True if it should be included, false otherwise.</returns> private bool ShouldAddOldLine(DiffPiece piece) { if (piece.Type == ChangeType.Unchanged || piece.Type == ChangeType.Imaginary) { return(false); } return(true); }
private static List <Run> ConvertLinveVmToRuns(DiffPiece lineVM) { //差分タイプによって、行頭の文字列内容と背景色を決定 var(color, preFix) = lineVM.Type switch { ChangeType.Deleted => (Colors.Pink, "💣| "), ChangeType.Inserted => (Colors.GreenYellow, "➕| "), ChangeType.Imaginary => (Colors.SkyBlue, "📌| "), ChangeType.Modified => (Colors.Yellow, "✏| "), _ => (Colors.Transparent, "🔏| "), }; //見やすいように少し半透明にしておく color.A = 0xC0; var baseColorBrush = new SolidColorBrush(color); var modifiedPieceBrush = new SolidColorBrush(Colors.Orange); //ChangeType.Modified以外は行全体で同じ書式 if (lineVM.Type != ChangeType.Modified) { var lineView = new Run() { Text = preFix + lineVM.Text, Background = baseColorBrush, }; return(new List <Run> { lineView }); } //ChangeType.Modifiedだったら変更された部分だけハイライトしたいのでSubPieceからいろいろやる var prefixRun = new Run() { Text = preFix, Background = baseColorBrush, }; var runs = new List <Run> { prefixRun }; foreach (var piece in lineVM.SubPieces) { runs.Add(new Run { Text = piece.Text, Background = piece.Type == ChangeType.Unchanged ? baseColorBrush : modifiedPieceBrush, }); } return(runs); }
private FlowDocument GenerateFlowDocument(DiffPaneModel diffPaneModel) { var flowDocument = new FlowDocument(); var lineWidths = new List <double>(); var stringBuilder = new StringBuilder(); bool isFirstLine = true; ChangeType?previousLineType = null; DiffPiece previousLine = null; foreach (var line in diffPaneModel.Lines) { if (line.Type != ChangeType.Modified && isFirstLine) { stringBuilder.Append(line.Text); } else if (line.Type != ChangeType.Modified && line.Type == previousLineType) { stringBuilder.Append(Environment.NewLine + line.Text); } else if (!isFirstLine && (line.Type != previousLineType || previousLineType == ChangeType.Modified)) { Paragraph paragraph = GetParagraph(stringBuilder, previousLineType, previousLine); flowDocument.Blocks.Add(paragraph); stringBuilder.Clear(); if (line.Type != ChangeType.Modified) { stringBuilder.Append(line.Text); } } isFirstLine = false; previousLineType = line.Type; previousLine = line; lineWidths.Add(CalculateLineWidth(line.Text)); } // process last line if (previousLine != null) { Paragraph lastParagraph = GetParagraph(stringBuilder, previousLineType, previousLine); flowDocument.Blocks.Add(lastParagraph); } flowDocument.LineStackingStrategy = LineStackingStrategy.BlockLineHeight; flowDocument.PagePadding = _zeroThickness; flowDocument.PageWidth = Math.Min(lineWidths.DefaultIfEmpty(0).Max(), 1000000); // Throws an ArgumentException if value is too big. I think the maximum allowed is 1 million. return(flowDocument); }
private static bool DoesLineHaveDifferentCoverage(DiffPiece line) { bool isDifferent = line.Type != ChangeType.Unchanged && line.Text != null && Regex.IsMatch(line.Text, @"'VC':\s*'\d+'"); if (isDifferent) { line.Text = Regex.Replace(line.Text, "^<tr ", "<tr class=\"danger\" "); } else { line.Type = ChangeType.Unchanged; } return(isDifferent); }
private static string GenerateDiff(DiffPiece diffPiece) { var diffRow = string.Empty; diffRow = diffPiece.Type switch { ChangeType.Deleted => diffPiece.Text.ToRed(), ChangeType.Inserted => diffPiece.Text.ToGreen(), ChangeType.Modified => diffPiece.SubPieces.Aggregate(diffRow, (current, subPiece) => $"{current}{GenerateDiff(subPiece)}"), ChangeType.Unchanged => diffPiece.Text.ToSilver(), _ => diffRow }; return(diffRow); } }
private static List <KeyValuePair <string, string> > GetSubPiecesInfo(DiffPiece line, bool isOld) { var details = new List <KeyValuePair <string, string> >(); foreach (var ele in line.SubPieces) { if (string.IsNullOrEmpty(ele?.Text)) { continue; } ChangeType subType = ChangeType.Imaginary; switch (ele.Type) { case ChangeType.Modified: subType = isOld ? ChangeType.Deleted : ChangeType.Inserted; break; case ChangeType.Inserted: subType = ChangeType.Inserted; break; case ChangeType.Deleted: subType = ChangeType.Deleted; break; case ChangeType.Unchanged: subType = ChangeType.Unchanged; break; } var subTypeStr = subType != ChangeType.Imaginary ? subType.ToString() : null; if (details.Count > 0) { var last = details[details.Count - 1]; if (string.Equals(last.Value, subTypeStr, StringComparison.InvariantCulture)) { details[details.Count - 1] = new KeyValuePair <string, string>(last.Key + ele.Text, subTypeStr); continue; } } details.Add(new KeyValuePair <string, string>(ele.Text, subTypeStr)); } return(details); }
private static bool NoChangeForNextTenRows(DiffPiece current, DiffPaneModel model) { int i = 0; foreach (DiffPiece diff in model.Lines.SkipWhile(x => x != current).Skip(1)) { if (diff.Type != ChangeType.Unchanged && diff.Type != ChangeType.Imaginary) { return(false); } if (i >= MAX_LINE_TO_SKIP) { return(true); } i++; } return(true); }
private static void AppendLine(StringBuilder sb, DiffPiece line) { switch (line.Type) { case ChangeType.Inserted: sb.Append("+ "); break; case ChangeType.Deleted: sb.Append("- "); break; default: sb.Append(" "); break; } sb.AppendLine(line.Text); }
private static int ProcessLine(DiffPiece line, int wasUnchanged, StringBuilder sb) { var changed = line.Type != ChangeType.Unchanged; if (changed || (wasUnchanged < Margin)) { if (line.Type == ChangeType.Inserted) { sb.Append("+ "); } else if (line.Type == ChangeType.Deleted) { sb.Append("- "); } else if (line.Type == ChangeType.Modified) { sb.Append("* "); } else if (line.Type == ChangeType.Imaginary) { sb.Append("? "); } else if (line.Type == ChangeType.Unchanged) { sb.Append(" "); } sb.Append(line.Text + "\n"); } else if (wasUnchanged == Margin) { sb.Append("..." + "\n"); } if (changed) { wasUnchanged = 0; } else { wasUnchanged++; } return(wasUnchanged); }
private static string WriteDiffPiece(DiffPiece newItem, DiffPiece expectedItem) { if (newItem.Type == ChangeType.Unchanged) { return(newItem.Text); } else if (newItem.Type == ChangeType.Inserted) { return(string.Format("Inserted - {0}", newItem.Text)); } else if (newItem.Type == ChangeType.Deleted) { return(string.Format("Deleted - {0}", newItem.Text)); } else if (newItem.Type == ChangeType.Modified || newItem.Type == ChangeType.Imaginary) { return(string.Format("Modified - {0} - Expected - {1}", newItem.Text, expectedItem.Text.Trim())); } return(""); }
private static string GetLinePrefix(DiffPiece line) { switch (line.Type) { case ChangeType.Inserted: return("+ "); case ChangeType.Deleted: return("- "); case ChangeType.Modified: return("M "); case ChangeType.Imaginary: return("I "); default: return(" "); } }
private static string RenderDiffCharacter(DiffPiece word, ref ChangeType lastAction) { StringBuilder result = new StringBuilder(); foreach (var characters in word.SubPieces) { if (characters.Type == ChangeType.Imaginary) { continue; } if (lastAction != ChangeType.Unchanged && lastAction != characters.Type) { result.Append(PangoEnd); } result.Append(StartSpan(characters.Type, lastAction)).Append(characters.Text); lastAction = characters.Type; } return(result.ToString()); }
private static DiffParagraph ShowSubPieceDiffs(DiffPiece line, bool isBeforeText) { var paragraph = CreateParagraph( string.Empty, line.Position.ToString() ?? " ", isBeforeText ? REMOVED_SIGN : ADDED_SIGN, isBeforeText ? GetBeforeModifiedBrush() : GetAfterModifiedBrush() ); var subPieces = line.SubPieces; foreach (var piece in subPieces) { switch (piece.Type) { case ChangeType.Unchanged: // if unchanged add the text with no coloring to the paragraph paragraph.Content.Inlines.Add(NewRun(piece.Text)); break; case ChangeType.Deleted: paragraph.Content.Inlines.Add(NewRun(piece.Text, GetDeletedRunBrush())); break; case ChangeType.Inserted: paragraph.Content.Inlines.Add(NewRun(piece.Text, GetModifiedRunBrush())); break; case ChangeType.Imaginary: break; case ChangeType.Modified: break; default: break; } } return(paragraph); }
/// <summary> /// this method is for merging 2 texts /// </summary> /// <description> /// merging left and right texts /// </description> /// <something> /// this is something /// </something> /// <param name="model"> /// <summary> /// this method is for merging 2 texts /// </summary> /// <description> /// merging left and right texts /// </description> /// </param> /// <param name="model2">this is description for model2</param> /// <returns>SideBySideDiffModel</returns> /// <completionlist cref="ConsoleKey.BrowserSearch"/> /// <example></example> /// <include file='IMerger.cs' path='[@name="asd"]'/> /// <permission cref="CLSCompliantAttribute.IsCompliant"></permission> /// <remarks></remarks> /// <see cref="decimal"/> /// <seealso cref="InvalidTimeZoneException.InvalidTimeZoneException()"/> public static SideBySideDiffModel GetMergedText(SideBySideDiffModel model, string model2) { DiffPaneModel mergedText = new DiffPaneModel(); try { var newLineList = model.NewText.Lines.ToList(); var oldLineList = model.OldText.Lines; for (int i = 0; i < newLineList.Count; i++) { switch (oldLineList[i].Type) { case ChangeType.Imaginary: DiffPiece leftLine = new DiffPiece(); leftLine.Position = i + 1; leftLine.SubPieces = model.NewText.Lines[i].SubPieces; leftLine.Text = model.NewText.Lines[i].Text; leftLine.Type = model.NewText.Lines[i].Type; mergedText.Lines.Add(leftLine); break; default: DiffPiece rightLine = new DiffPiece(); rightLine.Position = i + 1; rightLine.SubPieces = model.OldText.Lines[i].SubPieces; rightLine.Text = model.OldText.Lines[i].Text; rightLine.Type = model.OldText.Lines[i].Type; mergedText.Lines.Add(rightLine); break; } } } catch (Exception ex) { throw ex; } model.MergedText = mergedText; return(model); }
private string BuildTableCells(DiffPiece diffLine) { var lineNumber = (diffLine.Position.HasValue) ? diffLine.Position.ToString() : " "; var lineText = BuildLineText(diffLine); if (string.IsNullOrWhiteSpace(lineText)) { return(""); } string html = "" + $"<td class=\"lineNumber\">{lineNumber}</td>" + "<td> </td>" + $"<td class=\"line {ToCamelCase(diffLine.Type.ToString())}Line\">" + "<span class=\"lineText\">" + lineText + "</span>" + "</td>" + "<td></td>"; return(html); }