Project Implementation Details


Table of Contents

1. Introduction
1.1. Overview
2. The "doctree" XML file
2.1. <transnode>
2.2. <leafnode>
2.3. Common Components
2.3.1. <teaser>
2.3.2. <title>
2.3.3. <body>
2.3.4. <left>
2.3.5. <right>
2.3.6. <footer>
2.4. Special Components
2.4.1. <copyFile>
2.4.2. <copyDir>
2.4.3. <mkdir>
3. The main build.xml file
4. DoctreeMaintainer.jar
4.1. Source Code
5. OutputBuilder.jar
5.1. Source Code
5.1.1. OutputBuilder.class
5.1.2. HTMLNode.class
6. The Ant Functions
6.1. ant.properties
7. The CVS component

The documentation system developed by Ashley Mills for The University Of Birmingham during the summer of 2002 can be summarised:

The XHTML distribution pages for the project are automatically built by the "OutputBuilder" program, the information required to do this is provided as an XML document. The document type is called a "doctree", which is a euphemism for DOCument-TREE because the document outlines the tree structure the distribution pages should take.

The root of the document is <doctree>. There are two elements used throughout the doctree, <transnode> and <leafnode>. The doctree element behaves like a transnode accept it has no parents to link to, the available attributes are the same. The image below illustrates a typical doctree:

An example of a doctree

A representation of the sketch above, in XML, is shown below:

      <doctree id="index" htmlName="index.html" name="Project Home"
      linkParents="false"  linkChildren="true" linkSiblings="false" 
      includeTeaser="false">
        <transnode id="programming" name="Programming" includeTeaser="false" 
                      linkParent="true" linkChildren="true" linkSiblings="false">
          <teaser>
            <p>Contains documentation about various programming languages.</p>
          </teaser>

          <leafnode id="java" name="Java" srcDir="src/docs/java"
                       includeTeaser="true" linkParent="true" linkSiblings="true"
                       buildPDF="true" buildHTML="true" buildChunkedHTML="false"
                       includeXML="true">
            <teaser>
              <p>Java is an Object oriented language that has very good cross-platform support.</p>
            </teaser>
          </leafnode>

          <leafnode id="scheme" name="Scheme" srcDir="src/docs/scheme"
                       includeTeaser="true" linkParent="true" linkSiblings="true"
                       buildPDF="true" buildHTML="true" buildChunkedHTML="false"
                       includeXML="true">
            <teaser>
              <p>
                Scheme is a small and elegant dialect of LISP that was developed in the mid-1970s 
                at the Massachusetts Institute of Technology.
              </p>
            </teaser>
          </leafnode>
        </transnode>

        <transnode id="textProcessing" name="Text Processing" includeTeaser="false"
                      linkParent="true" linkChildren="true" linkSiblings="false">
          <teaser>
            <p>Contains documentation about various text processing systems</p>
          </teaser>

          <leafnode id="docbook" name="DocBook" srcDir="src/docs/docbooksys"
                       includeTeaser="true" linkParent="true" linkSiblings="true"
                       buildPDF="true" buildHTML="true" buildChunkedHTML="false"
                       includeXML="true">
            <teaser>
              <p>
                DocBook is a markup language defined in SGML and XML, it is particularly suited to
                technical documentation.
              </p>
            </teaser>

            <body>
              <div class="content" align="center">
                <div align="left">
                  <p>
                    More information about DocBook can be found at the OASIS home page:
                    <a href="http://www.oasis-open.org/committees/docbook">http://www.oasis-open.org/committees/docbook</a>
                  </p>
                </div>
              </div>
            </body>
          </leafnode>
        </transnode>
      </doctree>
    

When rendered as HTML, viewed via a CSS compliant web-browser the web-pages genearted by the OutputBuilder program at the time of writing looked like this (note that only some are shown):

The Index page generated using OutputBuilder on the doctree shown above.

The "Programming" page generated using OutputBuilder on the doctree shown above.

The "Java" page generated using OutputBuilder on the doctree shown above.

The output produced can be changed by modifying the OutputBuilder program and/or modifying the CSS.

