Controlling PDF Page Breaks in Confluence

In exporting pages in Confluence to PDF, I wanted to control where page breaks occur. CSS has various properties to control page breaking that I could make use of by manually inserting HTML tags in Confluence pages.

To make tagging easier and consistent, I wrote a user macro that lets me select the type of page break control I want in my terms: “KeepTogether”, “KeepwithPrevious”, “KeepwithNext”, “ForceBreakBefore”, and “ForceBreakAfter”. The macro inserts HTML div tags with the specific class used to reference the CSS property.

pdfcontrolbreak User Macro
## Macro title: pdfcontrolbreak
## Description: Control page breaks in PDF. Typically, before images, tables, and step lists.
## Configuration: pdfcontrolbreak, External Content, Convert wiki markup to HTML, HTML
## Developed by Bruce Michelsen
## Parameters:
## Specify type of control for page break. Typically, before images, tables, and step lists.
## Usage:
## {pdfcontrolbreak:breaktype}
##
## PARAMETER DEFINITIONS
## @param breaktype:title=breaktype|type=enum|enumValues=KeepTogether,KeepwithPrevious,KeepwithNext,ForceBreakBefore,ForceBreakAfter|desc=Specify the PDF page break control type|required=true
##
## DEFAULT VARIABLES AND VALUES
#set ($defvarbreaktype = "Keep Together")
##
## GET AND SET PARAMETERS
## Check for a blank first parameter
#if ($parambreaktype && $parambreaktype.length() > 0)
#set ($varbreaktype = $parambreaktype)
#elseif ($param0 && $param0.length() > 0)
#set ($varbreaktype = $param0)
#else
#set ($varbreaktype = $defvarbreaktype)
#end
##
## Set pdfcontroltype value
#if ($varbreaktype == "KeepTogether")
#set ($pdfcontroltype = "pdfnobreakinside")
#elseif ($varbreaktype == "KeepwithPrevious")
#set ($pdfcontroltype = "pdfnobreakbefore")
#elseif ($varbreaktype == "KeepwithNext")
#set ($pdfcontroltype = "pdfnobreakafter")
#elseif ($varbreaktype == "ForceBreakBefore")
#set ($pdfcontroltype = "pdfbreakbefore")
#elseif ($varbreaktype == "ForceBreakAfter")
#set ($pdfcontroltype = "pdfbreakafter")
#end
##
## DISPLAY
## Debugging: Uncomment to display values
## defvarbreaktype=$defvarbreaktype
## varbreaktype=$varbreaktype
## pdfcontroltype=$pdfcontroltype
##
## Display Logic
<div id="pdfcontrolbreak" class="$pdfcontroltype">$body</div>
&nbsp;

Notes:

  • The macro needs to be converted to work with later versions of Confluence.

PDF CSS Settings for Page Breaks
In the PDF Stylesheet, I included the following CSS settings to stylize page break controls:


/* Widows and Orphans */
.widows {widows:2;}
.orphans {orphans:2;}
p, li {widows:2;orphans:2;}

/* CSS for Brute Force User Macros */
div.pdfbreakbefore {page-break-before:always;}
div.pdfbreakafter {page-break-after:always;}
div.pdfnobreakbefore {page-break-before:avoid;}
div.pdfnobreakafter {page-break-after:avoid;}
div.pdfnobreakinside {page-break-inside:avoid;}

/* Keep Together */
p {page-break-inside:avoid;}

/* Keep with Next */
.wiki-content h1, .wiki-content h2, .wiki-content h3, .wiki-content h4, .wiki-content h5, .wiki-content h6, .wiki-content h7, .wiki-content h8, .wiki-content h9, .wiki-content h10, .wiki-content h11, .wiki-content h12 {
page-break-after:avoid;}

/* Keep with Previous */
.image-wrap, div.expand-control {page-break-before:avoid;}

Notes:

  • When inserting the page break tags, you cannot nest the tags; you must start and close a set before inserting another set.
  • Typically, I add the “KeepwithPrevious” around content that should stay with the preceding paragraph, such as around an image or table that has an introductory sentence rather than a heading.

Example
In the following example, I applied the pdfcontrolbreak macro to an image I wanted to keep with the preceding paragraph.


