OOXML Hacking: Styled Text Boxes Complete

My last post began the subject of styled text boxes. There I covered the parameters contained in the first line of each level definition. Today’s entry continues by introducing the XML elements inside the level definition that format text. As a reminder, a level definition is the equivalent of a PowerPoint style. Since a text box can have up to 9 text levels, we can format 9 unique styles.

Styled Text Boxes – Child elements

Child Elements are XML parameters that are within an a:lvl#pPr level definition, as opposed to the first line values covered in my last post. Here is a super simple level with only 2 enclosed parameters, shown in bold:

<a:lvl1pPr marL="0" indent="0">
  <a:defRPr sz="1400"/>

The first tag, a:buNone, sets the level to not have a bullet, while a:defRPr sets the text size to 14 points.

Next, here’s an example that shows line spacing and tab settings:

<a:lvl2pPr marL="0" indent="0">
    <a:spcPct val="125000"/>
    <a:spcPts val="1200"/>
    <a:spcPts val="500"/>
    <a:tab pos="457200" algn="l"/>
    <a:tab pos="914400" algn="l"/>
    <a:tab pos="1371600" algn="l"/>

In order, this block sets line spacing of 125% (or leading, for the designers), 12 points of space before and space after of 5 points. Finally, three left-aligned tabs are set. The units are EMUs, so these tabs are spaced 1/2″ apart.

Child Elements – Bullets

Out of 16 possible child elements, 11 are for bullet formatting. Creating bullets by editing XML is an exercise in frustration. It’s far easier to create bullets using the program interface and then transfer that XML to the p:defaultTextStyle section of presentation.xml.

For an overview of all level definition parameters, this page covers them: Datypic page for List Level Text Style

Styled Text Boxes – The Easy Way

Sure, you could do all of the above in a text editor, if you wanted to prove your coding prowess. But time is short and there’s a faster way to get this job done using PowerPoint’s program interface. This leverages the fact that the structure for list level text is exactly the same for p:titleStyle, p:bodyStyle and p:otherStyle as used in slideMaster1.xml, p:txBody, used in many slide layouts, and p:defaultTextStyle as seen in presentation.xml.

My preferred method is to start by making a copy of the Content with Caption slide layout, then deleting the title and content placeholder, leaving only a text placeholder preformatted with small text. Then I make 9 levels of text and format each to match a design or client specs for what the text box styles should look like. Do all your bullet formatting here. Save the file and exit PowerPoint.

Now expand the file and look in ppt/slideLayouts. The Content and Caption layout is usually slideLayout8.xml. If you duped it as suggested, open slideLayout9.xml and format the code to be humanly readable. Just below <a:lstStyle> are 9 level definitions with all the formatting you created in the program interface. Each level starts with <a:lvlXpPr where X is the level number. Copy all 9 level definitions, but not the starting <a:lstStyle> or closing </a:lstStyle> tags.

Now open ppt/presentation.xml, select all 9 level definitions (starting just below </a:defPPr>) and paste in the 9 levels from slideLayout9.xml. Save the file, zip everything back into a presentation. Each inserted text box should now have up 9 levels of styles that match the formatting you created on the duplicated layout. Delete the extra layout and you’re done.

Styled Text Boxes – What about the Font?

If you’ve tried these steps out, you might notice one glaring omission in the XML. When you format a slide layout and copy the XML, there is no font information in the level definitions. This is because the layout gets its font info from the slide master. There are 2 ways to fix this:

  • If all levels the text box are in the same font, open the presentation, create a text box, set the font, right-click on the text box and choose Set as Default Text Box.

This action fills an objectDefaults stub at the bottom of ppt/theme/theme1.xml. It looks something like this:

    <a:bodyPr wrap="square" rtlCol="0">
        <a:defRPr dirty="0" smtClean="0">
          <a:latin typeface="+mn-lt"/>

In this case typeface=”+mn-lt” sets the text box font to the Minor (hence mn) or Body theme font. The Heading theme font would appear as +mj-lt.

  • If there are different fonts for different levels, apply those fonts when formatting the duplicate slide layout.

Interesting fact: If a level is set by default to a theme font, clicking on the font dropdown and re-selecting the same theme font breaks the font inheritance from the slide master and specifies the theme font in the layout instead. Here’s the default XML from the layout level 1 again:

<a:lvl1pPr marL="0" indent="0">
  <a:defRPr sz="1400"/>

