DocX icon indicating copy to clipboard operation
DocX copied to clipboard

issue with one overload of method Xceed.Document.NET.Paragraph.ReplaceText();

Open bcs-software opened this issue 4 years ago • 2 comments

Hello all, We just tried this very useful lib for editing doc files (great job you have done!) and encountered something, which seems to be a bug. It is within the "Func" overload of the method ->

public void ReplaceText( string findPattern, Func<string, string> regexMatchHandler, bool trackChanges = false, RegexOptions options = RegexOptions.None, Formatting newFormatting = null, Formatting matchFormatting = null, MatchFormattingOptions fo = MatchFormattingOptions.SubsetMatch, bool removeEmptyParagraph = true );

// issue is here, starting from line 3798:
// Replace text when formatting matches.
if( formattingMatch )
{
  var newValue = regexMatchHandler.Invoke( match.Groups[ /*1*/0 ].Value ); // <----- here you have said, that it should be the second element
  // while we think it should be the first (we commented out index 1 and placed 0 instead).
  // We debugged it and the match.Groups contains only one item. Or maybe in a particular use case there could be 2 items...?
  this.InsertText( match.Index + match.Value.Length, newValue, trackChanges, newFormatting );
  this.RemoveText( match.Index, match.Value.Length, trackChanges, removeEmptyParagraph );
}

Before this change:

Dictionary<string, string> items = new Dictionary<string, string>();
items.Add("1", "One");
items.Add("2", "Two");

//...

document.ReplaceText(@"[12]", (a) => { return items[a.ToLower()]; }, false, System.Text.RegularExpressions.RegexOptions.IgnoreCase, new Xceed.Document.NET.Formatting() { Bold = true, FontColor = System.Drawing.Color.Green });

this code would produce a KeyNotFoundException, as a is an empty string. After the change, it all works fine. If we are wrong, could you please explain to us how to call the method properly?

Thank you!

bcs-software avatar Mar 10 '21 08:03 bcs-software

Hi, You are right, there is a bug in here. Good catch ! You solution should work, but if we look at the preceding ReplacingText function, there is a for loop to get the last correct Groups index. So the fix could be: ` int lastcap = 0; for( int k = 0; k < match.Groups.Count; k++ ) { var g = match.Groups[k]; if( ( g == null ) || ( g.Value == "" ) ) continue; lastcap = k; }

      var newValue = regexMatchHandler.Invoke( match.Groups[lastcap].Value );`

This will be fixed in v1.9. Thank you.

XceedBoucherS avatar Mar 10 '21 14:03 XceedBoucherS

Hi,

And I thank you for your solution. Just read it and it seems much better to me. I will try it now.

bcs-software avatar Mar 10 '21 15:03 bcs-software