如何在Google Apps脚本的子段落元素中添加命名范围 [英] How to add Named Ranges to sub-paragraph elements in Google apps-script

查看:35
本文介绍了如何在Google Apps脚本的子段落元素中添加命名范围的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在Google文档中实现类似于html跨度"的功能,但是每当我尝试向Google文档中的文本子字符串添加 NamedRange 时,该范围就会与同一段中的上一个文本.

I would like to implement a 'html-span-like' feature inside Google Documents but whenever I try to add a NamedRange to a substring of text inside a Google Document, the range is merged with previous text in the same paragraph.

结果,将 NamedRange 应用于整个段落.

In result, the NamedRange is applied to the whole paragraph.

这是我的测试用例:

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 的内容:

I then display the content of the NamedRange using the Logger class in this function:

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} 作为输出,但日志窗口"会告诉您:

I would assume to get {NamedText} as an output but the Log Window tells this:

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

可以看出,该范围已应用于未标记和已命名的文本.

As it can be seen, the range was applied to the unmarked as well as the named text.

我发现了下面详细介绍的解决方法,但这绝对不符合我的口味:它包括在两个 .appendText()调用.这样Text元素就不会合并.

I found a workaround detailed below but it's definitely not to my taste: it consists of adding empty inline images between the .appendText() calls. This way the Text elements are not merged.

我仍在寻找更好的解决方案.

I'm still looking for a better solution.

推荐答案

以下内容仅适用于 WORKAROUND ,但似乎可以使用.

The following is for WORKAROUND ONLY but appears to work.

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

It relies on InlineImage insertion before and after the Text chunk that has to be Named.

当将 NamedRange 应用于 paragraph

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分隔

After execution the document is appended with a new paragraph containing three words separated by two blank inline PNGs

{NotNamed}{NamedText1}{NamedText2}

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

And the execution of my getTextNamedRange() shows the desired behaviour:

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

重要通知:

  • 命名范围必须在最后一个 Text 插入之后一起应用,否则,以前的NamedRanges将采用新的插入和附加.

  • Named ranges must be applied alltogether after the last Text insertion, otherwise, previous NamedRanges adopt new insertions and appendings.

InlineImages ,因为这会导致导致 Text元素(和 NamedRange )要再次合并

InlineImages can't be removed from parent Paragraph using image.removeFromParent() because this causes the Text elements (and the NamedRange) to be merged again

这篇关于如何在Google Apps脚本的子段落元素中添加命名范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