And here’s what it looks like after reapplying the theme font in the layout:

<a:lvl1pPr marL="0" indent="0">
  <a:defRPr sz="1400">
    <a:latin typeface="+mn-lt"/>

Styled Text Boxes = Instant Text Placeholders

I believe this hack vastly increases the utility of the text box. In effect, it becomes a text placeholder that a user can easily add to any slide. Accessing the styles works exactly the same as a text placeholder. Use the Increase List Level button (Indent More on a Mac) to move through the levels.

Here’s a visual comparison of a text placeholder and a styled text box:

Text Placeholder compared to Styled Text Box

Styled Text Boxes – Other Issues

I’ve run across a couple of minor problems that you will need to keep in mind.

  • Picture bullets aren’t going to work. These require building an XML relationship to the bullet image stored in the file, which is very hard to do manually. Don’t bother.

  • Similar to the theme font issue mentioned above, default paragraph spacing in the layout is inherited from the slide master. This means your text box paragraphs will be missing any space before or after that displays in the layout. To fix this, set the paragraph spacing for each level in the layout. It doesn’t have to change, but you still have to set it to include the spacing in the layout XML.

As always, I welcome your questions, feedback and suggestions. Contact me at production@brandwares.com. Keep hacking!

11:37 pm

8 thoughts on “OOXML Hacking: Styled Text Boxes Complete

  1. Hi John,

    Love your XML hack tutorials, thanks for posting.

    Iā€™m interested in using your ‘Text Box Style’ hack to assign a ‘hierarchy of styles’ (heading 1, heading 2, body, bullet etc) within PPT ā€” assigning font styles, leading and spaces before and after. So the end use simply toggles through the styles using to access the predefined hierarchy.

    Have you seen this approach work successfully? Using, in essence, ‘paragraph/character styles’.

    And, in order to get the most out of it, is there a way to assign ‘ALL CAPS’ and ‘E X T E N D E D F O N T’? And then both ‘C O M B I N E D’ (in bold!).

    Thanks in advance

    Apologies for posting twice. I only saw your XML note AFTER posing the first one. And things fell off!

    • Yes, you can use the 9 levels to be 9 different styles, though they can’t be named as Heading 1, etc. In fact this is how we create text placeholder levels in all of our templates. If you’re doing this for a client, you should include a sample slide that explains how to access all the styles by using the Increase Indent button (or Indent More on a Mac), since this will be a new technique for most PowerPoint users.

      You can add either or both of all caps or expanded text to a text level. Here’s a default text definition:

      <a:defRPr sz="1800" kern="1200">

      Here it is formatted with both all caps and expanded text:

      <a:defRPr sz="1800" kern="1200" cap="all" spc="5000">
  2. Hi John,
    I just finished completing all of the steps in the section “Styled Text Boxes ā€“ The Easy Way”. When I opened my updated pptx file with my new code, the place holder was exactly as I designed it (gray font, a few different styles of orange bullets and specific line indentions). When I inserted a text box, none of my programmed changes were reflected. It was the black font with black bullets with standard line indents. I’ve spent a few hours combing through possible missteps on my part, but I can’t seem to isolate the issue. Can you give me some advice on things to look for?

    • I’d be happy to examine the file so see what the problem is. Please email it to me at production at brandwares dot com.

  3. Hi John,
    When I insert a text box in PPT, the words don’t automatically wrap within the box, so my coworkers have been grumbling to me about having to repeatedly open the shape format menu and check the Wrap Text in Shape box. I know the short term solution is to “Set Shape as Default”, but that only solves for that file. I’d like to add a feature to our corporate template that automatically wraps text within text boxes. I’ve been searching xlm files and can’t seem to find any code related to text wrapping. Can you help?

  4. Hi John, thank you for all this great info, it’s easy to understand and implement.
    Just one question – is there a way to specify the default internal margins of a text box? Also can the default be set to resize shape to fit/ do not autofit / shrink text on overflow as required?

    • The PowerPoint user interface has a feature for setting default text box formatting. Set the margins and resize options that you prefer, then right-click on the text box and choose Set as Default Text Box. This will not affect the text styling set in presentation.xml.

Leave a Reply

*Required fields. Your email address will not be published.

Posting XML? To enter XML code, please replace all less than signs "<" with "&lt;" and greater than signs ">" with "&gt;". Otherwise, Wordpress will strip them out and you will see only a blank area where your code would have appeared.