DITA Specialization with FrameMaker 10

DITA’s most significant feature is its support for specialization, i.e. adding new elements with specialized semantics that provide alternatives to existing elements. Most DITA users will want to create such customizations at one point or another. The process is simple enough as far as the DITA DTDs are concerned; however, FrameMaker’s rather unique support for structured documents requires several more non-obvious steps before the new specialization is usable in FrameMaker.

This page contains an edited version of the notes I took while trying to figure out this process. I hope it will prove helpful to new FrameMaker users, and also to people shopping around for an integrated DITA solution. Please note that I stopped using FrameMaker with version 10 so I can’t say if and how these tips apply to newer versions.

See Document Standards and Adobe FrameMaker 10 for more information about DITA and FrameMaker in general.

FrameMaker Basics

FrameMaker is not an XML editor with added typesetting capability, but rather the opposite: a DTP-capable word processor that also supports structured documents. Consequently, the hierarchy of file types required for structured editing is somewhat byzantine.

  1. Normal Documents — Unstructured FrameMaker documents are stored in a proprietary binary file format with embedded formatting and layout information, similar to Microsoft Word’s .doc format. Maker Interchange Format (MIF) stores the same data in an alternative SGML-based format for easier processing by external tools, similar to Word’s Rich Text Format (RTF). The file extensions are usually .fm for binary files and .mif for MIF files.
  2. Template Files — FrameMaker documents may store paragraph and character formats in a format catalog, allowing individual chunks of text to reference these formats instead of repeatedly specifying all the required information. You can share format catalogs among multiple documents by using any normal FrameMaker document as a template for new documents. Selecting a template file in the New File dialog copies all its formatting and layout information to the new document.
  3. Structure Applications — Any structured document is based on a structure application which combines a template file with an Element Definition Document (EDD). This is a FrameMaker document which defines all valid elements of the target format, and also determines their visual appearance. The EDD can either map elements to the template’s catalog formats, or directly specify any desired formats and format changes. When editing a structured document you are presented with its element tree, which is validated against the structure defined by the EDD.

    Note: You must import an EDD is into the associated template before you can base a structured document on the latter. Technically, you could delete the EDD at this point since its entire data is now embedded in the template; but FrameMaker cannot edit embedded EDD data, so you need to keep around the separate EDD file for potential future changes.

  4. XML Schemas — Structure applications may reference XML/SGML schemas but do not require them. You may import a DTD into an EDD to establish an element hierarchy, but the effect is the same as if you had manually created that hierarchy. The element structure of FrameMaker documents is defined exclusively by EDDs, and FrameMaker does not automatically update EDDs to reflect changes in associated DTDs. For example, whenever you specialize some DITA DTD you must find the corresponding EDD and replicate your structural changes to keep the two formats in sync.
  5. Read/Write Rules — Structure applications that reference XML/SGML schemas usually also define read/write rules. These are simple text files that determine the XML/SGML representation of complex objects such as tables. When you edit an XML file whose DOCTYPE indicates a known structure application, FrameMaker uses the application’s template (with embedded EDD) and read/write rules to internally convert the XML file into a normal document for editing. Saving an edited document causes FrameMaker to convert the file back into XML using the same mechanism.

The DITA 1.2 implementation that ships with FrameMaker 10 uses two other features that are relevant to our specialization example: text insets and variables. The much simpler DITA 1.1 implementation uses some variables but no text insets, by the way.

  • EDD Text Insets — All FrameMaker documents offer a feature called text insets, meaning that an entire other FrameMaker document is inserted at a specified place. The text inset is read-only as far as the containing document is concerned. The DITA 1.2 EDDs use this mechanism to partially recreate the external entity hierarchies of the XML DTDs. For example, the highlight domain is implemented by a single EDD fragment which appears as a text inset in all topic EDDs. This mechanism is unfortunately not quite as elegant as it sounds, because these text insets are not automatically updated. If you change some particular domain EDD you must manually update all higher-level EDDs that import it, whether directly or indirectly.
  • EDD Variables — Another standard FrameMaker feature, variables are essentially names for arbitrary text content, defined in a document’s global variable list. Whenever a variable is referenced, its text content appears instead. The top-level DITA 1.2 EDDs use this mechanism in conjunction with text insets for recurring lists of element choices. If you add new elements to an imported domain EDD, you must also add the new choices to all corresponding variables. All imported EDDs will automatically reflect the new variable values, without a manual update. Annoyingly, there can be multiple variables referring to the same domain EDD, and you typically need to change them all.

