如何在文档绑定脚本中查找用户光标的位置

时间:2013-06-06 17:41:32

标签: google-apps-script google-docs

我有一个谷歌应用程序脚本,该脚本与Google文档容器绑定,并从自定义菜单调用。我希望它能够对当前选择的文本采取行动,但我还没有找到一种方法让脚本知道选择了哪些文本。

我希望我可以使这段代码有效。 addMyLink()函数会将自定义网址(基于某些baseUrl)附加到所选文字。

function onOpen() {
  DocumentApp.getUi().createMenu('Linker')
      .addItem('Add awesome link', 'addMyLink')
      .addToUi();
}

function addMyLink(event) {
  var doc = DocumentApp.getActiveDocument();
  var currElement = event.element;
  var currSelection = {
     startOffset: event.startOffset,
     endOffset:   event.endOffset
  };

  // if selected text does not have a link already, add one
  if (currElement.asText().getLinkUrl(currSelection.startOffset) == null) {
    //Logger.log('no link')
    var url = baseUrl.replace('%target%',matchString)
    //Logger.log(url);
    currElement.asText().setLinkUrl(currSelection.startOffset, currSelection.endOffset, url);
  }
}

不幸的是,从自定义菜单调用的函数不会接收事件,因此这段代码只是一个梦想。是否有其他方法可以获取此信息?


我在问题跟踪器上输入了一个新问题,如果您对它感兴趣,请加注:

Issue 2865:获取当前用户位置&文档

中的状态信息

2 个答案:

答案 0 :(得分:2)

截至目前,这是不可能的。如果您观看“将脚本扩展到Google文档”视频,他们会提到此功能即将推出: http://www.youtube.com/watch?v=KIiCSdRCqXc#t=26m59s

答案 1 :(得分:2)

昨天添加了处理光标位置和所选文本的功能,解决了Issue 2865: Get current user location & state information in Document。另请参阅blog post

Google提供的方法与上述问题中描述的方法不同 - 没有事件,而是分别通过Document.getCursor()和Document.getSelection()提供有关光标位置和元素选择的信息。

这里是来自问题的代码,适用于新的API。在此示例中,您可以选择文档中的任何文本,并使用所选文本添加指向Google搜索的链接。

/**
 * If user has selected text, add a url link there, unless
 * the text already has a link.
 */
function addMyLink() {
  var doc = DocumentApp.getActiveDocument();
  var selection = doc.getSelection();

  // get a URL pattern containing %target%.
  // For this example, assume we want to build a google query
  var baseUrl = "https://www.google.com/search?q=%target%";

  if (!selection) {
    tryAgain( "No current selection." );
  }
  else {
    var elements = selection.getSelectedElements();

    // We'll only put a hyperlink on text within a paragraph - if the selection
    // spans paragraphs, reject it.
    if (elements.length > 1) { tryAgain( "Selection cannot span paragraphs." ); return;}

    var element = elements[0].getElement();
    var elementText = element.asText();
    var startOffset = elements[0].getStartOffset();      // -1 if whole element
    var endOffset = elements[0].getEndOffsetInclusive(); // -1 if whole element
    var selectedText = element.asText().getText();       // All text from element
    // Is only part of the element selected?
    if (elements[0].isPartial())
      selectedText = selectedText.substring(startOffset,endOffset+1);

    // Google Doc UI "word selection" (double click) selects trailing spaces - trim them
    selectedText  = selectedText.trim();
    endOffset = startOffset + selectedText.length - 1;

    // If you have poo, fling it now...
    // I mean - if you have other validation steps, put them here.

    // Check if there's a link here already.
    // Caveat: if there a link that starts INSIDE the selection,
    // this won't find it.
    if (elementText.getLinkUrl(startOffset) == null) {
       // Generate the URL, and set it on the selected text
       var url = baseUrl.replace('%target%',selectedText);
      elementText.setLinkUrl(startOffset, endOffset, url);
    }
    else {
      tryAgain( "Remove existing link first." );
    }
  }
}


/*
 * Use Dialog Box to deliver a message to user, with
 * "try again" message.
 *
 * @param {String} message The message to display in the dialog box
 *
 * @return {Button} The button the user clicked
 */
function tryAgain ( message ) {
  var ui = DocumentApp.getUi();
  return ui.alert("Please try again",message,ui.ButtonSet.OK);
}

function onOpen() {
  DocumentApp.getUi().createMenu('Selection')
    .addItem("Add Google Link", 'addMyLink' )
    .addToUi();
}