lassevk / DiffLib

A simple but powerful diff and merge class library for .NET, written in C#

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Screenshot and demo

jochenwezel opened this issue · comments

This samples show the basic power of this DiffLib and is provided as VB.NET:

image

Option Explicit On
Option Strict On

Imports DiffLib

Module Module1

    Sub Main()
        Const text1 As String = "This is a test of the diff implementation, with some text that is deleted."
        Const text2 As String = "This is another test of the same implementation, with some more text."
        Diffs.DumpDiffToConsole(text1, text2)
        Console.WriteLine()
    End Sub
End Module

Public Class Diffs

    Public Shared Function DumpDiffAsHtml(text1 As String, text2 As String) As String
        Dim sections As IEnumerable(Of DiffSection) = Diff.CalculateSections(Of Char)(text1.ToCharArray, text2.ToCharArray)
        Return DumpDiffAsHtml(text1, text2, sections)
    End Function

    Private Shared Function DumpDiffAsHtml(text1 As String, text2 As String, sections As IEnumerable(Of DiffSection)) As String
        Dim html = New System.Text.StringBuilder()
        Dim i1 = 0
        Dim i2 = 0
        For Each section In sections
            If section.IsMatch Then
                html.Append(text1.Substring(i1, section.LengthInCollection1))
            Else
                html.Append("<span style='background-color: #ffcccc; text-decoration: line-through;'>" + text1.Substring(i1, section.LengthInCollection1) + "</span>")
                html.Append("<span style='background-color: #ccffcc;'>" + text2.Substring(i2, section.LengthInCollection2) + "</span>")
            End If

            i1 += section.LengthInCollection1
            i2 += section.LengthInCollection2
        Next
        Return html.ToString()
    End Function

    Public Shared Sub DumpDiffToConsole(text1 As String, text2 As String)
        Dim sections As IEnumerable(Of DiffSection) = Diff.CalculateSections(Of Char)(text1.ToCharArray, text2.ToCharArray)
        DumpDiffToConsole(text1, text2, sections)
    End Sub

    Private Shared Sub DumpDiffToConsole(text1 As String, text2 As String, sections As IEnumerable(Of DiffSection))
        Dim DefaultColor As ConsoleColor = Console.ForegroundColor
        Dim html = New System.Text.StringBuilder()
        Dim i1 = 0
        Dim i2 = 0
        For Each section In sections
            If section.IsMatch Then
                Console.ForegroundColor = DefaultColor
                Console.Write(text1.Substring(i1, section.LengthInCollection1))
            Else
                Console.ForegroundColor = ConsoleColor.Red
                Console.Write(text1.Substring(i1, section.LengthInCollection1))
                Console.ForegroundColor = ConsoleColor.Green
                Console.Write(text2.Substring(i2, section.LengthInCollection2))
            End If

            i1 += section.LengthInCollection1
            i2 += section.LengthInCollection2
        Next
        Console.ForegroundColor = DefaultColor
    End Sub

End Class

An alternative for HTML output is following method:

        Const text1 As String = "This is a test of the diff implementation, with some text that is deleted."
        Const text2 As String = "This is another test of the same implementation, with some more text."
        Dim Html As String = Diffs.DumpDiffAsHtml(text1, text2)

which generated following output

This is a<span style="background-color: #ffcccc; text-decoration: line-through;"></span><span style="background-color: #ccffcc;">nother</span> test of the <span style="background-color: #ffcccc; text-decoration: line-through;">diff</span><span style="background-color: #ccffcc;">same</span> implementation, with some <span style="background-color: #ffcccc; text-decoration: line-through;"></span><span style="background-color: #ccffcc;">more </span>text<span style="background-color: #ffcccc; text-decoration: line-through;"> that is deleted</span><span style="background-color: #ccffcc;"></span>.

image

Maybe, this output is also nice/useful for some persons out there:
image

Public Module Module1
    Sub Main()
            Const text1 As String = "Begin" & vbNewLine & vbNewLine & "We are multiline" & vbNewLine & vbNewLine & "We are multiline" & vbNewLine & "This is a test of the diff implementation, with some text that is deleted." & vbNewLine & vbNewLine & "We are multiline" & vbNewLine & vbNewLine & "We are multiline" & vbNewLine & vbNewLine & "We are multiline"
            Const text2 As String = "Begin" & vbNewLine & vbNewLine & "We are multiline" & vbNewLine & vbNewLine & "We are multiline" & vbNewLine & "This is another test of the same implementation, with some more text." & vbNewLine & vbNewLine & "We are multiline" & vbNewLine & vbNewLine & "We are multiline" & vbNewLine & vbNewLine & "We are multiline"
            Diffs.DumpDiffToConsoleHumanFriendly(text1, text2)
    End Sub
