1

Below is Google's example for emboldening a partial text element. This is used for selected text that is not an entire element (e.g. just a sentence fragment is selected). I need to replace the action of emboldening with that of performing a regex replacement. The replaceText() function does not accept integers to tell it where to start and end (unlike the setBold() function).

This is a very similar (unanswered) question, but I believe Google Scripts has changed some of the commands, so I thought it worth posting again.

The Google example is:

// Bold all selected text.
var selection = DocumentApp.getActiveDocument().getSelection();
if (selection) {
  var elements = selection.getRangeElements();
  for (var i = 0; i < elements.length; i++) {
    var element = elements[i];

    // Only modify elements that can be edited as text; skip images and other non-text elements.
    if (element.getElement().editAsText) {
      var text = element.getElement().editAsText();

      // Bold the selected part of the element, or the full element if it's completely selected.
      if (element.isPartial()) {
        text.setBold(element.getStartOffset(), element.getEndOffsetInclusive(), true);
      } else {
        text.setBold(true);
      }
    }
  }
}

1 Answer 1

1

The regex implementation of replaceText method does not support lookarounds or capture groups, which makes it impossible to perform such partial replacement with it.

A workaround is to use a JavaScript replacement to prepare new substring, and then put it in place with replaceText. This preserves the formatting of text, even if, say, italicized part overlaps the selection where replacement happens. A potential drawback is that if the element contains a piece of text identical to the selection, replacement will happen there as well.

var text = element.getElement().editAsText();
if (element.isPartial()) {
  var start = element.getStartOffset();
  var finish = element.getEndOffsetInclusive() + 1; 
  var oldText = text.getText().slice(start, finish);
  var newText = oldText.replace(/a/g, "b");
  text.replaceText(oldText, newText);  
}
Sign up to request clarification or add additional context in comments.

2 Comments

This is a great solution. Unfortunately, it fails in the one thing I need it for (not mentioned). It fails if there are line breaks in the selection, since they are not preserved in getText and are therefore not found in replaceText function. So frustrating!
your answer works perfectly when you replace the final replaceText with text.deleteText(start, finish); followed by text.insertText(start, newText);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.