Turning the Tables with DITA 1.3

Table Rotation in DITA 1.3

[This blog post was originally published on the IXIASOFT website on July 27, 2015. It is reproduced here with permission].

This is the first in a series of articles examining aspects of DITA 1.3, aimed at content creators and information architects. Please note that the information that follows is based on the draft DITA 1.3 specification, which is liable to change between now and its final release expected by the end of 2015.

In a portrait-oriented document layout, a table with large quantities of data may have too many columns to be displayed neatly within the established page width. This is a common issue when creating technical documentation, especially for writers who work with file formats that have fixed dimensions designed to mimic print output, such as PDF. A table that is wider than the page it is printed on might look like the following example in a desktop publishing program:

Example of a table that is too wide to fit on a printed page
Example of a table that is too wide to fit on a printed page

This scenario is not as big of an issue for tables rendered in HTML as it is for desktop publishing since the user can usually scroll over to see the content of a table that doesn’t “fit” within the screen width. There are other options available for web-based tables as well, such as using a script to collapse and expand columns on demand. But if you are looking at “physical” pages with a fixed height and width, then you would have a problem.

Wouldn’t it be nice if there were a way to change the orientation of a table so that its width could fill the length of the page instead? DITA 1.3 makes this possible with the new @orient attribute that can be used for tables.

The @orient attribute has three possible values:

  • port: default value; short for “portrait”, where the table has the same orientation as the text flow
  • land: short for “landscape”, where the table is rotated 90 degrees counter-clockwise from the text flow
  • -dita-use-conref-target: this value is used for conref-ing a value for @orient from another map

The default “port” value displays tables in standard orientation. The “land” value tells the output processor to orient the table 90 degrees counter-clockwise, laying it out so that it fills the contents of the page in landscape mode.

The following code snippet illustrates how this would work:

<table frame="all" orient="land"> 

And the following illustration depicts the intended effect when rendered by the output engine:

Table oriented in landscape mode, rotated 90 degrees counter-clockwise from the original
Table oriented in landscape mode, rotated 90 degrees counter-clockwise from the original

This feature has been long awaited for by many; however, it should be pointed out that this type of print behavior has always been possible, but only if you were willing to dive into the XSL. I am aware of several technical documentation groups who have implemented a similar function for their own specific needs, typically by using an @outputclass value with equivalent XSL code in order to interpret table orientation at output.

DITA 1.3 takes this into account, stating that the @orient attribute can be ignored for the aforementioned situation. More options are available at the XSL level, including the ability to orient the contents of the entire page (not just the table) to whatever is needed. But for those of us who aren’t up to the challenge of figuring out how to rotate a body page in their PDF plugin, @orient is the next best thing.

So why isn’t there an equivalent value to orient the table 90 degrees clockwise as well?

This might make sense if you want to have tables with different orientations on your pages, such as a table printed 90 degrees counter-clockwise on the verso (left-hand) page and 90 degrees clockwise on the recto (right-hand) page. The problem is being able to predict prior to rendering the output whether a given table will appear verso or recto. While this can be done with some customized XSL code, it made sense within the specification to simply state that a table ought to appear in a landscape orientation, which has only a single value. It also makes sense to have a single, standard orientation for tables rendered in landscape mode, as lengthy tables that are spread over more than one page are easier to understand if they follow the same orientation as the source table. (Widow and orphan control over table output is also a potential issue, but this is fundamentally no different than with a “regular” table. Again, tweaks to the XSL can take care of this*).

In addition to “port” and “land” there is a third possible value for @orient: “-dita-use-conref-target”. When this value is used, it pulls in a previously set value for @orient that already exists via the conref mechanism. This would come in handy if you have a particular type of data in a table that should always be oriented in a particular way. All you have to do then is reference that table in subsequent tables. Here is some sample code for the first, “master” table:

<table id="master-table" orient="land"> 
  <tgroup cols="2"> 
    <tbody> 
      <row> 
        <entry>1</entry> 
        <entry>2</entry> 
      </row> 
      <row> 
        <entry>A</entry> 
        <entry>B</entry> 
      </row> 
    </tbody> 
  </tgroup> 
</table>

Any subsequent tables that should be oriented in the same way can simply reference the @id of the original table with a @conref and use orient=”-dita-use-conref-target” to pull in whatever value is being used on that master table. Here’s what this would look like in a code sample:

