Home > Software design >  Google Apps Script search and replace URL truncates 1 character in rendered link
Google Apps Script search and replace URL truncates 1 character in rendered link

Time:05-23

I'm using the code below to search for URLs in a Google Doc and turn them into active links. It works beautifully, except that the link cuts off the last character of the URL (e.g. "https://link.com/123" gets linked as "https://link.com/12").

function updateLinks() {
  var linkRegex = "https?:\/\/[^\\s]*";

  //Open active doc
  var body = DocumentApp.getActiveDocument().getBody();
  //Find URLs
  var link = body.findText(linkRegex);

  //Loop through the body finding texts matching the search pattern
  while (link != null) {
    // Get the link as an object
    var linkElement = link.getElement().asText();
    // Get the positions of start and end
    var start = link.getStartOffset();
    var end = link.getEndOffsetInclusive();
    //slice only the link out of it
    var correctLink = linkElement.getText().slice(start, end);

    // Format link
    linkElement.setLinkUrl(start, end, correctLink);
    // Find next
    link = body.findText(linkRegex, link);
  }
}

I'm sure this is simple, but I'm a complete novice and would appreciate any advice. Thanks in advance!

CodePudding user response:

Your code is working for me

What do your original files look like?

function updateLinks() {
  var linkRegex = "https?:\/\/[^\\s]*";
  var body = DocumentApp.getActiveDocument().getBody();
  var link = body.findText(linkRegex);
  while (link != null) {
    var linkElement = link.getElement().asText();
    var start = link.getStartOffset();
    var end = link.getEndOffsetInclusive();
    var correctLink = linkElement.getText().slice(start, end);
    linkElement.setLinkUrl(start, end, correctLink);
    link = body.findText(linkRegex, link);
  }
}

CodePudding user response:

I thought that the reason of your issue is due to slice(start, end) of linkElement.getText().slice(start, end). In this case, it is required to be slice(start, end 1). So, please modify it as follows and test it again.

From:

var correctLink = linkElement.getText().slice(start, end);

To:

var correctLink = linkElement.getText().slice(start, end   1);

Or, when you want to use linkRegex, how about the following modification?

var correctLink = linkElement.getText().match(new RegExp(linkRegex))[0];

Note:

  • As additional information, when the multiple URLs are included in a paragraph, I think that the following modification might be useful. Of course, in this modification, even when a single URL is included in a paragraph, the script works.

    • From

        var start = link.getStartOffset();
        var end = link.getEndOffsetInclusive();
        //slice only the link out of it
        var correctLink = linkElement.getText().slice(start, end);
      
        // Format link
        linkElement.setLinkUrl(start, end, correctLink);
      
    • To

        var text = linkElement.getText();
        var correctLinks = [...text.matchAll(new RegExp(linkRegex, "g"))];
        correctLinks.forEach(obj => linkElement.setLinkUrl(obj.index, obj.index   obj[0].length - 1, obj[0]));
      

Reference:

  • Related