by Wander Boessenkool (Red Hat)

Producing a Red Hat Training course takes a lot of hard, but also thankful, work. In this series of posts I will explore the workflow that goes into producing a single course.

To satisfy our technical readers we still start this series with a post about the tools we use to produce our output documents, from the slide-decks used by our instructors, through the PDF files sent to our printers to produce the printed version of our Instructor Guides and Student Workbooks, to the HTML content and stylesheets used for our Red Hat Online Learning offering.

Single Source Publishing

All of our course materials are authored in DocBook, an XML dialect designed for producing texts, ranging from a one page article all the way up to a set of multiple books. Using DocBook we can then easily convert a single set of source files describing a book into a wide range of output formats using XSL transforms.

One of the main tools we use is Publican. Publican is a set of tools and stylesheets based around the DocBook standards, making it easy to deal with large books, and large collection of books. Publican is also used by the Red Hat Documentation team, and the Fedora Documentation team.

Using Publican and DocBook we can use the same source files to produce both the print content that is used in traditional classrooms and our Virtual Training classrooms, as well as the pure digital content that is used in our Red Hat Online Learning classrooms. Publican can also output to a variety of other outputs that we (currently) do not use, like man-pages, plain text,or ePub.

Editing Our Source Files

Editing XML files can be a daunting task, but luckily you do not have to type everything manually. Some people on our team use powerful graphic editors with lots of automatic code insertion and other whistles, while others (like me) prefer the simple elegance of a text-editor like vim (albeit with some useful extensions, like xml.vim)

Managing Revisions

We manage our revisions using SubVersion (SVN). This allows us to work on a project with multiple people at the same time, without clobbering each other's work. Another revision control system like GIT would work as well. The joys of using any kind of revision control system is that you can easily back out when you've just made a disastrous error (like accidentally pressing ggVGd:w! while in vim), or locate exactly what commit by what team member introduced that Brony reference into your clustering course.

Producing Output

We convert our source DocBook XML files into readable materials by using a publican build command. (Actually we have written Makefiles that do that for us).

publican will then grab our source xml, include any standard content like legal notices into it, validate if the document adheres to the DocBook standard, and then convert it into the desired target format using XSL transformations. For PDF output this requires two steps: first converting our DocBook into XSL-FO formatting code, and then calling fop to convert the XSL-FO code into a shiny PDF.

Getting the output we desire for our courses includes a fair amount of customization of the XSL stylesheets used by publican. You can combine your customizations, and the default content that you want to go along with it, into a publican Brand. The Publican project has examples of these types of customizations, for example in the publican-fedora brand.

Enough talk, give me examples!

If you have ever taken a Red Hat Training course you will know that our courses are full off hands-on exercises. One of these exercise types is the Performance Checklist, an exercise where you are guided through a number of steps to accomplish a task. The different steps in a Performance Checklist will instruct you to perform a specific action leading up to the goal, but will typically not include the exact commands you need to accomplish that action. Instead you can find the solutions in the back of your Student Workbook (or hidden behind a button in our Online Learning environment).

One of our big tricks when writing these exercises is that we do include the solutions in these steps, we just do not render them in the main portion of the book. Our XSL transforms are set up in such a way that the solutions will be stripped when rendering the “normal” part of the book, but they will be rendered when including that same exercise in the Solutions appendix of the book. (We do not actually type the same exercise twice, we just use an <xi:include> XML tag in the Solutions appendix to copy it in from the main book)

<task role="Checklist">
  <title>A Short Example</title>
  <tasksummary>
    <para>
      <emphasis role="bold">Lab Overview:</emphasis> This is a short example
      Performance Checklist
    </para>
    <para>
      <emphasis role="bold">Success Criteria:</emphasis> You will have
      successfully completed this exercise when you understand the basics of
      Performance Checklist tagging.
    </para>
  </tasksummary>
  <taskprerequisites>
    <para>
      None, nothing at all, zero, nada.
    </para>
  </taskprerequisites>
  <procedure>
    <step>
      <para>
        Make your <code>bash</code> shell say hello to you.
      </para>
      <screen role="solution"><prompt>[student@&dsk; ~]$ </prompt><userinput>echo "Hello World"</userinput>
Hello World</screen>
    </step>
  </procedure>
</task>

In the main part of the book this would render as:

Performance Checklist

A Short Example

Lab Overview: This is a short example Performance
Checklist

Success Criteria: You will have successfully completed
this exercise when you understand the basics of Performance Checklist
tagging.

  1. Make your bash shell say hello to you.

While in the solutions appendix this would render as:

Performance Checklist

A Short Example

Lab Overview: This is a short example Performance
Checklist

Success Criteria: You will have successfully completed
this exercise when you understand the basics of Performance Checklist
tagging.

  1. Make your bash shell say hello to you.

    [student@desktopX ~]# echo "Hello World"
    Hello World

As you can see in the example above we use a fair amount of role="something" on our tags. For example on the <task> we use the role Checklist to mark the exercise as a Performance Checklist, so that we can render it with little check boxes in front of each step. The magic that stops the solution from appearing in the main part of the book is the role="solution" attribute on the <screen> tag in the example above.

Tagging is easy! Show me some XSL

If you really want to get your hands dirty consider the following (simplified) example based on one of the actual .xsl files we use.

<xsl:template match="*[count(ancestor::*[@role='solutions']) = 0]/*[@role='solution']"/>

This XSL will match on any object that has the attribute role="solution", but only if none of it's ancestors in the XML tree has the attribute role="solutions". When it matches it does absolutely nothing, thus removing the content and children of this object from the output tree. Since we only put the role="solutions" attribute on the root node of our Instructor Guide and on the Solutions appendix, we effectively strip all solutions from the “normal” part of the Student Workbook.

More Information

If you want more information on how to use DocBook and Publican to produce beautiful, maintainable documentation you can refer to the sites linked in this article. If you really want to get your hands dirty using custom XSL and XSL-FO you can refer to DocBook XSL: The Complete Guide by Bob Stayton, available for on-line reading here.

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.