如何在Google apps-script中为子段落元素添加命名范围



我想在Google文档中实现一个'html-span-like'功能,但每当我尝试将NamedRange添加到Google文档中的文本子字符串时,该范围将与同一段落中的先前文本合并。

结果,NamedRange应用于整个段落。

下面是我的测试用例:

function createTextNamedRange(){
  // Retrieve the current document's body
  var doc = DocumentApp.getActiveDocument();
  var docBody = doc.getBody();
  // Add a new paragraph with text {NotNamed}
  var para = docBody.appendParagraph('{NotNamed}');
  // Append some text that will be named ( .appendText() method returns a Text element )
  var textElem = para.appendText('{NamedText}');
  // Build a range for the Text element
  var range=doc.newRange().addElement(textElem).build();
  // Name the range and append it to the document
  doc.addNamedRange('myNamedRange',range);
}

然后在此函数中使用Logger类显示NamedRange的内容:

function getTextNamedRange(){
  // Retrieve the named range
  var namedRanges =    DocumentApp.getActiveDocument().getNamedRanges();
  // Iterate through each instance of name 'myNamedRange' (there's only one)
  for (var nr in namedRanges){
    var namedRange = namedRanges[nr];
    // A range may contain several RangeElements, iterate through them
    var rangeElements = namedRange.getRange().getRangeElements();
    for(var re in rangeElements) {
      // Get the text of each RangeElement and display it in the logger
      var text = rangeElements[re].getElement().asText().getText();
      Logger.log('Text with namedRange (' + namedRange.getName() + ') : "' + text +'"');
    }
  }
}

我假设得到{NamedText}作为输出,但日志窗口告诉这个:

Text with namedRange (myNamedRange) : "{NotNamed}{NamedText}"

可以看到,这个范围既适用于命名文本,也适用于未标记文本。

我在下面找到了一个详细的解决方案,但它绝对不符合我的口味:它包括在.appendText()调用之间添加空的内联图像。这样,文本元素就不会合并。

我还在寻找更好的解决方案。

以下是WORKAROUND仅,但似乎工作。

它依赖于必须命名的Text块之前和之后的InlineImage插入。

防止NamedRangeParagraph中的Text块中合并

function createTextNamedRangeWorkaround(){
  // WORKAROUND: prevent the Text Merging (and hence the NamedRange merging)
  // by separating Text Elements with blank Inline Images
  // Import a blank PNG file
  // NOTE: This shouldn't be fetched each time 
  //       but only once and passed as an argument
  var blankImage = UrlFetchApp.fetch('http://upload.wikimedia.org/wikipedia/commons/d/d2/Blank.png');
  // Retrieve the current document's body
  var doc = DocumentApp.getActiveDocument();
  var docBody = doc.getBody();
  // Add a new paragraph with text {NotNamed}
  var para = docBody.appendParagraph('{NotNamed}');
  // WORKAROUND HERE : 
  para.appendInlineImage(blankImage.getBlob());
  // Append some text
  var textElem1 = para.appendText('{NamedText1}');
  // WORKAROUND HERE : 
  para.appendInlineImage(blankImage.getBlob());
  // Append some text
  var textElem2 = para.appendText('{NamedText2}');
  // Build Named ranges after text insertion (see notice below)
  var range1=doc.newRange().addElement(textElem1).build();
  // Name the range and append it to the document
  doc.addNamedRange('Range1',range1);
  var range2=doc.newRange().addElement(textElem2).build();
  // Name the range and append it to the document
  doc.addNamedRange('Range2',range2);
}

执行后,文档附加一个新段落,该段落包含三个由两个空白内联png分隔的单词

{NotNamed}{NamedText1}{NamedText2}

和我的getTextNamedRange()的执行显示所需的行为:

Text with namedRange (Range1) : "{NamedText1}"
Text with namedRange (Range2) : "{NamedText2}"

重要注意事项:

  • 命名范围必须在最后一次Text插入之后全部应用,否则,之前的NamedRanges将采用新的插入和追加。

  • InlineImages不能使用image.removeFromParent()从父Paragraph中删除,因为这会导致Text元素(和NamedRange)再次合并

相关内容

  • 没有找到相关文章

最新更新