DavidR
DavidR

Reputation: 369

Regex replacement within a partial text element in google apps script

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);
      }
    }
  }
}

Upvotes: 1

Views: 536

Answers (1)

user3717023
user3717023

Reputation:

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);  
}

Upvotes: 1

Related Questions