This concludes our brief tour of FrameMaker’s support for structured documents. Please refer to the various FrameMaker manuals for more details.

Composite Documents

Composite documents consist of multiple parts which are, physically or logically, individual documents in their own right. A typical example is a book containing multiple chapters, with each chapter perhaps containing multiple sections.

Structured markup can either directly embed the component topics as nested elements, or else link to a separate file for each component. DITA implements the first option with the ditabase document type, and the second option with the map and bookmap document types (so-called DITA maps).

Unfortunately, FrameMaker 10 supports only the first option fully. Let’s have a look at the various ways to create composite DITA documents in FrameMaker, and their respective shortcomings.

  • ditabase — Works as expected, but has all the drawbacks that led to the creation of DITA maps: all components are stored in one monolithic file which knows only ditabase elements and uses only ditabase formatting. There is no support for book features such as automatically generated lists and tables, although PDF output does generate bookmark trees for title elements.
  • map — Supported, but with a very odd twist: when creating print or PDF output, FrameMaker first combines all linked documents into a single composite ditabase document, and then outputs that document! This process reformats all your topics according to the ditabase template, rather than the template for the original topic type. So unless you only have ditabase topics, you must ensure that your ditabase formatting exactly matches that of all your topic types – or else you’ll see different formatting on screen and in print.
  • bookmap — Supported, but with the same formatting issue and more problems to boot: FrameMaker cannot create any of the book lists that are the sole raison d’être for this document type! Not only are the corresponding DITA elements ignored, but the list creation and numbering/pagination features of standard FrameMaker books are unavailable, too. (The initial release also ignored the booktitle element in print & PDF output, but that has been fixed in version 10.0.1).

What to do? DITA maps require an annoying duplication of all topic formatting in ditabase, and bookmap is so poorly supported as to be virtually pointless. You can always fall back on old-style ditabase composite documents if you are happy with their limitations. Otherwise, you might consider two more options.

  • FrameMaker Book — You can add DITA topic files as chapters to unstructured FrameMaker books. This works well, formats each topic file according to its own template (rather than ditabase), and provides standard book features such as automatic list generation. There are two major drawbacks: the book itself is not a DITA map, and you cannot nest topics to automatically reformat title elements as chapter, section, or subsection titles. If you require such hierarchies you either need to recreate all titles as virtual book “folders”, or else write ditabase chapters with embedded topic nesting.
  • Third-Party Tools — Leximation’s DITA-FMx promises automatic generation of bookmap lists and tables, among many other improvements. I cannot give a recommendation as I haven’t used this toolkit, but you may wish to check out the documentation and trial version if you intend to author DITA bookmaps with FrameMaker 10.

In the following specialization examples, we focus on the standard DITA topic type. However, as this section shows, you may unexpectedly require ditabase formatting when authoring composite documents in FrameMaker. Customizing ditabase works exactly the same way as customizing topic – simply substitute “ditabase” for “topic” in all file paths and document type names.

Preparations

Before we attempt to specialize the DITA 1.2 implementation that ships with FrameMaker 10, it’s a good idea to create our own local copy on which all modifications are performed. The new DITA specializations will exist side-by-side with the original document types.

  1. Locate the original DITA 1.2 installation in directory C:\­Program Files\­Adobe\­AdobeFrameMaker10\­Structure\­xml\­DITA_1.2\­app. On 64-bit versions of Windows, substitute Program Files (x86) for Program Files.
  2. Copy the entire directory tree below app to a new directory in your user space. We’ll assume (My) Documents\­ditamod but you can pick any name you like. Note that our specializations require only the subdirectories base and technicalContent, so you can skip the others until you want to modify their contents.

Now we need to decide how to make our modifications available to FrameMaker. We could simply change the original structure applications to redirect FrameMaker to the new directory tree. However, it’s probably smarter to leave the original applications unchanged, and create new applications with different names for our modifications. This allows side-by-side use of both the original and the modified applications.

Each DITA top-level element corresponds to one structure application. For our example, we choose the most popular one: the default topic element defined in technicalContent\­dtd\­topic.dtd.

  1. Open the EDD file ditamod\­technicalContent\­edd\­topic.edd.fm in FrameMaker. Change the structure application name right at the top from “DITA_1.2_topic” to “DITAmod_1.2_topic” (or whatever name you like). Save the file but leave it open for now.
  2. Open the template file ditamod\­technicalContent\­template\­topic.template.fm in FrameMaker. Choose File: Import: Element Definitions… from the main menu, change the Import from Document field to topic.edd.fm (only open files are listed), and click Import. Now choose StructureTools: Set Structured Application… from the main menu to verify that the template is now associated with “DITAmod_1.2_topic”. Save the template and close both files.