A <transnode> element represents a transitional node in the XHTML tree, for example, "Text Processing". A transnode has a number of attributes that can be specified. To enable an attribute one uses 'attributeName="true"' to disable an attribute one uses 'attributeName="false"'. All the attributes that only take the values 'true' and 'false' must be provided. Some attributes take values other than 'true' or 'false' and unless otherwise specified a value must be provided for them. The attributes for transnode are shown in the table below:

[Note]Note

Attribute values may only contain plain text, XML markup is not allowed.

Table 1. <transnode> attributes

AttributeDescriptionRequired
id The value assigned to the 'id' attribute identifies the the node. The generated webpage will take the name "idhome.html" unless the 'htmlName' attribute has been provided. The generated webpage will be placed in a sub-directory named id. YES
name The value assigned to the 'name' attribute is used primarily as the title of the generated webpage if the <title> element has not been provided. A secondary usage is in the creation of hyperlinks between webpages, for example if the 'linkParent' attribute has been set to 'true', the webpage generated for this node will link to the webpage generatef for it's parent and vice-versa. The text of the link will be the value of the 'name' attribute. If the name attribute is omitted, the value of the 'id' attribute will be used as a failsafe. YES
htmlName If the 'htmlName' attribute is provided, the name of the generated webpage will be that specified by the value of the 'htmlName' attribute. If the 'htmlName' attribute is not provided the name of the generated webpage will be created from the value of the 'id' attribute. NO
includeTeaser If the 'includeTeaser' attribute is set to 'true' the children of the <teaser> element will be included in the body of the generated webpage. If the 'includeTeaser' attribute is set to 'false' the children of the <teaser> element will not be included in the body of the generated webpage. YES
linkParent If the 'linkParent' attribute is set to 'true', the webpage generated for the parent of this node will be automatically hyper-linked to the webpage generated for this node and vice-versa. If the 'linkParent' attribute is set to 'false', the webpage generated for this node will not be automatically hyper-linked to the webpage generated for the parent of this node and vice-versa. YES
linkChildren If the 'linkChildren' attribute is set to 'true', the webpages generated for the children of this node will be automatically hyper-linked to from the webpage generated for this node. If the 'linkChildren' attribute is set to 'false', the webpages generated for the children of this node will not be automatically hyper-linked to from the webpage generated for this node. YES
linkSiblings If the 'linkSiblings' attribute is set to 'true', the webpages generated for the siblings of this node will be automatically hyper-linked to from the webpage generated for this node. If the 'linkSiblings' attribute is set to 'false', the webpages generated for the siblings of this node will not be automatically hyper-linked to from the webpage generated for this node. The hyper-links will be placed on the left of the generated webpage. YES

A <leafnode> element represents a leaf of the XHTML tree, for example, "LaTeX". A leafnode has a number of attributes that can be specified. To enable an attribute one uses 'attributeName="true"' to disable an attribute one uses 'attributeName="false"'. All the attributes that only take the values 'true' and 'false' must be provided. Some attributes take values other than 'true' or 'false' and unless otherwise specified a value must be provided for them. The attributes for leafnode are shown in the table below:

[Note]Note

Attribute values may only contain plain text, XML markup is not allowed.

Table 2. <leafnode> attributes

