Replacing text with MergeFields

Hi Guys,

I’m trying to replace my own placeholders with word merge fields.
When I use the method Replace(Regex pattern, IReplacingCallback handler, bool isForward) and set isForward = false it works fine. But when I set isForward = true my code doesn’t work correctly. Looks like it remembers positions of matches before replacing and then inerts a next one whitout taking into account that a document has been already modified.

There is the code of my replace evaluator:

internal class ReplaceEvaluator : IReplacingCallback
{
    private int count = 1;

    #region IReplacingCallback Members

    public ReplaceAction Replacing(ReplacingArgs e)
    {
        // Create document builder.
        DocumentBuilder builder = new DocumentBuilder((Document)e.MatchNode.Document);

        // This is a Run node that contains either the beginning or the complete match.
        Node currentNode = e.MatchNode;

        // The first (and may be the only) run can contain text before the match,
        // in this case it is necessary to split the run.
        if (e.MatchOffset > 0)
        {
            currentNode = SplitRun((Run)currentNode, e.MatchOffset);
        }

        Run currentRun = (Run)currentNode;

        // Move to the run.
        builder.MoveTo(currentRun);

        builder.InsertField(String.Format(@"MERGEFIELD Filed{0} * MERGEFORMAT", count++));
        e.Replacement = "";
        return ReplaceAction.Replace;
    }

    #endregion

    ///
    /// Splits text of the specified run into two runs.
    /// Inserts the new run just after the specified run.
    ///
    private static Run SplitRun(Run run, int position)
    {
        Run afterRun = (Run)run.Clone(true);
        afterRun.Text = run.Text.Substring(position);
        run.Text = run.Text.Substring(0, position);
        run.ParentNode.InsertAfter(afterRun, run);
        return afterRun;
    }
}

My document plain text is “Test1\fTest2\fTest3\f”.

After replcaing with isForward=false:
"MERGEFIELD Filed3 \* MERGEFORMAT«Filed3»MERGEFIELD Filed2 \* MERGEFORMAT«Filed2»MERGEFIELD Filed1 \* MERGEFORMAT«Filed1»"
After replacing with isForward = true:
"MERGEFIELD Filed3 \* MERGEFORMAT«Filed3»FIELD Filed2 \* MERGEFORMAT«Filed2»FIELD Filed1 \* MERGEFORMAT«Filed1»\fTest2\fTest3\f"

That is how I run the replace method:

doc.Range.Replace(new Regex(@"test\d", RegexOptions.IgnoreCase), new ReplaceEvaluator(), false);

What have I change in my code to make it works when isForward = true?
Thanks.

Hi
Thanks for your request. This occurs because you perform some node manipulations in your IReplacingCallback. When you are replacing from the beginning of the range to the end, nodes indexes might be changed and that is why the problem occurs. So if you need to perform manipulations with nodes in your IReplacingCallback, I would suggest you replacing from the end of the range to the beginning.
Is there a reason why you need to replace your placeholders from the beginning to the end?
Best regards,

Hi Alexey,

Thanks for your quick reply.

So, if I need to replace some text with a merge field I can’t use replacing from the beginning to the end. Did I understand you correctly?

And yes, there is a reason, unfortunatly.

Hi
Thanks for your request. Could you please clarify why you need to replace from the beginning to the end? Maybe we will help you to find another way to achieve what you need.
Best regards,

Hi Alexey,

I did find the way to make replacing from the end to the beginning as you suggested.

Thanks for your attention.