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 your editor uses, 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 provided with the Oxygen editor. By deploying your shells and modules as Toolkit plugins Oxygen becomes immediately able to use them with no additional configuration required. This makes it very quick to develop and test new shells and vocabulary modules.
Entity resolution catalogs are an OASIS standard and are 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 [see general section on creating Toolkit plugins]. One extension point is in the master entity resolution catalog, catalog-dita_template.xml.
Neither the Toolkit nor the DITA standard say how you have 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 (or that otherwise would be expected to work together or that are developed and deployed as a unit) into a single plugin, named "unique-package-prefix.doctypes", where unique-package-prefix is a Java-style reverse Internet domain name, e.g. "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 it's deployed to.
As deployed to the Toolkit a plugin is just a directory containing the files that make up the plugin.
doctypes
that then contains one subdirectory for each distinct vocabulary module or document type shell. For example, if I have a shell for each of the base topic types plus a new attribute domain module, the directory structure in my plugin would be: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 appropriate 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 then 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.
catalog.xml
file providing the appropriate catalog entries for the files in that subdirectory. If I expect to have both DTD and XSD versions of my shells or modules, I create another level of subdirectory, one for DTDs and one for XSDs, like so: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 provide the actual mapping from public IDs or schema location urns to files go in the dtd
or xsd
directories. Each module's main directory just 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.
catalog.xml
file under the com.planetsizedbrains.doctypes
directory would look like this:<?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 plug-in's directory. --> <nextCatalog catalog="doctypes/catalog.xml"/> </catalog>
com.planetsizedbrains.doctypes/doctypes/
directory looks like this:<?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 add 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>
dtd
or xsd
directory for a document type shell, the catalog would look something like this:<?xml version="1.0" encoding="UTF-8"?> <catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog" prefer="public"> <public publicId="urn:pubid:planetsizedbrains.com:doctypes:dita:topic" uri="topic.dtd" /> <system systemId="urn:pubid:planetsizedbrains.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.xml
file goes in the top-level directory. For a document type plugin it looks like this:<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.
plugins/
directory of your Toolkit and run the integrator.xml
Ant script, e.g., from the root directory of the Toolkit: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 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.
[Need a reference to a general topic on troubleshooting entity resolution issues.]