AttributeDescriptionRequired
id The value assigned to the 'id' attribute identifies the the node. The generated webpage will take the name "idhome.html" unless the 'htmlName' attribute has been provided. The generated webpage will be placed in a sub-directory named id. YES
name The value assigned to the 'name' attribute is used primarily as the title of the generated webpage if the <title> element has not been provided. A secondary usage is in the creation of hyperlinks between webpages, for example if the 'linkParent' attribute has been set to 'true', the webpage generated for this node will link to the webpage generatef for it's parent and vice-versa. The text of the link will be the value of the 'name' attribute. If the name attribute is omitted, the value of the 'id' attribute will be used as a failsafe. YES
htmlName If the 'htmlName' attribute is provided, the name of the generated webpage will be that specified by the value of the 'htmlName' attribute. If the 'htmlName' attribute is not provided the name of the generated webpage will be created from the value of the 'id' attribute. NO
includeTeaser If the 'includeTeaser' attribute is set to 'true' the children of the <teaser> element will be included in the body of the generated webpage. If the 'includeTeaser' attribute is set to 'false' the children of the <teaser> element will not be included in the body of the generated webpage. YES
linkParent If the 'linkParent' attribute is set to 'true', the webpage generated for the parent of this node will be automatically hyper-linked to the webpage generated for this node and vice-versa. If the 'linkParent' attribute is set to 'false', the webpage generated for this node will not be automatically hyper-linked to the webpage generated for the parent of this node and vice-versa. YES
linkSiblings If the 'linkSiblings' attribute is set to 'true', the webpages generated for the siblings of this node will be automatically hyper-linked to from the webpage generated for this node. If the 'linkSiblings' attribute is set to 'false', the webpages generated for the siblings of this node will not be automatically hyper-linked to from the webpage generated for this node. The hyper-links will be placed on the right of the generated webpage. YES
srcDir The 'srcDir' attribute specifies the directory of the XML DocBook source of the item being documented. The item being documented is identified by the 'id' attribute, so the XML DocBook source file for the item being documented is considered to be srcDir/id.xml. This may be omitted if one desires to make a leaf that has no source associated with it. If this is the desired behaviour, 'buildPDF', 'buildHTMl', 'buildChunkedHTML' and 'includeXML' must be set to 'false'. NO
buildPDF If the 'buildPDF' attribute is set to 'true', PDF will be built from the XML DocBook source of the item being documented, specified by the 'id' attribute in the directory specified by the 'srcDir' attribute. The outputted PDF file will be placed in the output directory as dictated by the structure of the tree and linked to from the webpage generated for the node. If the 'buildPDF' attribute is set to 'false', PDF output will not be built and hence it will not be linked to from the webpage generated for this node. YES
buildHTML If the 'buildHTML' attribute is set to 'true', XHTML will be built from the XML DocBook source of the item being documented, specified by the 'id' attribute in the directory specified by the 'srcDir' attribute. The outputted XHTML file will be placed in the output directory as dictated by the structure of the tree and linked to from the webpage generated for the node. If the 'buildHTML' attribute is set to 'false', XHTML output will not be built and hence it will not be linked to from the webpage generated for this node. YES
buildChunkedHTML If the 'buildChunkedHTML' attribute is set to 'true', segmented XHTML files will be built from the XML DocBook source of the item being documented, specified by the 'id' attribute in the directory specified by the 'srcDir' attribute. The outputted XHTML files will be placed in the output directory as dictated by the structure of the tree and placed under the sub-directory segmentedhtml. The segmented XHTML will be linked to via the webpage generated for this node. If the 'buildChunkedHTML' attribute is set to 'false', XHTML output will not be built and hence it will not be linked to from the webpage generated for this node. YES
includeXML If the 'includeXML' attribute is set to 'true', the XML DocBook source created for the item being documented, specified by the 'id' attribute in the directory specified by the 'srcDir' attribute, will have it's xincludes resolved and the single XML file generated placed in the output directory as dictated by the structure of the tree. The XML file will be linked to from the webpage generated for this node. If the 'includeXML' attribute is set to 'false', the XML DocBook source will not have it's xincludes resolved or be linked to from the webpage generated for this node. YES

Both <transnode> and <leafnode> support nested elements that can be used to provide extended functionality. These nested elements are all optional apart from <teaser> which is mandatory.

The teaser element contains information marked up in XHTML 1.0 that is used in the generated webpage for this node. The teaser is used by the parent of the node the teaser belongs to, to provide a little information about it's children to the person browsing the web page. It is called a teaser after the terms use in the entertainment world, i.e, it's purpose is to entice the person browsing the webpage into investigating the item it belongs to. If includeTeaser is set to 'true' the webpage generated for the node the teaser belongs to will contain the children of the teaser element wrapped in a left aligned division inside a center aligned division. The teaser shown below:

          <teaser>
            <p>This is a teaser</p>
          </teaser>
        

Will be output as:

          <div class="content" align="center">
            <div align="left">
              <p>This is a teaser</p>
            </div>
          </div>
        

