获取第一个超链接及其文本值 [英] Get the first hyperlink and its text value
问题描述
我希望每个人都身体健康,状况良好.最近,我一直在使用应用程序脚本来研究Google Docs超链接,并一直学习.我试图获取所有超链接并对其进行编辑,为此我从发布.我已经阅读了多次代码,现在我对它的工作方式有了很好的了解.
我的困惑
我的困惑是这段代码中发生的递归过程,尽管我熟悉递归函数的概念,但是当我尝试修改代码以仅从文档中获取第一个超链接时,我不明白如何在没有递归的情况下实现该过程.破坏递归函数.
这是我正在尝试的代码;
I hope everyone is in good health health and condition.
Recently, I have been working on Google Docs hyperlinks using app scripts and learning along the way. I was trying to get all hyperlink and edit them and for that I found an amazing code from this post. I have read the code multiple times and now I have a good understanding of how it works.
My confusion
My confusion is the recursive process happening in this code, although I am familiar with the concept of Recursive functions but when I try to modify to code to get only the first hyperlink from the document, I could not understand it how could I achieve that without breaking the recursive function.
Here is the code that I am trying ;
/**
* 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} 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;
}
我尝试添加
I tried adding
if (links.length > 0){
return links;
}
,但是它不会停止该函数,因为它是递归的,它会返回到先前的调用并继续运行.这是测试文档以及我正在使用的脚本.
https://docs.google.com/document/d/1eRvnR2NCdsO94C5nqedit?usp = sharing
希望您能理解我要传达的内容,感谢您浏览我的帖子.保持快乐:D
but it does not stop the function as it is recursive and it return back to its previous calls and continue running.
Here is the test document along with its script that I am working on.
https://docs.google.com/document/d/1eRvnR2NCdsO94C5nqly4nRXCttNziGhwgR99jElcJ_I/edit?usp=sharing
I hope you will understand what I am trying to convey, Thanks for giving a look at my post. Stay happy :D
推荐答案
我相信您的目标如下.
- 您要使用Google Apps脚本从共享文档中检索第一个链接和链接文本.
- 您要在检索第一个元素时停止递归循环.
我尝试添加
if (links.length > 0){
return links;
}
但是它不会停止该函数,因为它是递归的,它会返回到先前的调用并继续运行.
but it does not stop the function as it is recursive and it return back to its previous calls and continue running.
不幸的是,关于此,我不明白您将脚本放在脚本的什么位置.在这种情况下,我认为当 links
具有该值时,必须停止循环.并且,还需要检索文本.那么,如何进行如下修改?我修改了脚本中的3个部分.
About this, unfortunately, I couldn't understand where you put the script in your script. In this case, I think that it is required to stop the loop when links
has the value. And also, it is required to also retrieve the text. So, how about modifying as follows? I modified 3 parts in your script.
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++) {
if (links.length > 0) break; // <--- Added
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;
curUrl.text = text.slice(curUrl.startOffset, curUrl.endOffsetInclusive + 1); // <--- Added
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++) {
if (links.length > 0) { // <--- Added or if (links.length > 0) break;
return links;
}
links = links.concat(getAllLinks(element.getChild(i)));
}
}
return links;
}
- 在这种情况下,我认为
if(links.length> 0){return links;}
可以修改为if(links.length> 0)break;
. - In this case, I think that
if (links.length > 0) {return links;}
can be modified toif (links.length > 0) break;
. -
顺便说一句,当使用Google Docs API时,链接和文本都可以通过一个简单的脚本进行检索,如下所示.使用此功能时,请在高级Google服务中启用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]).
}
这篇关于获取第一个超链接及其文本值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!