Google-apps-script – Convert all links to images in a Google Document with actual images

google docsgoogle-apps-script

I've got a few Google Docs that contain some paragraphs of text and multiple Drive links in the following format:

https://drive.google.com/open?id=XXXX

How can I use a script to replace all the links in the Google Doc with the images that the links direct to?

Best Answer

Here is a script for this purpose. It uses findText method to locate the links. Once a link is found, the element containing it is inspected: its text content is matched again against the link format, this time using string match method of plain JavaScript. The reason is that findText does not offer an easy way to retrieve the content that was actually matched...

Anyway, once the id is obtained from text.match, the image is acquired and appended to the element's parent. The logic is that the element we are looking at is probably Text, and Text cannot contain other elements. So the parent (probably Paragraph) is used instead.

The appendInlineImage method appends it at the end of paragraph. There is also insertInlineImage which allows for finer positioning, but it operates in terms of element index, not text offset. To my inderstanding, to insert an image directly where its URL is found, one would have to replace the original Text element by two, putting an image in between two pieces. This seemed too complicated to me, so I left it at appendInlineImage.

At the very end, all matching URLs are removed with replaceText method.

function replaceLinksByImages() {
  var searchPattern = "https://drive.google.com/open\\?id=\\w+";
  var body = DocumentApp.getActiveDocument().getBody();
  var found = body.findText(searchPattern); 
  while (found) {
    var elem = found.getElement();
    var text = elem.getText();
    var match = text.match(/https:\/\/drive.google.com\/open\?id=(\w+)/);
    if (match) {
      var id = match[1];
      var image = DriveApp.getFileById(id).getBlob();
      elem.getParent().appendInlineImage(image);
    }
    found = body.findText(searchPattern, found);
  }
  body.replaceText(searchPattern, "");
}