I need to replace the word without affecting hyperlink (hyperlink must be preserved for the replaced word) and those with non hyperlinks the replace must happen in a regular way.
Here is the link of the coded Docs
I have tried with
function run() {
var findtext = "Search";
var replacetext = "Replacer";
var body = DocumentApp.getActiveDocument().getBody();
var foundElement = body.findText(findtext);
while (foundElement != null) {
var foundText = foundElement.getElement().asText();
var startOffset = foundElement.getStartOffset();
var endOffsetInclusive = foundElement.getEndOffsetInclusive();
var hyperlink = foundText.getLinkUrl(0);
foundText.insertText(0, findtext);
foundText.setLinkUrl(startOffset + findtext.length, endOffsetInclusive + findtext.length, hyperlink);
foundText.deleteText(startOffset + findtext.length, endOffsetInclusive + findtext.length)
foundElement = body.findText(findtext, foundElement);
}
}
findText
as a word.It is tricky because you can't get a "word" element. You have to:
findText
returns. This contains the search result.For example:
foundText.insertText(0, findtext)
Inserts the text you are looking for, i.e. "Search", at the start of the element which the result is in.
This:
var hyperlink = foundText.getLinkUrl(0)
This will only get the hyperlink found at the start of the paragraph, for example, which means that if the first word of the paragraph has a hyperlink, this is what it will return. In getLinkUrl()
you should use the start index of the search result.
This code will replace text and will keep the hyperlink, if it has one.
function replaceTextKeepHyperlink(textToReplace, ReplacementText) {
var body = DocumentApp.getActiveDocument().getBody();
var searchResult = body.findText(textToReplace);
while (searchResult != null) {
// Getting info about result
var foundText = searchResult.getElement().asText();
var start = searchResult.getStartOffset();
var end = searchResult.getEndOffsetInclusive();
var hyperlink = searchResult.getElement().getLinkUrl(start);
// Modifying text
foundText.deleteText(start, end)
foundText.insertText(start, ReplacementText)
foundText.setLinkUrl(start, start + ReplacementText.length - 1, hyperlink)
// Moving to next search result
searchResult = body.findText(textToReplace, searchResult);
}
}
It will not keep any other formatting though, so for that you would have add in some lines to the "Getting info" and "Modifying" parts of the code.
mshcruz found that if you called the function with parameters like this:
replaceTextKeepHyperlink("Search", "PrefixedSearch")
The function gets caught in an infinite loop, because it finds the text its looking for in the text its just replaced, replaces that part, and on and on.
He provided the fix which is incorporated below with a try block to avoid the error that it produces if a textToReplace
is found at the end of the document:
function replaceTextKeepHyperlink(textToReplace, ReplacementText) {
var body = DocumentApp.getActiveDocument().getBody();
var searchResult = body.findText(textToReplace);
while (searchResult != null) {
var foundText = searchResult.getElement().asText();
var start = searchResult.getStartOffset();
var end = searchResult.getEndOffsetInclusive();
var hyperlink = searchResult.getElement().getLinkUrl(start);
foundText.deleteText(start, end)
foundText.insertText(start, ReplacementText)
foundText.setLinkUrl(start, start + ReplacementText.length - 1, hyperlink)
try {
let rangeBuilder = DocumentApp.getActiveDocument().newRange();
rangeBuilder.addElement(searchResult.getElement(), start, end+ReplacementText.length - 1);
searchResult = rangeBuilder.getRangeElements()[0];
} catch (e){
Logger.log("End of Document")
return null
}
searchResult = body.findText(textToReplace, searchResult);
}
}