Packaging Document Type Shells and Vocabulary Modules as Toolkit Plugins
You can simplify deployment and testing of document type shells and vocabulary modules by packaging them as Open Toolkit plugins.
The DITA Open Toolkit provides a general plugin facility that makes it easy to integrate local shells and new vocabulary modules into the Toolkit's master entity resolution catalog. This makes the shells and modules immediately available to all processors that use the Toolkit's catalog, including, of course, the Toolkit itself.
If your DITA-aware editor uses the Toolkit's catalog to resolve DTD and XSD references, then by deploying your modules to the Toolkit, you should be able to immediately start validating and editing with your shells and modules. For example, the OxygenXML editor is configured by default to use the master catalog of the Open Toolkit. By deploying your shells and modules as Toolkit plugins, Oxygen can immediately use them with no additional configuration. This makes it very quick to develop and test new shells and vocabulary modules.
Entity resolution catalogs are an OASIS standard supported by most XML-aware tools. A catalog provides a mapping from public identifiers, system identifiers (such as URNs) and URIs, to files on a local system.
The Open Toolkit's plugin mechanism works through pre-defined extension points that plugins can plug into One extension point is in the master entity resolution catalog, catalog-dita_template.xml.
Neither the Toolkit nor the DITA standard dictate how to organize your document type shells and modules. The practice I use is to package all the document type shells and modules for a given project into a single plugin, named "unique-package-prefix.doctypes," where unique-package-prefix is a Java-style reverse Internet domain name, for example, "com.planetsizedbrains," resulting in a plugin named "com.planetsizedbrains.doctypes." The point of the Java-style name is to ensure that the plugin's name will be unique in any Toolkit instance.
As deployed to the Toolkit, a plugin is just a directory containing the files that make up the plugin.
com.planetsizedbrains.doctypes/ doctypes/ concept/ phase-of-moon-AttDomain/ reference/ task/ topic
- plugin.xml, which defines the plugin to the Toolkit and controls how it is integrated with the extension point.
- catalog.xml, which is the file that will be integrated with the extension point in the main catalog-dita_template.xml file.
The doctypes/ directory under the main plugin directory contains a master catalog file that includes the catalogs from each module-specific directory. This organization provides a general-purpose root directory for your doctypes regardless of how they might be packaged for different tools.
com.planetsizedbrains.doctypes/ doctypes/ concept/ dtd/ xsd/ phase-of-moon-AttDomain/ dtd/ xsd/ reference/ dtd/ xsd/ task/ dtd/ xsd/ topic dtd/ xsd/
With this organization, the catalog.xml files that map public IDs or schema location URNs to files go in the dtd or xsd directories. Each module's main directory contains a catalog.xml file that simply includes the catalog files from each of the subdirectories. This approach keeps everything self contained at each level. If you add or remove a module from your plugin you simply update the top-level catalog file in the doctypes/ directory to add or remove a reference to that module's top-level catalog file and everything just works.
<?xml version="1.0" encoding="UTF-8"?> <catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog" prefer="public"> <!-- NOTE: The following catalog entries will be added to the Toolkit's top-level catalog-dita.xml without modification, so they need to work as they will be in that catalog, not as they exist within the plugin's directory. --> <nextCatalog catalog="doctypes/catalog.xml"/> </catalog>
<?xml version="1.0" encoding="UTF-8"?> <catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog" prefer="public"> <nextCatalog catalog="topic/catalog.xml"/> <nextCatalog catalog="concept/catalog.xml"/> <nextCatalog catalog="reference/catalog.xml"/> <nextCatalog catalog="task/catalog.xml"/> <nextCatalog catalog="phase-of-moon-AttDomain/catalog.xml"/> </catalog>
This is the catalog that will be included by the
<nextCatalog> entry added to the main catalog-dita.xml file.
<?xml version="1.0" encoding="UTF-8"?> <catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog" prefer="public"> <nextCatalog catalog="dtd/catalog.xml"/> <nextCatalog catalog="xsd/catalog.xml"/> </catalog>
<?xml version="1.0" encoding="UTF-8"?> <catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog" prefer="public"> <public publicId="urn:pubid:dita4practitioners.com:doctypes:dita:topic" uri="topic.dtd" /> <system systemId="urn:pubid:dita4practitioners.com:doctypes:dita:topic.dtd" uri="topic.dtd" /> </catalog>
The general pattern here is that there is a catalog in each directory that points down into the next directory. Only the top-level catalog and leaf catalogs vary—the intermediate catalogs are always the same. This makes it easy to copy an existing module or shell's directory tree as the starting point for a new module or shell. This also makes it easier to reorganize the directories if necessary, since no single catalog points down more than one directory level.
<plugin id="com.planetsizedbrains.doctypes"> <feature extension="dita.specialization.catalog.relative" value="catalog.xml" type="file"/> </plugin>
The bit in bold is the plugin identifier and is the only part you must change for
your own module. The
<feature> element is always the same for a doctype plugin. The plugin name must be unique across
all plugins in your Toolkit, so the easiest and most reliable thing is to use the
same Java-style name for the plugin ID as you used for the plugin's directory.
ant -f integrator.xml
Your shells and modules should be ready to use. You can verify the integration by opening the Toolkit's catalog-dita.xml file and looking for a reference to your plugin's top-level catalog file. If you are using an editor like OxygenXML that lets you follow file references (in Oxygen you put your cursor on a line that contains a reference to a file and press "ctrl+enter"), you can use that feature to follow the chain of references from catalog to catalog to make sure you have everything hooked up correctly. But if you followed the file organization pattern shown here, it should be good.