In the webpage generated for the node the teaser belongs to, assuming that 'includeTeaser' is set to 'true'. If the parent of the node the teaser belongs to sets 'includeChildren' to 'true', a table will be generated containing links to all the webages generated from the children of that parent, each child will be represented by a new row in the table. The row will have two collumns, the first column will contain the link to the webpage generated for the child, the text of the link will be set to the value of the 'name' attribute of the child. The second column will contain the children of the childs teaser element to serve as a description and teaser to the person browsing the webpage.

The teaser is considered mandatory for both transnodes and leafnodes, however, only transnodes can use it to provide information about child nodes since leafnodes have no children. Both transnodes and leafnodes can have the teaser included in the webpage generated for them by setting the 'includeTeaser' attribute to true.

It was found that the automation system lacked the ability to produce some of the output tree and so some of the output tree had to be built via the startup Ant scipt. This was considered to be bad practice since the doctree file should contain all the information required to build the output tree. A simple parsing of the output tree with OutputBuilder.jar should produce all of the output. In order to overcome the limitations of the doctree a special element was created called, ahem, <special>.

The <special element provides the user with the ability to copy files and directories and to create directories. This means that any part of the output tree that cannot be created via a leaf or a transnode can simply be copied from the source directory. This is practical and less time-expensive than modifying the doctree declaration to include a new kind of node or something.

The <special> element may only be used at the root level, i.e as a direct child of the <doctree> element, like this:

        <doctree>
          <transnode...
          <transode...
          <leafnode...
          <title...
          <body...
          <special>
            ...
          </special>
        </doctree>
      

The three elements that may be nested within the special element are shown below.

The main build.xml file is shown below:

<?xml version="1.0" encoding="UTF-8"?>
<project name="Documentation Project" default="all" basedir=".">
  <target name="all" description="Builds all the items in the project and the HTML distribution pages">
    <!-- Load in properties -->
    <loadproperties srcFile="ant.properties"/>

    <!-- Execute the outputBuilder -->
    <java jar="OutputBuilder.jar" fork="true">
      <arg line="doctree.xml"/>
    </java>
  </target>

  <target name="maintain" description="Loads DoctreeMaintainer">
    <java jar="DoctreeMaintainer.jar" fork="true">
      <arg line="doctree.xml"/>
    </java>
  </target>

  <target name="clean" description="Deletes the output directory">
    <loadproperties srcFile="ant.properties"/>
    <delete dir="${build}" includeEmptyDirs="true"/>
  </target>
</project>
    

It is a very simple build file that when ran normally executes the OutputBuilder.jar on the file doctree.xml (the filename can be changed if desired). It also provides a target called maintain which when invoked from the command line like:

ant maintain

Will execute the DoctreeMaintainer.jar program in order to edit the doctree.xml file. (the filename can be changed if desired).

A clean target is provided which deletes the build directory. It is invoked like this:

ant clean

DoctreeMaintainer.jar provides a GUI interface to editing the doctree.xml file. It is built from the Java files located in src/maintainer by running Ant on the build.xml file in that directory. It is invoked like:

ant maintain

From the main Ant build file or from the command line like this:

java -jar DoctreeMaintainer.jar doctree.xml

doctree.xml can be replaced by any other doctree file. A screenshot of the DoctreeMaintainer in action is shown below:

The DoctreeMaintaner in action

As you can see, usage is pretty self-explanitory, one selects the nodes from the list of nodes in the drop down box at the bottom and the information about that node is loaded whereupon one may make changes to the node and save those changes. When a node is loaded, only the fields pertinent to that type of node are editable.

One may create a new node by selecting the transnode that one would like the new node to be a child of and then clicking on "New 'transnode'" or "New 'leafnode'" according to the desired result. One may only create new nodes from a transnode since leafnodes cannot have children. After creating the new node and filling in the required fields, one should click on "save" to save the changes.

One may delete nodes, but only leafnodes, or transnodes without children. If one wants to delete a transnode, one should delete it's children first.

The checkboxes correspond to attributes that may be set to 'true' or 'false'. A tick indicates a value of 'true' and no tick indicates a value of 'false'. When one clicks the save button the information about the node being displayed is saved.

