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);
        }
Ejemplo n.º 2
0
 public DifferLineVm ReadModel(DiffPiece line)
 {
     Position   = line.Position?.ToString() ?? "";
     Text       = line.Text;
     ChangeType = line.Type;
     return(this);
 }
Ejemplo n.º 3
0
        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;
            }
        }
Ejemplo n.º 4
0
        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);
                }
            }
        }
Ejemplo n.º 5
0
 private static string FormatText(DiffPiece diffPiece)
 {
     return(new StringBuilder(diffPiece.Text)
            .Replace(' ', '·')
            .Replace("\t", "→   ")
            .ToString());
 }
Ejemplo n.º 6
0
        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;
            }
        }
Ejemplo n.º 7
0
        /// <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));
        }
Ejemplo n.º 9
0
        //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);
        }
Ejemplo n.º 10
0
        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>");
            }
        }
Ejemplo n.º 11
0
        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());
        }
Ejemplo n.º 12
0
        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);
        }
Ejemplo n.º 13
0
        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());
        }
Ejemplo n.º 14
0
 private TextBlock Format(DiffPiece diffPiece)
 {
     return(new TextBlock()
     {
         Text = FormatText(diffPiece),
         TextWrapping = TextWrapping.NoWrap,
         Background = GetLineBackgroundBrush(diffPiece.Type)
     });
 }
Ejemplo n.º 15
0
        private string BuildBlock(DiffPiece leftPiece, DiffPiece rightPiece)
        {
            var leftSet  = BuildTableCells(leftPiece);
            var rightSet = BuildTableCells(rightPiece);

            var html = WrapRow(leftSet + rightSet);

            return(html);
        }
Ejemplo n.º 16
0
        /// <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);
        }
Ejemplo n.º 19
0
        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);
        }
Ejemplo n.º 20
0
        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);
        }
    }
Ejemplo n.º 21
0
        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);
        }
Ejemplo n.º 22
0
        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);
        }
Ejemplo n.º 23
0
        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);
        }
Ejemplo n.º 24
0
        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);
        }
Ejemplo n.º 25
0
 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("");
 }
Ejemplo n.º 26
0
        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("  ");
            }
        }
Ejemplo n.º 27
0
        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());
        }
Ejemplo n.º 28
0
        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);
        }
Ejemplo n.º 29
0
        /// <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);
        }
Ejemplo n.º 30
0
        private string BuildTableCells(DiffPiece diffLine)
        {
            var lineNumber = (diffLine.Position.HasValue) ? diffLine.Position.ToString() : "&nbsp;";
            var lineText   = BuildLineText(diffLine);

            if (string.IsNullOrWhiteSpace(lineText))
            {
                return("");
            }

            string html = ""
                          + $"<td class=\"lineNumber\">{lineNumber}</td>"
                          + "<td>&nbsp;</td>"
                          + $"<td class=\"line {ToCamelCase(diffLine.Type.ToString())}Line\">"
                          + "<span class=\"lineText\">"
                          + lineText
                          + "</span>"
                          + "</td>"
                          + "<td></td>";

            return(html);
        }