h2. Simply a Filler about Cheese
{cheese}

h3. Roses
You can keep the following image with this text by using a PDF control break user macro.

{pdfcontrolbreak:breaktype=KeepwithPrevious}
!roses19.jpg!
{pdfcontrolbreak}

I applied the pdfcontrolbreak macro to a section I wanted to appear on a new page.


{pdfcontrolbreak:breaktype=ForceBreakBefore}
h2. Start on New Page
{pdfcontrolbreak}

{loremipsum}

When exported to PDF, the content looks like this:
pdfcontrolbreaks

Adding a Header and Footer to a PDF in Confluence

For my purposes, I wanted the same header and footer to appear in PDFs for both single page PDFs and space PDFs.

Given that you can configure a header and a footer from PDF Layout, it seems you can only have these elements when you create a space PDF. However, it’s not true. You can configure a header and footer in the PDF stylesheet.

That’s right, there is a separate stylesheet for controlling PDFs. Why? Confluence uses a stylesheet for a set or space of information. When you export to PDF, Confluence uses a separate stylesheet for exporting because of the process that Confluence uses to create the PDF. In the PDF export, the information is converted to XML than to HTML than to PDF. The PDF stylesheet comes into play when converting from HTML to PDF. (Any @media print settings in the general stylesheet apply to printing but not to creating a PDF.)

While I could have had a different header and footer for a page PDF than for a space PDF by configuring separate header and footer elements in both PDF Layout and in the PDF stylesheet, I chose to configure the header and footer in only the PDF stylesheet because I wanted to use the same header and footer and maintain the configurations in only one place.

Tip: To remind myself later not to configure the header and footer in PDF Layout, I added HTML comments into the PDF Space Export Header and Footer fields (Browse > Advance > PDF Layout):

PDF Space Export Header

<!-- Use Page-specific header settings in PDF Stylesheet -->

PDF Space Export Footer

<!-- Use Page-specific footer settings in PDF Stylesheet -->

Configuring a Header

You can have the same header in a page and space PDF by configuring header and footer elements in the PDF stylesheet.

To configure a header,

  1. Click Browse > PDF Stylesheet > Edit.

Confluence uses a built-in CSS file for PDF exporting and a custom CSS file (in PDF Stylesheet). The settings in the custom PDF stylesheet override the built-in CSS settings. To get the look I wanted on the title page, I had to override the default CSS settings with my settings in the PDF stylesheet.

PDF exporting in Confluence makes use of CSS paged media to create a header and footer.
Of the various areas three areas are used for the header (@top-left, @top-center, @top-right) and three areas are used for the footer (@bottom-left, @bottom-center, @bottom-right). One thing to note is that the areas can merge together if content in an area exceeds its boundaries.

For all pages except for the title page and the TOC pages, I wanted a header using an image across the top and a footer consisting of the page title, the page number, and copyright info.

Notes:

  • In PDF Layout, you can specify an img tag; however, in PDF Stylesheet, you must use a background-image selector.
  • In PDF Stylesheet, you position a background-image using background CSS selectors.
  • With a background-image, you must specify the full URL to the source.
  • I overrode the default CSS settings, including the page content margins.
  • To work around a @bottom alignment issue, I overrode the padding.
  • To work around an issue with the @top when using a background-image where I was not able to set margin above or have image exceed beyond the specified @top area. I put the same image in all three @top areas, specifying different positions (left center, center center, right center) to display different parts of the image in each area.
  • In @top-left, when specifying background-image, you must specify the width because background-image tags are not affected by the img declaration of -fs-fit-images-to-width:;

My PDF Stylesheet @page Settings