The text areas contain the wrappers for the various elements already. These will not be saved to the file when clicking 'save' unless the wrapper contains some content. The content must be marked up in XHTML 1.0 as dictated by the doctree file format. If the text area has any content it will be added directly to the node hence the need for the wrapping with the tags for the elements like <teaser> and so on. Bare this in mind when using the tool.

Every time the DoctreeMaintainer is ran, it creates a backup of the doctree file it is editing, the name of this backup file is the word 'BACKUP' plus the system date plus the name of the original doctree file, an example is shown below:

BACKUP-Thu-Sep-19-16-53-03-BST-2002-doctree.xml

If one desires to turn off this behaviour one has to edit the file src/maintainer/DoctreeMaintain.java.

DoctreeMaintainer.jar contains the following classes:

OutputBuilder.jar is used to transverse the doctree file to produce the output tree. It is built from the Java files located in src/outputbuilder by running Ant on the build.xml file in that directory. It is invoked, either from the ant file by typing

ant

in the root directory of the documentation project that contains the build.xml file, or by executing:

java -jar OutputBuilder.jar docree.xml

This will automatically transverse the doctree file and build all the output it is directed to build.

OutputBuilder.jar uses a number of 'functions' written as Ant scripts to perform certain actions like building specific output formats for items being documented. The functions used are:

The parameters these 'functions' take are explained in the function source codes. The functions are not called directory but instead, they are invoked from OutputBuilder.jar via targets in a project, this is the purpose of the file AntFunctions.xml which looks like this:

<project name="AntFunctions" default="usage" basedir=".">
  <target name="buildHTML">
    <ant antfile="BuildHTML.xml"/>
  </target>

  <target name="buildChunkedHTML">
    <ant antfile="BuildChunkedHTML.xml"/>
  </target>

  <target name="buildPDF">
    <ant antfile="BuildPDF.xml"/>
  </target>

  <target name="copyXMLFiles">
    <ant antfile="CopyXmlFiles.xml"/>
  </target>

  <target name="makeDirectory">
    <ant antfile="MakeDirectory.xml"/>
  </target>

  <target name="copyFile">
    <ant antfile="CopyFile.xml"/>
  </target>

  <target name="copyDirectory">
    <ant antfile="CopyDirectory.xml"/>
  </target>

  <target name="usage">
    <echo>Provides some 'function' calls to be used by other programs.</echo>
  </target>
</project>
    

The OutputBuilder program loads in this file as an Ant project and then invokes the targets programmatically, this is explained in more detail in the source code for OutputBuilder.

Each of the functions loads in a properties file which defines common properties called ant.properties, this is shown below:

#basic properties for the build
lib=lib
src=src/doc
build=build
fo.output.stylesheet=lib/docbook-xsl/fo/customfo.xsl
xhtml.output.stylesheet=lib/docbook-xsl/xhtml/customdocbook.xsl
xhtml.chunked.output.stylesheet=lib/docbook-xsl/xhtml/customchunk.xsl
graphics.prefix=../build
      

This provides a way to modify certain properties used in the build process.

The project is in CVS. The CVS repository is one directory up from the documentation source tree. The repository only contains projects for this tutorial system. Each project was individually checked into the repository, this was considered appropriate since an automated procedure would require either the specification of the location of the new project, which would therefore be as time consuming as checking the project in manually, or a standard location for projects that is scanned by some program and any new directories added as new projects, which would be too restrictive and problematic.

The build file shown below updates the source tree from the CVS repository and then calls the standard build process to rebuild the projects, this is efficient since CVS will only update when changes have been made and hence the build process will only rebuild when changes have been made.

<project name="project update" default="updateandbuild">
  <target name="updateandbuild" depends="update, build"/>

  <!-- updates the source tree to the latest from CVS-->
  <target name="update">
    <cvs command="checkout" cvsRoot="/bham/htdocs/supportweb/documentation/tutorials/cvsrepos" package="." dest="/bham/htdocs/supportweb/documentation/tutorials/docsystem/src/doc/tutorials/"/>
  </target>

  <!-- calls the build file that generates the rendered output -->
  <target name="build">
    <ant dir="docsystem" antfile="build.xml"/>
  </target>
</project>