Problem with IReplacingCallback and insertHtml

Hi,

I’m trying to replace some placeholder with html using

a ReplacingCallback

@Override
public int replacing(ReplacingArgs arguments) throws Exception {
    DocumentBuilder builder = new DocumentBuilder(doc);
    builder.moveTo(arguments.getMatchNode());
    builder.insertHtml(value);
    return ReplaceAction.REPLACE;
}

But my results are not as I’d expect them.

I got something like :
Text {replaceMe} Text {replaceMe}
but after Replacement, I end up with something like:
Text replacedText replacedText Text

I attached a test case for you. Can you please tell me if I’m doing anything wrong here and how to make this work as expected?

Hi Scherge,

Thanks for your inquiry. Yes, you can achieve your requirement by implementing IReplacingCallback interface. Please use the same approach shared at following documentation link to achieve your requirements.
https://docs.aspose.com/words/java/find-and-replace/

I have modified your code, please see the following code snippet. Hope this helps you. Please let us know if you have any more queries.

class FreeTextReplacingCallbackHander implements IReplacingCallback {
    Document doc;
    String value;
    public FreeTextReplacingCallbackHander(Document doc, String value) {
        this.doc = doc;
        this.value = value;
    }
    private Run splitRun(Run run, int position) throws Exception
    {
        Run afterRun = (Run)run.deepClone(true);
        afterRun.setText(run.getText().substring(position));
        run.setText(run.getText().substring((0), (0) + (position)));
        run.getParentNode().insertAfter(afterRun, run);
        return afterRun;
    }
    public int replacing(ReplacingArgs e) throws Exception {
        DocumentBuilder builder = new DocumentBuilder(doc);
        // This is a Run node that contains either the beginning or the complete match.
        Node currentNode = e.getMatchNode();
        // 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.getMatchOffset() > 0)
            currentNode = splitRun((Run)currentNode, e.getMatchOffset());
        // This array is used to store all nodes of the match for further highlighting.
        ArrayList runs = new ArrayList();
        // Find all runs that contain parts of the match string.
        int remainingLength = e.getMatch().group().length();
        while (
                (remainingLength > 0) &&
                        (currentNode != null) &&
                        (currentNode.getText().length() <= remainingLength))
        {
            runs.add(currentNode);
            remainingLength = remainingLength - currentNode.getText().length();
            // Select the next Run node.
            // Have to loop because there could be other nodes such as BookmarkStart etc.
            do
            {
                currentNode = currentNode.getNextSibling();
            }
            while ((currentNode != null) && (currentNode.getNodeType() != NodeType.RUN));
        }
        // Split the last run that contains the match if there is any text left.
        if ((currentNode != null) && (remainingLength > 0))
        {
            splitRun((Run)currentNode, remainingLength);
            runs.add(currentNode);
        }
        builder.moveTo((Run)runs.get(0));
        builder.insertHtml(value);
        for (Run run : (Iterable) runs){
            run.remove();
        }
        // Signal to the replace engine to do nothing because we have already done all what we wanted.
        return ReplaceAction.SKIP;
    }
}

Wow,

thanks a lot Tahir.

It works like a charm

You guys rock!

Hi Scherge,

Thanks for your feedback. Please feel free to ask if you have any question about Aspose.Words, we will be happy to help you.