在 google 文档中的选择中应用 google 应用脚本代码

Applying google app script code in selection in google docs

我有以下代码,将整个 google 文档中的一些关键字加粗:

function boldKeywords() {
  // Words that will be put in bold:
  var keywords = ["end", "proc", "fun"];

  var document = DocumentApp.getActiveDocument();
  var body = document.getBody();

  var Style = {};
  Style[DocumentApp.Attribute.BOLD] = true;

  for (j in keywords) {

    var found = body.findText(keywords[j]);

    while(found != null) {
      var foundText = found.getElement().asText();
      var start = found.getStartOffset();
      var end = found.getEndOffsetInclusive();
      foundText.setAttributes(start, end, Style)
      found = body.findText(keywords[j], found);
    }
  }

}

但我希望代码仅在文档的选定区域以粗体显示关键字,为此,我尝试使用函数 getSelection(),但我遇到的问题是此函数 returns一个Range,但是为了申请findText我需要一个Body,有人知道我能做什么吗?

修改脚本

function boldKeywordsInSelection() {
  const keywords = ["end", "proc", "fun"];
  const document = DocumentApp.getActiveDocument();
  const selection = document.getSelection();

   // get a list of all the different range elements
  const rangeElements = selection.getRangeElements();

  const Style = {};
  Style[DocumentApp.Attribute.BOLD] = true;

  // forEach used here because for in was giving me trouble...
  rangeElements.forEach(rangeElement => {

    // Each range element has a corresponding element (e.g. paragraph)
    const parentElement = rangeElement.getElement();

    // fixing the limits of the bold operations depending on the selection
    const startLimit = rangeElement.getStartOffset();
    const endLimit = rangeElement.getEndOffsetInclusive();

    for (j in keywords) {
      let found = parentElement.findText(keywords[j]);
      // wrapping in try catch to escape the for loop from within the while loop
      try {
        while (found != null) {
          const foundText = found.getElement().asText();
          const start = found.getStartOffset();
          // Checking if the start of the word is after the start of the selection
          if (start < startLimit) {
            // If so, then skip to next word
            found = parentElement.findText(keywords[j], found);
            continue;
          }
          // Checking if the start of the word is after the end of the selection
          // if so, go to next element
          if (start > endLimit) throw "out of selection";
          const end = found.getEndOffsetInclusive();

          foundText.setAttributes(start, end, Style)
          found = parentElement.findText(keywords[j], found);
        }
      } catch (e) {
        Logger.log(e)
        continue;
      }
    }
  })
}

查看代码中的注释了解更多详情。

A getSelection 生成一个 Range 对象,其中包含 RangeElement 的各种实例。每个 RangeElement 引用一个父元素,以及该父元素中的索引位置。父元素是范围元素所属的元素。例如:

此选择跨越 3 个元素。因此选择有 3 个范围元素。您只能对整个元素使用 findText 方法,不能对范围元素使用。

这意味着脚本的流程大致相同,只是您需要遍历每个元素并在每个元素中找到文本。由于这会将 个元素 选择之外,因此您需要跟踪选择和找到的元素的索引位置,并确保找到的元素在选择。

参考资料