Lastly, we must inform FrameMaker of our new topic application. FrameMaker maintains lists of available and default applications for each Windows user, so let’s edit those.

  1. Choose StructureTools: Edit Application Definitions from the FrameMaker main menu. Copy the entire block “DITA_1.2_topic” right at the start of the file, paste it to the end of the file, and change the copied application name to “DITAmod_1.2_topic”. Now change all directory prefixes in the copied block from $STRUCTDIR\­xml\­DITA_1.2\­app\ to the location of your ditamod folder. Keep all the subdirectories and file names after the prefix. Save the file and choose StructureTools: Read Application Definitions to complete this step.
  2. We can also make our modified application the default for DITA 1.2 topic elements. Choose DITA: DITA Options… from the FrameMaker main menu, ensure that DITA v1.2 is selected, and click Application Mappings…. Now select the mapping tag “DITA_1.2_Applications” (which is stupidly not preselected), scroll down to the “topic” entry, and change its application from “DITA_1.2_topic” to “DITAmod_1.2_topic”. Click Add/Edit and confirm both dialogs.

Now we have redirected the DITA 1.2 topic element to our local application, which is (so far) completely identical to the default application except for its internal name. If you wish to modify base elements other than topic, you’ll have to look up the corresponding EDD and template files in FrameMaker’s structure application definitions and repeat steps 3–6 accordingly. You can also create a new document type entirely, but we don’t cover this possibility here.

Note that many DTD and EDD files in the copied directory tree refer to other files in the same directory tree. For example, various files under technicalContent include files under base. Fortunately, all references use relative paths (..\..\) so we don’t need to update them, as long as the subdirectory structure remains intact.

Adding Small Caps

With our preparations complete, it’s time to create a simple specialization. Let’s add a new element called sc to the highlight domain that should request Small Caps formatting. As with any DITA domain specialization, we first need to add the new element to the DTD fragments for the domain.

  1. The two changed DTD fragments for the highlight domain are highlightDomain.mod and highlightDomain.ent, downloadable for your convenience. Compare them to the original versions to see the various changes, then put both files in the directory ditamod\­base\­dtd.

That’s all, as far as DITA is concerned. Now we need to inform FrameMaker of those changes. Although you can theoretically import a changed DTD into an existing EDD, I found that doing so with a DITA 1.2 EDD resulted in wiping out most of its contents! The DTD import function appears to be incompatible with the text insets used by the DITA 1.2 EDDs. No matter, performing the EDD update by hand is more instructive anyway…

  1. Open the EDD fragment ditamod\­base\­edd\­highlightDomain.eddmod.fm in FrameMaker. Copy the i element and paste it as a sibling to the other elements. Change the topmost tag of the copied element from “i” to “sc”, the default for its “class” attribute from “+ topic/ph hi-d/i” to “+ topic/ph hi-d/sc”, the character format in its text format rules from “high.italic” to “high.smallcaps”, and its descriptive tag from “Italic” to “Small Caps”. Save and close the file.
  2. Open the top-level EDD file ditamod\­technicalContent\­edd\­topic.edd.fm, i.e. the one whose application name we already changed to “DITAmod_1.2_topic”. Show the Variables window in FrameMaker and insert “| sc ” after any occurrence of “| i ” in a variable definition. The four affected variables are “basic.ph; before xref”, “basic.ph.noxref”, “ph”, and “title.cnt; before image”. Use the Add/Edit Variable window to perform and confirm the changes.
  3. Still within the file topic.edd.fm, select the section named “highlightDomain.eddmod.fm”. This is the text inset that refers to the eponymous file. In the Text Inset Properties window, check that the source is correct and click Update. Save the EDD when this rather lengthy process is complete, but leave it open.
  4. Open the associated template file ditamod\­technicalContent\­template\­topic.template.fm. Choose Format: Characters: Designer… from the FrameMaker main menu to show the Character Designer window. Select the character tag “high.italic”, then Commands: New Format…. Enter the tag “high.smallcaps”, check Store in Catalog but uncheck Apply to Selection, and click Create. Back in the Character Designer window, select the new character tag “high.smallcaps”, change the angle to As Is, check Small Caps, and click Update All. (If you intend to use small caps for acronyms, you may also wish to change the language to None to prevent spell checking.)
  5. Still within the file topic.template.fm, choose File: Import: Element Definitions… from the main menu, change the Import from Document field to topic.edd.fm, and click Import. This introduces the new element sc into our template, mapped to the new character format “high.smallcaps”. Save and close all files.