<table conref="#master-table" orient="-dita-use-conref-target">
  <tgroup cols="2">
    <tbody>
      <row>
        <entry>1</entry>
        <entry>2</entry>
      </row>
      <row>
        <entry>A</entry>
        <entry>B</entry>
      </row>
    </tbody>
  </tgroup>
</table>

When this second table is rendered, the conref pulls in the value from @orient in the original table, so it is resolved in this case.

Keep in mind that the illustrations depict what the specification intends to be displayed – your results may vary, depending on the output type (PDF, eBook, HTML, etc.) and also on the fonts being used. For PDFs, it is the PDF renderer doing all of the work, so the outcome is entirely dependent on how the software tools implement @orient. Likewise, the outcome for HTML-based and ePub-type outputs is entirely dependent on the browser/ePub reader. Prior to implementing this, check your output to see if what you set in the code comes out as you expected.

Rotating Cell Content
DITA 1.3 also makes it possible to rotate content within individual cells in a table by using the new @rotate attribute for the element. This attribute arguably has a wider scope than @orient for tables, as @rotate for cell entries may also be handy to have for non-print output types.

Much like the @orient attribute for tables, @rotate for cell entries can take any one of three possible values:

  • 0: the default, where no rotation to cell contents occurs
  • 1: the contents of the cell are rotated 90 degrees counter-clockwise
  • -dita-use-conref-target: this value is used for conref-ing a value for @rotate from another cell entry

The value of interest here is “1”, which changes the rotation value for the specified cell. This can be used to makes its contents stand out or to make them more readable in a given circumstance.

The following example code shows how this could be used:

<table frame="all">
  <tgroup cols="2">
    <tbody>
      <row>
        <entry>Lorem ipsum</entry>
        <entry>Dolor sit amet</entry>
      </row>
      <row>
        <entry>123</entry>
        <entry rotate="1">ABC</entry>
      </row>
    </tbody>
  </tgroup>
</table>

This table and its contents would be rendered in the following fashion:

Rotated Table Cell Example
Rotated Table Cell Example

Note that this is what is intended. Certainly if we are talking about an image contained within a cell, the intent would be to rotate that image 90 degrees counter-clockwise.

As with the @orient examples for the table element, the illustrations depict the intended effect – your results may vary. While it is also possible to combine the effects of @orient=”land” and @entry=”rotate” for an individual cell in a table, the DITA 1.3 specification does not specify how the two should interact together. This is deliberate as it allows for leeway in how software implementers interpret how these two conditions would work together.

As we saw earlier with @orient, more options are available if you are willing to dive into the XSL. For example, you can dig into the PDF plugin and apply the XSL-FO @reference-orientation attribute for rotation values of 0 (the default, left-to-right-text), 90, 180, 270, -90, -180, and -270. For HTML outputs, you can use the target browser’s own CSS transform property to accomplish the same thing. Note that there are different browser-specific implementations for this property.

Finally, while the DITA 1.3 specification lays out how things ought to work with @orient and @rotate, as a general principle the specification steers away from stating exactly how software tools should process any of its features, as it is not the place of the specification to do that. This is all the more reason to test any implementation before putting it into practice.

*A note from IXIASOFT DITA Specialist, Leigh W. White – “One of those “XSL tweaks” to keep in mind: For example, a legal portrait page has 1 inch margins all around, leaving 9 inches of vertical body region. On that page you have a paragraph that takes up 2 inches, leaving 7 inches of vertical body space (not counting the text block’s margins or padding). Following the text, you have a table that is 8 inches wide and 5 inches high for which you have specified @orient=”land”.

This table uses an attribute set that specifies “keep-with-previous.on-page.” Unrotated, the table will fit vertically on the same page as the text (though it will “run off” the right side of the page) because (2+5)<9. But rotated, the table will not fit vertically on the same page because (2+8)>9. And because you’ve specified that the text and the table must be kept together on a page, the PDF renderer will shift them to the next page in an effort to make this happen, but it can’t happen there either, so…. Depending on what the renderer finally decides to do, you might see the table run off the bottom edge of the page, or you might not see it at all. This is an important potential conflict to keep in mind when managing flow using the “keep with” XSL-FO attributes.”

About

"DITAWriter" is Keith Schengili-Roberts. I work for AMD as a Senior Manager for Technical Documentation, and have recently helped usher in a new company-wide DITA-based CCMS. And I like to write about DITA and the technical writing community. To get ahold of me you can email me at: keith@ditawriter.com.

View all posts by