Hello, I have a similar functionality that requires to replace text with bookmark. I’m using Aspose Android via Java. The code works fine except that in certain scenario, it will have an error like this, depending on the text length. One of the sample text I’ve used is this “%SIGNATUREBG%Hellohi%SIGNATUREBG%”
“java.lang.StringIndexOutOfBoundsException: length=13; index=20”
The exception is thrown on this line of code:
afterRun.text = run.text.substring(position)
On the first time it replaces, it is fine. It is the 2nd time when it tries to replace, then it will throw the exception.
Here are the code snipplets in Kotlin:
val signatureBookmarkOptions = FindReplaceOptions()
signatureBookmarkOptions.direction = FindReplaceDirection.FORWARD
signatureBookmarkOptions.replacingCallback = ReplacingCallbackImpl()
templateDocument.range.replace("%SIGNATUREBG%",
"",
signatureBookmarkOptions,
)
ReplacingCallbackImpl
internal class ReplacingCallbackImpl : IReplacingCallback {
var i = 0
@Throws(java.lang.Exception::class)
override fun replacing(e: ReplacingArgs): Int {
var currentNode = e.matchNode
if (e.matchOffset > 0) {
currentNode = splitRun(currentNode as Run, e.matchOffset)
}
val runs = ArrayList<Any>()
// Find all runs that contain parts of the match string.
var remainingLength = e.match.group().length
while (remainingLength > 0 && currentNode != null &&
currentNode.text.length <= remainingLength) {
runs.add(currentNode)
remainingLength -= currentNode.text.length
do {
currentNode = currentNode!!.nextSibling
} while (currentNode != null && currentNode.nodeType !== NodeType.RUN)
}
if (currentNode != null && remainingLength > 0) {
splitRun(currentNode as Run, remainingLength)
runs.add(currentNode)
}
val builder = DocumentBuilder(e.matchNode.document as Document)
builder.moveTo(runs[0] as Run)
val name = e.match.group(0).substring(1, e.match.group(0).length - 1) + i++
builder.startBookmark(name)
builder.endBookmark(name)
for (run in runs as Iterable<Run>) {
run.remove()
}
return ReplaceAction.SKIP
}
@Throws(java.lang.Exception::class)
private fun splitRun(run: Run, position: Int): Run? {
val afterRun = run.deepClone(true) as Run
afterRun.text = run.text.substring(position)
run.text = run.text.substring(0, position)
run.parentNode.insertAfter(afterRun, run)
return afterRun
}
}
What I’m trying to achieve is to convert “%SIGNATUREBG%Hellohi%SIGNATUREBG%” to “Hellohi”, but inserting 2 bookmarks respectively before and after “Hellohi”.
Please advise, thank you :).