PositionedImage Support introduced in Google Apps Script

Issue 1529, programmatic support of “Fixed Images”, has been fixed. As of December 2015, Google Apps Script can manipulate PositionedImage objects in Google Docs. Previously, we only had control over InlineImages via our scripts, so this is good news.

There are some hiccups with the introduction of this new feature, though, so this article aims to help programmers get quickly acquainted with it.

Note: This post is information I have concurrently posted on Stack Overflow.

PositionedImages behave a little differently than InlineImage elements, as they need to be anchored to a ListItem or Paragraph element, while InlineImages can be added only to Body, FooterSection, HeaderSection or TableCell elements.

A PositionedImage is an object anchored in an element, while an InlineImage is itself an element of a document. This implies that you cannot convert one type of image directly to the other. (When you switch an image from “Wrap text” to “Inline” using the UI, the PositionedImage is removed from its anchor paragraph, then inserted into the body of the document outside of that paragraph. You could emulate that via script if necessary.)

Insert a PositionedImageScreenshot

Here you can see an example of a PositionedImage inserted by the following script. By default, the image will be set with “Wrap text” enabled, and have no margins. As we’ll see later, we also have programmatic control over those image attributes.

The log shows the ID of the new image, like this:

[15-12-11 20:35:03:706 EST] kix.9dwnzjfapdy8

Be careful – if you add multiple images to the same element (e.g. Paragraph), with default layout, the newest image will overlay existing ones. Therefore, it may look like you have a single image when there are actually a pile of them.

Retrieve existing PositionedImages

Since a PositionedImage is not an element of a document, it does not appear in the element hierarchy with elements like paragraphs, tables, or InlineImages, and cannot be found through the document methods getChild(), getNextSibling(), and so on. Likewise, there is no Body.getPositionedImages() to parallel Body.getImages().

Instead, you can get a PositionedImage using its unique ID, e.g. kix.9dwnzjfapdy8 from the earlier example.

var positionedImage = getPositionedImage(storedId);

Alternatively, you can get all the PositionedImage objects in a containing element as an array.

var positionedImages = getPositionedImages();
for (var i=0; i<positionedImages.length; i++) {
  Logger.log( positionedImages[i].getId() );
}

Retrieving all the PositionedImages in a document requires traversing all the possible anchor elements. The following utility does just that.

Layout control

Most of the layout controls for PositionedImages are well described in the documentation:

The PositionedLayout enum used with the Layout methods is unique to PositionedImages. At the time of launch of PositionedImage support however, it was not included in editor autocompletion, and the documentation contained no examples of its use. Let’s fill that gap.

Here’s how you can set the layout of a PositionedImage so that it is wrapped by text:

positionedImage.setLayout( DocumentApp.PositionedLayout.WRAP_TEXT );

The following utility function gets the English equivalent of a PositionedLayout enum.

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s