Repeat steps 3–6 for any other modified DITA document types that should include the new sc element. Note that the top-level EDDs for map and bookmap directly embed the element definitions for the highlight domain, rather than importing highlightDomain.eddmod.fm as a text inset. In that case, you also need to repeat step 2 directly in the top-level EDD while omitting step 4.

Adding Equations

FrameMaker has a fairly powerful equation editor, but DITA does not (yet) offer any built-in support for equations. This feature is left to domain specialization, so that’s exactly what we are going to do.

There is an old workspace for a DITA 1.1 math domain based on MathML. The workspace has seen no update since its creation in February 2009, which probably tells us something about the priority the DITA community assigns to mathematical typesetting.

Our quick & dirty implementation is largely unrelated to the rather complex workspace proposal, and in any case FrameMaker does not support MathML so we use its native equation format instead. However, we adopt the names and concepts of three basic elements:

  • math and mathph specialize foreign to wrap equations. math is intended for stand-alone equations whereas mathph is intended for inline equations, but our implementation does not formalize these intentions.
  • equation specializes fig to wrap math elements (instead of regular images) and associate them with a caption. Again, our implementation does not formalize this intention; you can put anything you like into an equation.

Now let’s implement these three elements. Since we have several new files and multiple changes in existing files, I put up most of the affected files for download to simplify matters.

  1. The two DTD fragments for our new math domain are mathDomain.mod and mathDomain.ent. Put both files in the directory ditamod\­base\­dtd.
  2. The corresponding EDD fragment is mathDomain.eddmod.fm and should go in the directory ditamod/base/edd. This EDD mostly just copies the default definitions for fig and foreign, but also changes the element type of math and mathph from “Container” to “Equation”. This last change tells FrameMaker to bring up the equation editor when you insert one of those elements.
  3. Adding an entire new domain entails editing any top-level DTD that should receive that domain. Place the changed file topic.dtd in directory ditamod\­technicalContent\­dtd to include the new math domain in the standard topic document type.
  4. The corresponding top-level EDD is ditamod\­technicalContent\­edd\­topic.edd.fm, and now the process gets laborious. Open the file in FrameMaker, show the Variables window, and insert “| equation ” after any occurrence of “| fig ” in a variable definition. The affected variables are “basic.block; before image” and its four variants with “.nolq”, “.noquote”, “.nopara”, and “.notbl” after “basic.block”. Now insert “| math | mathph ” after “foreign” in the variable definition “foreign.unknown.incl”. Use the Add/Edit Variable window to perform and confirm the changes.
  5. Still within the file topic.edd.fm, move the cursor past the last section. Choose File: Import: mathDomain.edd.fm… from the main menu. (That file must be open for the choice to appear.) Verify that Body Page Flow and Reformat Using Current Document’s Catalogs are checked, but change Updating of Imported Flow from Automatic to Manual. Now click Import and save the file, but leave it open.
  6. Open the associated template file ditamod\­technicalContent\­template\­topic.template.fm. Choose File: Import: Element Definitions… from the main menu, change the Import from Document field to topic.edd.fm, and click Import. This introduces the new math domain elements into our template. Save and close all files.
  7. We need additional read/write rules to store equations as FrameMaker MIF files when saving the containing DITA XML file. Place the changed file topic.rules.txt in directory ditamod\­technicalContent\­rules. The new rules for math and mathph appear at the bottom.

Repeat steps 3–7 for any other modified DITA document types that should include the new math domain elements. Note that FrameMaker will gobble spaces after mathph equations that were deserialized from MIF files. To prevent this, simply use a non-breaking space (Ctrl+Space) after inline equations.

Note: If you try to use these read/write rules with FrameMaker 9, you’ll encounter an annoying bug. Whenever an equation is exported to a MIF file, FM9 will create a new file rather than overwriting the existing file. Worse, FM9 does this whenever the containing XML document is saved, whether the equation itself has changed or not. This makes roundtripping equations to and from XML effectively impossible. Fortunately, FrameMaker 10 has fixed this issue.