11using System ;
22using System . Collections . Generic ;
3+ using System . Linq ;
34using DiffPlex . Chunkers ;
45using DiffPlex . DiffBuilder . Model ;
56using DiffPlex . Model ;
@@ -12,8 +13,8 @@ public class SideBySideDiffBuilder : ISideBySideDiffBuilder
1213 private readonly IChunker lineChunker ;
1314 private readonly IChunker wordChunker ;
1415
15- private delegate void PieceBuilder ( string oldText , string newText , List < DiffPiece > oldPieces , List < DiffPiece > newPieces ) ;
16-
16+ private delegate ChangeType PieceBuilder ( string oldText , string newText , List < DiffPiece > oldPieces , List < DiffPiece > newPieces , bool ignoreWhitespace , bool ignoreCase ) ;
17+
1718 /// <summary>
1819 /// Gets the default singleton instance.
1920 /// </summary>
@@ -26,25 +27,32 @@ public SideBySideDiffBuilder(IDiffer differ, IChunker lineChunker, IChunker word
2627 this . wordChunker = wordChunker ?? throw new ArgumentNullException ( nameof ( wordChunker ) ) ;
2728 }
2829
29- public SideBySideDiffBuilder ( IDiffer differ = null ) :
30+ public SideBySideDiffBuilder ( IDiffer differ = null ) :
3031 this ( differ , new LineChunker ( ) , new WordChunker ( ) )
3132 {
3233 }
3334
34- public SideBySideDiffBuilder ( IDiffer differ , char [ ] wordSeparators )
35+ public SideBySideDiffBuilder ( IDiffer differ , char [ ] wordSeparators )
3536 : this ( differ , new LineChunker ( ) , new DelimiterChunker ( wordSeparators ) )
3637 {
3738 }
3839
3940 public SideBySideDiffModel BuildDiffModel ( string oldText , string newText )
4041 => BuildDiffModel ( oldText , newText , ignoreWhitespace : true ) ;
4142
42- public SideBySideDiffModel BuildDiffModel ( string oldText , string newText , bool ignoreWhitespace )
43+ public SideBySideDiffModel BuildDiffModel ( string oldText , string newText , bool ignoreWhitespace ) => BuildDiffModel (
44+ oldText ,
45+ newText ,
46+ ignoreWhitespace ,
47+ false ) ;
48+
49+ public SideBySideDiffModel BuildDiffModel ( string oldText , string newText , bool ignoreWhitespace , bool ignoreCase )
4350 {
4451 return BuildLineDiff (
4552 oldText ?? throw new ArgumentNullException ( nameof ( oldText ) ) ,
4653 newText ?? throw new ArgumentNullException ( nameof ( newText ) ) ,
47- ignoreWhitespace ) ;
54+ ignoreWhitespace ,
55+ ignoreCase ) ;
4856 }
4957
5058 /// <summary>
@@ -62,7 +70,7 @@ public static SideBySideDiffModel Diff(string oldText, string newText, bool igno
6270
6371 var model = new SideBySideDiffModel ( ) ;
6472 var diffResult = Differ . Instance . CreateDiffs ( oldText , newText , ignoreWhiteSpace , ignoreCase , LineChunker . Instance ) ;
65- BuildDiffPieces ( diffResult , model . OldText . Lines , model . NewText . Lines , BuildWordDiffPiecesInternal ) ;
73+ BuildDiffPieces ( diffResult , model . OldText . Lines , model . NewText . Lines , BuildWordDiffPiecesInternal , ignoreWhiteSpace , ignoreCase ) ;
6674
6775 return model ;
6876 }
@@ -84,43 +92,46 @@ public static SideBySideDiffModel Diff(IDiffer differ, string oldText, string ne
8492 if ( newText == null ) throw new ArgumentNullException ( nameof ( newText ) ) ;
8593
8694 if ( differ == null ) return Diff ( oldText , newText , ignoreWhiteSpace , ignoreCase ) ;
95+
8796 var model = new SideBySideDiffModel ( ) ;
8897 var diffResult = differ . CreateDiffs ( oldText , newText , ignoreWhiteSpace , ignoreCase , lineChunker ?? LineChunker . Instance ) ;
89- BuildDiffPieces ( diffResult , model . OldText . Lines , model . NewText . Lines , ( ot , nt , op , np ) =>
98+ BuildDiffPieces ( diffResult , model . OldText . Lines , model . NewText . Lines , ( ot , nt , op , np , iw , ic ) =>
9099 {
91- var r = differ . CreateDiffs ( oldText , newText , false , false , wordChunker ?? WordChunker . Instance ) ;
92- BuildDiffPieces ( r , op , np , null ) ;
93- } ) ;
94-
100+ var r = differ . CreateDiffs ( oldText , newText , iw , ic , wordChunker ?? WordChunker . Instance ) ;
101+ return BuildDiffPieces ( r , op , np , null , iw , ic ) ;
102+ } , ignoreWhiteSpace , ignoreCase ) ;
103+
95104 return model ;
96105 }
97106
98- private static void BuildWordDiffPiecesInternal ( string oldText , string newText , List < DiffPiece > oldPieces , List < DiffPiece > newPieces )
107+ private static ChangeType BuildWordDiffPiecesInternal ( string oldText , string newText , List < DiffPiece > oldPieces , List < DiffPiece > newPieces , bool ignoreWhiteSpace , bool ignoreCase )
99108 {
100- var diffResult = Differ . Instance . CreateDiffs ( oldText , newText , false , false , WordChunker . Instance ) ;
101- BuildDiffPieces ( diffResult , oldPieces , newPieces , null ) ;
109+ var diffResult = Differ . Instance . CreateDiffs ( oldText , newText , ignoreWhiteSpace , ignoreCase , WordChunker . Instance ) ;
110+ return BuildDiffPieces ( diffResult , oldPieces , newPieces , null , ignoreWhiteSpace , ignoreCase ) ;
102111 }
103112
104- private SideBySideDiffModel BuildLineDiff ( string oldText , string newText , bool ignoreWhitespace )
113+ private SideBySideDiffModel BuildLineDiff ( string oldText , string newText , bool ignoreWhiteSpace , bool ignoreCase )
105114 {
106115 var model = new SideBySideDiffModel ( ) ;
107- var diffResult = differ . CreateDiffs ( oldText , newText , ignoreWhitespace , false , lineChunker ) ;
108- BuildDiffPieces ( diffResult , model . OldText . Lines , model . NewText . Lines , BuildWordDiffPieces ) ;
109-
116+ var diffResult = differ . CreateDiffs ( oldText , newText , ignoreWhiteSpace , ignoreCase , lineChunker ) ;
117+ BuildDiffPieces ( diffResult , model . OldText . Lines , model . NewText . Lines , BuildWordDiffPieces , ignoreWhiteSpace , ignoreCase ) ;
118+
110119 return model ;
111120 }
112121
113- private void BuildWordDiffPieces ( string oldText , string newText , List < DiffPiece > oldPieces , List < DiffPiece > newPieces )
122+ private ChangeType BuildWordDiffPieces ( string oldText , string newText , List < DiffPiece > oldPieces , List < DiffPiece > newPieces , bool ignoreWhiteSpace , bool ignoreCase )
114123 {
115- var diffResult = differ . CreateDiffs ( oldText , newText , ignoreWhiteSpace : false , false , wordChunker ) ;
116- BuildDiffPieces ( diffResult , oldPieces , newPieces , subPieceBuilder : null ) ;
124+ var diffResult = differ . CreateDiffs ( oldText , newText , ignoreWhiteSpace : ignoreWhiteSpace , ignoreCase , wordChunker ) ;
125+ return BuildDiffPieces ( diffResult , oldPieces , newPieces , subPieceBuilder : null , ignoreWhiteSpace , ignoreCase ) ;
117126 }
118127
119- private static void BuildDiffPieces ( DiffResult diffResult , List < DiffPiece > oldPieces , List < DiffPiece > newPieces , PieceBuilder subPieceBuilder )
128+ private static ChangeType BuildDiffPieces ( DiffResult diffResult , List < DiffPiece > oldPieces , List < DiffPiece > newPieces , PieceBuilder subPieceBuilder , bool ignoreWhiteSpace , bool ignoreCase )
120129 {
121130 int aPos = 0 ;
122131 int bPos = 0 ;
123132
133+ ChangeType changeSummary = ChangeType . Unchanged ;
134+
124135 foreach ( var diffBlock in diffResult . DiffBlocks )
125136 {
126137 while ( bPos < diffBlock . InsertStartB && aPos < diffBlock . DeleteStartA )
@@ -139,8 +150,8 @@ private static void BuildDiffPieces(DiffResult diffResult, List<DiffPiece> oldPi
139150
140151 if ( subPieceBuilder != null )
141152 {
142- subPieceBuilder ( diffResult . PiecesOld [ aPos ] , diffResult . PiecesNew [ bPos ] , oldPiece . SubPieces , newPiece . SubPieces ) ;
143- newPiece . Type = oldPiece . Type = ChangeType . Modified ;
153+ var subChangeSummary = subPieceBuilder ( diffResult . PiecesOld [ aPos ] , diffResult . PiecesNew [ bPos ] , oldPiece . SubPieces , newPiece . SubPieces , ignoreWhiteSpace , ignoreCase ) ;
154+ newPiece . Type = oldPiece . Type = subChangeSummary ;
144155 }
145156
146157 oldPieces . Add ( oldPiece ) ;
@@ -176,6 +187,18 @@ private static void BuildDiffPieces(DiffResult diffResult, List<DiffPiece> oldPi
176187 aPos ++ ;
177188 bPos ++ ;
178189 }
190+
191+ // Consider the whole diff as "modified" if we found any change, otherwise we consider it unchanged
192+ if ( oldPieces . Any ( x=> x . Type == ChangeType . Modified || x . Type == ChangeType . Inserted || x . Type == ChangeType . Deleted ) )
193+ {
194+ changeSummary = ChangeType . Modified ;
195+ }
196+ else if ( newPieces . Any ( x => x . Type == ChangeType . Modified || x . Type == ChangeType . Inserted || x . Type == ChangeType . Deleted ) )
197+ {
198+ changeSummary = ChangeType . Modified ;
199+ }
200+
201+ return changeSummary ;
179202 }
180203 }
181204}
0 commit comments