Google Docs API-完整的文档(超链接问题) [英] Google Docs API - complete documentation (hyperlink issue)

查看:149
本文介绍了Google Docs API-完整的文档(超链接问题)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望每个人都身体健康.这篇文章是我以前的帖子

我的主要目标

因此,主要目标是获取超链接并将其链接的文本更改为超链接.我最初使用了 post 中的代码,并对其进行了修改以更改第一个文本超链接.这是我修改后的代码,用于更改第一个超链接的文本.

  function onOpen(){const ui = DocumentApp.getUi();ui.createMenu('做什么?').addItem('HyperLink Modifier','findAndReplacetext').addToUi();}/***获取文档中所有LinkUrl的数组.该功能是*递归,如果未提供任何元素,则默认为*活动文档的正文"元素.** @param元素要操作的document元素.*.* @returns {Array}对象数组,可见*                              {元素,* startOffset,* endOffsetInclusive,* url}*/函数getAllLinks(element){var links = [];元素=元素||DocumentApp.getActiveDocument().getBody();如果(element.getType()=== DocumentApp.ElementType.TEXT){var textObj = element.editAsText();var text = element.getText();var inUrl = false;for(var ch = 0; ch< text.length; ch ++){var url = textObj.getLinkUrl(ch);if(url!= null){如果(!inUrl){//我们到了!inUrl = true;var curUrl = {};curUrl.element =元素;curUrl.url = String(url);//获取副本curUrl.startOffset = ch;}别的 {curUrl.endOffsetInclusive = ch;}}别的 {如果(inUrl){//再也没有了,我们不是.inUrl = false;links.push(curUrl);//添加到链接curUrl = {};}}}如果(inUrl){//如果链接以与元素相同的字符结尾links.push(curUrl);}}别的 {var numChildren = element.getNumChildren();对于(var i = 0; i< numChildren; i ++){links = links.concat(getAllLinks(element.getChild(i)));}}返回链接;}/***替换文档中的全部或部分UrlLinks.** @param {String} searchPattern用来搜索正则表达式的模式* @param {String}替换文本以用作替换** @returns {Number}个Urls数已更改*/函数findAndReplacetext(){var links = getAllLinks();while(links.length> 0){var link = links [0];var段落= link.element.getText();var linkText = paragraph.substring(link.startOffset,link.endOffsetInclusive + 1);var newlinkText =`($ {linkText})[$ {link.url}]`link.element.deleteText(link.startOffset,link.endOffsetInclusive);link.element.insertText(link.startOffset,newlinkText);links = getAllLinks();}}String.prototype.betterReplace = function(search,replace,position){如果(this.length>位置){返回this.slice(0,position)+ this.slice(position).replace(search,replace);}返回这个;} 

注意::我使用了 insertText deleteText 函数来更新超链接的文本值.

我上面的代码有问题

现在的问题是此代码运行太慢.我想可能是因为我每次都需要运行脚本来搜索下一个超链接,所以也许我可以打破循环,每次只获得第一个超链接.
然后从我之前的帖子我是一个打破循环并仅获得第一个超链接的解决方案,但是不幸的是,当我尝试新代码时,它仍然很慢.在那篇文章中,他还通过使用Google Docs API向我提出了一种新方法,我尝试使用该方法超级快.这是使用 Google Docs API

的代码

  function myFunction(){const doc = DocumentApp.getActiveDocument();const res = Docs.Documents.get(doc.getId()).body.content.reduce((ar,{paragraph})=> {如果(段落&&段落.元素){段.elements.forEach(({textRun})=> {如果(textRun&& textRun.textStyle&& textRun.textStyle.link){ar.push({text:textRun.content,url:textRun.textStyle.link.url});}});}返回ar;},[]);console.log(res)//您可以检索第一个链接并通过console.log(res [0])进行测试.} 

我的新问题

我喜欢新代码,但由于无法找到与超级链接关联的文本,我再次陷入困境.我尝试使用功能 setContent setUrl ,但是它们似乎不起作用.另外,我在主文档上找不到这些功能的文档.该API的代码.我确实在此处中找到了前面提到的功能的参考文献,但是它们不适用于appscript.
这是我正在处理的示例文档
https://docs.google.com/document/d/1eRvnR2NCdsO94C5nqedit?usp = sharing

尾注:

我希望我能够完整地传达我的信息以及与之相关的所有细节.如果不是很好,请不要生我的气,我仍在学习过程中,我的英语能力也很弱.无论如何,如果您需要任何其他数据,请在评论中让我知道,感谢您抽出宝贵的时间.

解决方案

要从文档中删除所有超链接,可以执行以下操作:

  • 首先,检索这些超链接的开始 end 索引.可以通过调用 documents.get 来完成,遍历正文内容中的所有元素,检查哪些是段落,遍历相应的 batchUpdate 制作 UpdateTextStyleRequest .您想要删除每对索引之间的 link 属性,为此,您只需要将 fields 设置为 link (为了指定要更新的属性),并且不要在请求中提供的 textStyle 属性中设置 link 属性,因为

    I hope everyone is in good health. This post is my continue of my previous post

    My main goal

    So main goal was to get the hyperlink and change it the text linked with it. I initially used code from this post and modified it to change the text of first hyperlink. Here is my modified code to change the text of first hyperlink.

    function onOpen() {
      const ui = DocumentApp.getUi();
      ui.createMenu('What to do?')
        .addItem('HyperLink Modifier', 'findAndReplacetext')
        .addToUi();
    }
    
    
    /**
     * Get an array of all LinkUrls in the document. The function is
     * recursive, and if no element is provided, it will default to
     * the active document's Body element.
     *
     * @param    element The document element to operate on. 
     * .
     * @returns {Array}         Array of objects, vis
     *                              {element,
     *                               startOffset,
     *                               endOffsetInclusive, 
     *                               url}
     */
    function getAllLinks(element) {
      var links = [];
      element = element || DocumentApp.getActiveDocument().getBody();
      
      if (element.getType() === DocumentApp.ElementType.TEXT) {
        var textObj = element.editAsText();
        var text = element.getText();
        var inUrl = false;
        for (var ch=0; ch < text.length; ch++) {
          var url = textObj.getLinkUrl(ch);
          if (url != null) {
            if (!inUrl) {
              // We are now!
              inUrl = true;
              var curUrl = {};
              curUrl.element = element;
              curUrl.url = String( url ); // grab a copy
              curUrl.startOffset = ch;
            }
            else {
              curUrl.endOffsetInclusive = ch;
            }          
          }
          else {
            if (inUrl) {
              // Not any more, we're not.
              inUrl = false;
              links.push(curUrl);  // add to links
              curUrl = {};
            }
          }
        }
        if (inUrl) {
          // in case the link ends on the same char that the element does
          links.push(curUrl); 
        }
      }
      else {
        var numChildren = element.getNumChildren();
        for (var i=0; i<numChildren; i++) {
          links = links.concat(getAllLinks(element.getChild(i)));
        }
      }
      return links;
    }
    
    /**
     * Replace all or part of UrlLinks in the document.
     *
     * @param {String} searchPattern    the regex pattern to search for 
     * @param {String} replacement      the text to use as replacement
     *
     * @returns {Number}                number of Urls changed 
     */
    
    function findAndReplacetext() {
        var links = getAllLinks();
        while(links.length > 0){
          var link = links[0];
          var paragraph = link.element.getText();
          var linkText = paragraph.substring(link.startOffset, link.endOffsetInclusive+1);
          var newlinkText = `(${linkText})[${link.url}]`
          link.element.deleteText(link.startOffset, link.endOffsetInclusive);
          link.element.insertText(link.startOffset, newlinkText);
          links = getAllLinks();
        }
    }
    
    String.prototype.betterReplace = function(search, replace, position) {
      if (this.length > position) {
        return this.slice(0, position) + this.slice(position).replace(search, replace);
      }
      return this;
    }
    

    Note: I used insertText and deleteText functions to update the text value of hyperlink.

    My problem with above code

    Now the problem was that this code was running too slow. I thought may be it was because I was running the script every-time I needed to search for next hyperlink, So maybe I can break the loop and only get the first hyperlink each time.
    Then from my previous post the guy gave me a solution to break loop and only get the first hyperlink but when I tried the new code unfortunately it was still slow. In that post he also proposed me a new method by using Google Docs API, I tried using that it was was super fast. Here is the code using Google Docs API

    function myFunction() {
        const doc = DocumentApp.getActiveDocument();
        const res = Docs.Documents.get(doc.getId()).body.content.reduce((ar, {paragraph}) => {
          if (paragraph && paragraph.elements) {
            paragraph.elements.forEach(({textRun}) => {
              if (textRun && textRun.textStyle && textRun.textStyle.link) {
                ar.push({text: textRun.content, url: textRun.textStyle.link.url});
              }
            });
          }
          return ar;
        }, []);
        console.log(res)  // You can retrieve 1st link and test by console.log(res[0]).
      }
    

    My new problem

    I liked the new code but I am stuck again at this point as I am unable to find how can I change the text associated with the hyperlink. I tried using the functions setContent and setUrl but they don't seem to work. Also I am unable to find the documentation for these functions on main documentation of this API. I did find I reference for previously mentioned functions here but they are not available for appscript.
    Here is the sample document I am working on
    https://docs.google.com/document/d/1eRvnR2NCdsO94C5nqly4nRXCttNziGhwgR99jElcJ_I/edit?usp=sharing

    End note:

    I hope I was able to completly convey my message and all the details assosiated with it. If not kindly don't be mad at me, I am still in learning process and my English skills are pretty weak. Anyway if you want any other data let me know in the comments and Thanks for giving your time I really appreciate that.

    解决方案

    In order to remove all the hyperlink from your document, you can do the following:

    • First, retrieve the start and end indexes of these hyperlinks. This can be done by calling documents.get, iterate through all elements in the body content, checking which ones are paragraphs, iterating through the corresponding TextRun, and checking which TextRuns contain a TextStyle with a link property. All this is already done in the code you provided in your question.
    • Next, for all TextRuns that include a link, retrieve their startIndex and endIndex.
    • Using these retrieved indexes, call batchUpdate to make an UpdateTextStyleRequest. You want to remove the link property between each pair of indexes, and for that you would just need to set fields to link (in order to specify which properties you want to update) and don't set a link property in the textStyle property you provide in the request since, as the docs for TextStyle say:

    link: If unset, there is no link.

    Code sample:

    function removeHyperlinks() {
      const doc = DocumentApp.getActiveDocument();
      const hyperlinkIndexes = Docs.Documents.get(doc.getId()).body.content.reduce((ar, {paragraph}) => {
        if (paragraph && paragraph.elements) {
          paragraph.elements.forEach(element => {
            const textRun = element.textRun;
            if (textRun && textRun.textStyle && textRun.textStyle.link) {
              ar.push({startIndex: element.startIndex, endIndex: element.endIndex });
            }
          });
        }
        return ar;
      }, []);
      hyperlinkIndexes.forEach(hyperlinkIndex => {
        const resourceUpdateStyle = {
          requests: [
            {
              updateTextStyle: {
                textStyle: {},
                fields: "link",
                range: {
                  startIndex: hyperlinkIndex.startIndex,
                  endIndex: hyperlinkIndex.endIndex
                }
              }
            }
          ]    
        }
        Docs.Documents.batchUpdate(resourceUpdateStyle, doc.getId());
      });
    }
    

    这篇关于Google Docs API-完整的文档(超链接问题)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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