Changing the color of all links in Google Slides with Google Apps Script

My goto theme in Google Slides is Material and for the Totally Unscripted show use the ‘one column text’ layout for highlight news/community updates.

TU12 - News and Community Developments Aug 2017

One annoyance with this theme is the text hyperlink color defaults to light blue (HEX: #4FC3F7), which isn’t so great in the sidebar column:

Link colors

You can override the link color in each textbox by formating the text color but it feels like lots of unnecessary clicking. As Google recently announced that there is a Google Slides Service for Google Apps Script I thought I’d have a look at manipulating link colors and share the results in this post.

Not reinventing the wheel

As part of Google’s announcement was the news that Add-ons have been extended to Google Slides. As Slides add-ons are very new there wasn’t anything I could find in the store (although there is Link Style for Google Documents). I also did a quick check of Stack Overflow but again as it’s a new release I couldn’t find anything explicitly for Slides (various posts like this one for Google Documents). Given there was nothing to recycle I ended up on the Slides Service Documentation. From this it’s a case of figuring out what you can access. My technique for approaching new services and APIs is to look at what classes are available. In the case of Slides Service I could see a Link class but this turned out to be a dead end (these appear to be links attached to slide elements rather than inline text links). So rather than starting at the end I started looking from the beginning, so if we .getActivePresentation() using the links in the documentation to see what is returned and the associated methods. So from a Presentation we can use .getSlides() which returns Slide[] and so on. Doing this and with a bit of trial and error you can get down to TextStyle which has a .setForegroundColor() method.

Presentation Reference

Going through this process in the documentation ends up helping is write the code as it’s a similar process of navigating down the object tree. Below is the functional code I eventually came up with:

/**
 * @OnlyCurrentDoc
 */

function changeLinkColorForShapes(){
  var deck = SlidesApp.getActivePresentation();
  var slides = deck.getSlides();
  slides.forEach(function(slide) {
    // https://developers.google.com/apps-script/reference/slides/slide#getPageElements()
    var elements = slide.getPageElements();
    elements.forEach(function(element){
      // https://developers.google.com/apps-script/reference/slides/page-element#getPageElementType()
      var type = element.getPageElementType();
      // Text boxes are 'SHAPES' (this code doesn't handle table cells)
      if (type == "SHAPE"){
        // https://developers.google.com/apps-script/reference/slides/text-range#getTextStyle()
        var textStyle = element.asShape().getText().getTextStyle();
        // https://developers.google.com/apps-script/reference/slides/text-style#hasLink()
        // Returns true if there is link on the text, false if not, or null  
        // if the link is on part of the text or there are multiple links.
        if (textStyle.hasLink() || textStyle.hasLink() == null){
          textStyle.setForegroundColor('#ffffff');
        }
      }
    });
  });
}

If you’d like to text this code you can copy this presentation and open Tools > Script editor… to allow you to run the changeLinkColor() function. After running the link on the slide should change from light blue to white.

Summary

So hopefully you can see one way for navigating the developer documentation. The code above is functional for my purposes but there are a number of improvements you could try out. For example, you might want to extend by into Table/TableCell elements or selectively change the link color using the Layout and .getLeft()/.getWidth() values. One limitation of this approach is it’s changing the entire text holder font color rather so if there is text as well as links both these will be set to the same color. From the documentation I can’t see a way around this but you might be able to find a workaround.