@page
/* Any @page-specific properties */
{
margin: .7in .5in; /* Sets the page area for content */
padding: 0em; /* override default that breaks @bottom alignment */
/* Note: @page-specific header/footer settings override Space PDF Layout header/footer settings.*/
/* @page-specific header settings */
/* This is a viable solution for having headers/footers in single page PDFs and space PDFs versus using PDF Layout Header (only space PDFs) but you have to put a background image in all the @top areas where you want the image to appear and size and position them using CSS background selectors. */
@top-left {
background-image: url(http://wiki.mydomain.com/confluence/download/attachments/33164238/pdfheader.png);
background-repeat: no-repeat;
background-size:720px auto;
background-position:left center;
page-break-inside: avoid;
}
@top-center {
background-image: url(http://wiki.mydomain.com/confluence/download/attachments/33164238/pdfheader.png);
background-repeat: no-repeat;
background-size:720px auto;
background-position:center center;
page-break-inside: avoid;
}
@top-right {
background-image: url(http://wiki.mydomain.com/confluence/download/attachments/33164238/pdfheader.png);
background-repeat: no-repeat;
background-size:720px auto;
background-position:right center;
page-break-inside: avoid;
}

/* @page-specific footer settings */
@bottom-left {
text-align:left;
font-family: OpenSansRegular, Verdana, sans-serif;
font-size: 8pt;
color:#9BCBEB;
vertical-align:top;
padding:15px 0px;
/* content: "My User Guide"; /* Override page title with global title */
content: element(runningtitle); /* TEST page title as added in PDF export template */
white-space:nowrap; /* Doesn't apply to element. */
/* overflow:hidden; /* Doesn't apply to element. */
/* text-wrap:none; /* Doesn't apply to element. */
/* display:block; /* Doesn't apply to element. */
/* margin-bottom:20px; /* Doesn't apply to element. */
}
@bottom-center {
text-align:center;
font-family: OpenSansRegular, Verdana, sans-serif;
font-size: 8pt;
color:#9BCBEB;
vertical-align:top;
padding:15px 10px;
content: counter(page) " of " counter(pages);
white-space:nowrap; /* single line for page info */
}
@bottom-right {
text-align:right;
font-family: OpenSansRegular, Verdana, sans-serif;
font-size: 8pt;
color:#9BCBEB;
vertical-align:top;
padding:15px 0px;
content: "Copyright mycompany, Inc. All rights reserved.";
white-space:nowrap;
}
/* Any other @page-specific rules */
}

For footers, I wanted to display a footer consisting of the page title, the page number, and copyright info.

@bottom-left {
content: "My User Guide"; /* Set global title */
...
}
@bottom-center {
content: counter(page) " of " counter(pages); /* Shows page number of total pages */
...
}
@bottom-right {
content: "Copyright mycompany, Inc. All rights reserved.";
...
}

These settings are “global” because they’re hard-coded in the PDF stylesheet. If you want to customize the title, you have to edit the PDF stylesheet before generating the PDF. The fact that the PDF stylesheet is currently local to each wiki space rather than being global to the entire wiki, makes maintenance a little easier.

Initially, I decided to use a title for the entire set of pages, as if it were a book, but that didn’t really work when exporting a single page so I later extended the capability of PDF exporting so I could use page titles. See Using a Running Element for Displaying the Page Title.

In using text, I needed to specify text alignment for each area, font size, color, vertical alignment, padding, wrapping, etc.

Notes:

  • You can show the current page number using
    counter(page)
  • You can show the total page number using
    counter(pages)
    For example:
    content: counter(page) ” of ” counter(pages);

Adding a Title Page to a PDF in Confluence

In exporting pages in Confluence to PDF, I wanted to add a title page to the PDF.

In Confluence, you can have a title page in a PDF that you create for pages in the set of pages or “space”. You can only add a title page to a space PDF; you cannot add a title page to a PDF you create from a specific page.

To configure a title page,

  1. Click Browse > Advance > PDF Layout.
  2. In PDF Space Export Title Page, specify the settings you want.
    The settings consist of HTML tags, which you can stylize using CSS in the PDF Stylesheet.

For my title page, I wanted to display a full-page image (attached in a wiki page) that would contain the title and other info.

My PDF Space Export Title Page Settings

<!-- This title page appears only when exporting a space PDF --> 
<div id="fsTitlePage" >  
  <img id="imgpdftitlepage" src="/download/attachments/33164238/pdftitlepage.png"/>  
</div>

In my settings, I set “id” attributes so I could stylize the tags in my stylesheet.

To stylize a title page,

  1. Click PDF Stylesheet > Edit.
  2. Specify the CSS for stylizing the layout settings.

For my title page, I wanted the image to fill the page area and not break over into a new page. I found that images are scaled to fit a specified width so I set a width specifically for the title page image.

My PDF Stylesheet Title Page Settings

/* PDF Layout properties */  
#fsTitlePage {  
  page-break-after: always; /* Force a break after the page */
  page-break-inside: avoid; /* Prevent a page break inside the title page */ 
}
img#imgpdftitlepage {-fs-fit-images-to-width:7.5in} /* Set width for scaling title page image */

To get the look I wanted on the title page, I had to override the default CSS settings.

Confluence uses a built-in CSS file for PDF exporting and a custom CSS file (in PDF Stylesheet). The settings in the custom PDF stylesheet override the built-in CSS settings.

PDF exporting in Confluence makes use of CSS paged media to stylize PDF pages.
Of the various areas, I used @top-left, @top-center, and @top-right for the header and I used @bottom-left, @bottom-center, and @bottom-right for the footer.

For the title page and the TOC pages, I didn’t want the header nor the footer to display so I set the @top and @bottom areas to be empty. (Setting @bottom-center{} is equivalent to setting @bottom-center{content:none;}.) If you don’t specify the areas, you won’t override the default CSS settings. (Also, I found that the areas can merge together if content in an area exceeds its boundaries.)

The @page title area applies to the title page and the TOC pages. I overrode the margins, padding and @top and @bottom areas within it.

My PDF Stylesheet @page title Settings

@page title {
/* Any page title-specific properties for title and toc pages.*/   
/* Override default settings */  
  margin: .5in .5in; /* top/bottom, right/left */  
  padding: 0em;  
  @top-left {}  
  @top-center{}  
  @top-right {}  
  @bottom-left {}  
  @bottom-center{}  
  @bottom-right {}  
}

Note: Although it seems you should be able to use the pseudo @page :first to create a title page, you cannot. You can only create the page before the TOC when you use the PDF Layout Title page.

Creating PDFs in Confluence

I use Atlassian Confluence, a wiki, to create documentation for software. Although users can find and view information in the wiki, some users want to view the information in PDF. I explored how to create PDFs in Confluence.

Using Confluence, you can generate or “export” a page or multiple pages to PDF. When you export a single page to PDF, you get only that page; when you export multiple pages, you get bookmarks, a title page (optional), a Table of Contents, and the pages you want.

  • To create a PDF of a single page, go to the page you want, then click Tools > Export to PDF.
  • To create a PDF of multiple pages, you administer the set of pages or “space” to which the pages belong by clicking Browse > Advanced > PDF Export, then select or deselect the listed pages until you have selected the pages you want in the PDF, then click Export.

When exporting a space to PDF, you can configure layout options for the PDF by clicking Browse > Advance > PDF Layout. You can also stylize the output using a PDF stylesheet (separate from the stylesheet used for pages in the wiki).

Exploring Social Media

The company I work for, Domo, is taking a risk in having every employee get involved in social media, especially introverts like me who consciously chose not to go into sales or marketing. That’s right, I’d rather deal with data than people. But only because of a traumatic experience as a Cub Scout attempting to sell Scout-O-Rama tickets. Hey, it was painful. And the Girl Scout cookies sell themselves!

Sometimes people in sales and marketing are like WW II candy bombers, dropping “little vittles” to the public. Instead of staying on the ground and providing flight instructions, I’m taking my chance to fly. Look out below…

In the process of learning more about social media, I’m exploring ways to get technical content into the social media. Certainly, there are benefits of social media to communicate “about” technical information for software products, but I’m exploring the benefits of using blogs, posts, content feeds, and wikis as deliverables of technical information.

As a technical communicator, I can aid the company in its efforts to build brand identity, awareness, and customer loyalty by furthering my efforts to understand how customers use products and how to deliver information that aids them in their goals. By discovering appropriate methods for delivering content using social media, I can add value to the content and deliver content to interested customers in timely and convenient ways.

Hang on. I’m reaching for a Girl Scout cookie and a glass of milk. Here’s to transforming technical communication from being a parachute drop of static information to being an ongoing conversation of dynamic information that will benefit the company and its customers.

For information about the Domo Social Experiment, see http://www.domo.com/social/