End Module

Public Class Diffs

    Public Shared Sub DumpDiffToConsoleHumanFriendly(text1 As String, text2 As String)
        DumpDiffToConsole(text1, text2, 15)
    End Sub

    Public Shared Sub DumpDiffToConsole(text1 As String, text2 As String, charsMargin As Integer)
        Dim sections As IEnumerable(Of DiffSection) = Diff.CalculateSections(Of Char)(text1.ToCharArray, text2.ToCharArray)
        DumpDiffToConsole(text1, text2, sections, charsMargin)
    End Sub

    Private Shared Sub DumpDiffToConsole(text1 As String, text2 As String, sections As IEnumerable(Of DiffSection), charsMargin As Integer)
        Dim DefaultColor As ConsoleColor = Console.ForegroundColor
        Dim html = New System.Text.StringBuilder()
        Dim i1 = 0
        Dim i2 = 0
        For Each section In sections
            If section.IsMatch Then
                Console.ForegroundColor = DefaultColor
                Dim UnchangedText As String = text1.Substring(i1, section.LengthInCollection1)
                If i1 = 0 Then
                    'begin of string -> only the char amount of {charsMargin} at the end
                    If UnchangedText.Length <= charsMargin Then
                        Console.Write(HumanFriendlyEscapeOfControlChars(UnchangedText))
                    Else
                        Console.Write(HumanFriendlyEscapeOfControlChars("..." & UnchangedText.Substring(UnchangedText.Length - charsMargin)))
                    End If
                ElseIf i1 + UnchangedText.Length = text1.Length Then
                    'begin of string -> only the char amount of {charsMargin} at the end
                    If UnchangedText.Length <= charsMargin Then
                        Console.Write(HumanFriendlyEscapeOfControlChars(UnchangedText))
                    Else
                        Console.Write(HumanFriendlyEscapeOfControlChars(UnchangedText.Substring(0, charsMargin) & "..."))
                    End If
                Else
                    'inside the string -> the char amount of {charsMargin} from the begin and from the end
                    If section.LengthInCollection1 > 2 * charsMargin Then
                        Console.Write(HumanFriendlyEscapeOfControlChars(UnchangedText.Substring(0, System.Math.Min(UnchangedText.Length, charsMargin))))
                        Console.WriteLine("...")
                        Console.Write(HumanFriendlyEscapeOfControlChars(UnchangedText.Substring(UnchangedText.Length - System.Math.Min(UnchangedText.Length, charsMargin))))
                    Else
                        Console.Write(HumanFriendlyEscapeOfControlChars(UnchangedText))
                    End If
                End If
            Else
                Console.ForegroundColor = ConsoleColor.Red
                Console.Write(HumanFriendlyEscapeOfControlChars(text1.Substring(i1, section.LengthInCollection1)))
                Console.ForegroundColor = ConsoleColor.Green
                Console.Write(HumanFriendlyEscapeOfControlChars(text2.Substring(i2, section.LengthInCollection2)))
            End If

            i1 += section.LengthInCollection1
            i2 += section.LengthInCollection2
        Next
        Console.ForegroundColor = DefaultColor
    End Sub

    Private Shared Function HumanFriendlyEscapeOfControlChars(text As String) As String
        Return text.Replace(ControlChars.Cr, "<CR>").Replace(ControlChars.Lf, "<LF>").Replace(ControlChars.Tab, "<TAB>").Replace(ControlChars.VerticalTab, "<VTAB>").Replace(ControlChars.NullChar, "<NUL>").Replace(ControlChars.Back, "<BACK>").Replace(ControlChars.FormFeed, "<FF>").Replace(ChrW(27), "<ESC>")
    End Function

    '--> the remaining methods from class Diffs as in this community post

End Class

This will be added into the documentation wiki.

Above sample code and some more have also been collected at https://github.com/CompuMasterGmbH/CompuMaster.Text.Diff