DITA specialization using FrameMaker
What is DITA Specialization
Specialization is the process by which new designs are created based on existing designs, allowing new kind of content to be processed using existing processing rules. Specialization allows you to define new kinds of information (new structural types or new domains of information), while reusing as much of existing design and code as possible, and minimizing or eliminating the costs of interchange, migration, and maintenance.
FrameMaker provides special handling for many objects in DITA like Table, Image, Title, Indexterm, Xref etc. so when we specialize any such element which have some special handling, same handling should be available for it. E.g. when we insert a crossref in any DITA document (xref or fm-xref element from element catalog or Special->Cross Reference), DITA-Cross reference dialog shows up. Same should happen if we insert any specialized xref element in any DITA document and name of specialized element should also show in DITA Element drop down.
Types of DITA specialization
- Specialization can be broadly categorised into two types
- Structural Specialization
- Domain Specialization
Structural specialization defines new types of structured information, such as new topic types or new map types. Structural types define structures for modules of information, such as concept or task or reference, which often apply across subject areas. When doing structural specialization we generally create new specialized elements from top (Map or Topic) and then create specialization till the element required so essentially with structured specializtion, we create a whole new hierarchy e.g. if we have to create a new structurally specialized UIControlWindow element for uicontrol element, we should create Specialization of Topic, body, p, uicontrol elements.
Domain specialization creates new markup that can be useful in multiple structural types, such as new kinds of keywords, tables, or lists, or new attributes such as conditional processing attributes.Domains typically define markup for a particular domain or subject area, such as programming, or hardware. Domain elements become available wherever their ancestor elements are allowed once the domains are integrated with the structural specializations in a document type. E.g. if we create domain specialized table element , it should be available whereever table element is, in the element hierarchy.
NOTE: We dont support attribute based specialization in FrameMaker.
How to Specialize DITA Elements in FrameMaker
When we are specializing DITA elements, the most important and tedious process is defining the new specializing elements and deciding where they will fit in the existing DITA hierarchy. Some times we can get carried away and specialize elements more than what’s required or can create crude specializations. So most effort should be put in carefully designing the specialized elements required and should avoid creating specialized elements when the existing elements could suffice. Once we have the list of elements we want and defined where they will fit in the existing DITA elements hierarchy, 75% task is done and rest is moreover following the following mechanical steps.
- Create new set of DTDs defining the new set of elements derived, from existing element types. The Detailed steps for this are listed at the end.
- Combine the specialized DTDs into a base dtd.
- Create a new Read Write Rule file using the existing standard Topic/Map read write rule file and add the element mappings for specialized elements derived from DITA elements, which have some mappings defined. Its like if we have any declaration in read write rule file for the base element and we want the element derived from that to have similar functionality, we need to add the same declaration for child element as well e.g. If we have mapped DITA image element to FrameMaker Graphic element then the specialized image element need to have same declaration in read write rule file to have special image handling. If there is unwrap statement for any element, then elements derived from that should be unwrapped as well.
- Import the base DTD as EDD in FrameMaker using the read write rule file and DTDs created in step 1-3.
- Check the class attributes of all the specialized elements in EDD. The correct element hierarchy should be created from the base element to the specialized one. Its the only criteria for Frame to map specialized element to its parent element.
- Make FrameMaker specific changes in the EDD file as listed below:
- For topic specialization
- Copy All the elements starting from “FM-” from standard Topic EDD to the New EDD generated. These are all FrameMaker specific elements which are declared to handle special objects like table, crossref, image etc.
- Change the content model of element properties to “fm-propheading?, fm-propertybody+”.
- Change the content model of element choicetable to “chhead, fm-chbody” and simpletable to “sthead, fm-stbody.
- Change the content model of sthead to “fm-stheadrow” and chhead to “fm-chheadrow”.
- Add fm-xref element to the content model of xref, syntaxdiagram, synblk, groupseq, groupchoice, groupcomp andfragment elements and all the elements where xref is valid. We need to do the same for specialized xref elements as well i.e. whereever any element of type xref is allowed, fm-xref should also be allowed.
- Add fm-linktext where ever linktext or any specialization of linktext is allowed.
- Hide the elements fm-graphic, alt, index-base, index-see, index-see-also and index-see-also using conditional tag.
- For Map specialization
- Change the content model of reltable to (fm-reltablemeta)?,(relheader)?,(fm-reltablebody).
- Change the content model of relheader to (fm-relheaderrow).
- Copy elements fm-relheaderrow and fm-reltablebody from standard Map edd to current EDD.
- Add fm-topicreflabel to content model of topicref.
- Copy the element formatting of standard DITA elements from the default DITA Topic/map EDD to the new EDD and also define the formatting rules for the new specialized elements.
- Import EDD into new template file, import paragraph and character formats from standard DITA template into this new template and create new structured application for specialized elements using the template, read write rule and the integrated DTD file created from step 1-7. Add new topic type as doctype in the application definition and also replace the name of ditabase.dtd with the new integrated DTD created in step 1. We also need to change the value of “writer external dtd” in the read write rule file to the new integrated dtd name.
- Change the new application name in DITA option dialog (DITA-Topic Application, DITA Map Application) and click on save.
- You should be able to see your specialized Topic/Map in the DITA->New DITA file submenu. Start authoring. It’s simple.
DITA elements with special handling in FrameMaker for specialization
For special elements like table, image, indexterm, footnote etc. the EDD contains special information denoting its type. All specialized elements for such special elements should also have corresponding information in EDD then only the special handling can be provided to the specialized elements. Following is the list of elements with special handling and the needful for specialization.
- topicref:- User should include fm-topicreflabel as the valid first element in the general rule of its specialized topicrefs. The functionalities like update reference, open all topicref, conref topic ref, navtitle update etc. are also available for specialized topicrefs.
- indexterm:- If indexterm import and export processing is ON in DITA options then the nesting of indexterm and Index-see, index-see-also, index-sort-as processing etc. is also available for specialized indexterms.
- table/simpletable/reltable/choicetable:-DITA table elements doesn’t contain numCols and colWidth properties which need to be set explicitly in ditafm.ini for reltable/simpletable and for elements specialized from them. While specializing reltable, simple table etc., user need to add elements parallel to fm-reltablemeta, fm-chheadrow etc with similar structure in the EDD file (as we have for standard elements) and need to make similar declarations in read write rule file for the new elements. When we insert specialized table/simpletable/reltable elements, the name of specialized elements also appears in insert table dialog.
- topic/map:- If correct specialized topic/map application is set in DITA options, the specialized topic/map name appears in DITA->New DITA file submenu. Composite FM doc/ Book with FM doc etc functionality is available for the specialized topics as well.
- image/alt:- We need to make declaration in read write rule file for specialized image element to work as Frame graphic object. We don’t support specialization of alt element.
- xref/link:- When a specialization of xref element is created, in the EDD file, we need to make element fm-xref available whereever the specialized xref is available. When we insert specialized xref/link element in DITA document, DITA-CROSS REFRENCE dialog opens and name of specialized xref/link element is available as DITA element.
- linktext:- We need to add fm-linktext in the EDD, as a valid choice, at all occurrences of specialized linktext element.
- prolog/draft-comment:- If the DITA option for conditionalize prolog/comments on file open is selected, then the specializations of prolog and draft-comment elements are conditionalized as well.
- fn:- We need to declare specialized fn element as footnote in read write rules file.
- NOTE: For all the above elements with some special handling, empty class attribute is allowed for the base element.
How to make changes in DITA DTDs for specialization
DITA dtds are divided into smaller modules, based on the base elements hierarchy (Topic and Map) and their respective domain and structural specializations like Task, Concept, BookMap, UIDomain, Programing Domain etc. There are fixed set of changes which need to be done in DTDs which are defined below.
Making changes in DTDs for structural specialization
For structural specialization, we need to create a new DTD file with specialized elements and then we have to integrate it with the existing DITA DTDs, the way we want our final output to work. If we want to make our specialized elements types work with the existing topic/map hierarchies, we can add our specialization to ditabase.dtd or we can create a separate dtd. We will take an example where user want to define a new specialized object element with only specialized xref and footnote elements as its content model.
The Steps to perform are:
- Copy any existing MOD file and rename it. e.g. refrence.mod to objectsp.mod.
- Open the new mod file e.g. objectsp.mod and in section “SPECIALIZATION OF DECLARED ELEMENTS”, change infotype declaration to the newly declared structured type, which will be required for integrating the specialized modules with the existing ones.
<!ENTITY % objectsp-info-types "%info-types;" >
- ADDITIONAL INFORMATION: In next 3 steps, remove the existing stuff in the respected heads and add the new elements related information. We copy existing DTds mainly for the purpose that we get a formatted structure defined for declaring our new elements.
- Declare the new entities for the specialized elements required till the top of the hierarchy.
<!ENTITY % myobjecttype "myobjecttype" > <!ENTITY % mybody "mybody" > <!ENTITY % myp "myp" > <!ENTITY % myobject "myobject" > <!ENTITY % myxref "myxref" > <!ENTITY % myfootnote "myfootnote" >
- Declare the new specialized elements:
<!ELEMENT myobject ((%myxref;)*, (%myfootnote;)*)> <!ATTLIST myobject declare (declare) #IMPLIED classid CDATA #IMPLIED codebase CDATA #IMPLIED data CDATA #IMPLIED type CDATA #IMPLIED codetype CDATA #IMPLIED archive CDATA #IMPLIED standby CDATA #IMPLIED height NMTOKEN #IMPLIED width NMTOKEN #IMPLIED usemap CDATA #IMPLIED name CDATA #IMPLIED tabindex NMTOKEN #IMPLIED longdescref CDATA #IMPLIED %univ-atts; outputclass CDATA #IMPLIED longdescre CDATA #IMPLIED >
- and so on for other elements
- In “SPECIALIZATION ATTRIBUTE DECLARATIONS” section, declare the element from which the specialized element is derived from. We have to declared the hierarchy till the base topic/Map type (starting with a “-” for structural specialization) e.g. if the specialized element is derived from any reference element, we have to define the complete hierarchy from specialized element to reference to topic (as reference is again specialized from topic).
<!ATTLIST myobjecttype %global-atts; class CDATA "- topic/topic myobjecttype/myobjecttype" > <!ATTLIST mybody %global-atts; class CDATA "- topic/body myobjecttype/mybody" > <!ATTLIST myp %global-atts; class CDATA "- topic/p myobjecttype/myp" > <!ATTLIST myxref %global-atts; class CDATA "- topic/xref myobjecttype/myxref" > <!ATTLIST myobject %global-atts; class CDATA "- topic/object myobjecttype/myobject" > <!ATTLIST myfootnote %global-atts; class CDATA "- topic/fn myobjecttype/myfootnote" >
- Integrate the new mod file with the existing ones by modifying ditabase.dtd. For the specialization in the example stated above, add entry in the “TOPIC NESTING OVERRIDE” section for declaring the new type with the base types and in “TOPIC ELEMENT INTEGRATION” section for importing the mod file
<!ENTITY % info-types "topic | concept | task | reference | ? myobjecttype | glossentry" > <!ENTITY % topic-type PUBLIC ?"-//OASIS//ELEMENTS DITA Topic//EN" ?"topic.mod" > %topic-type; <!ENTITY % objectsp-type PUBLIC ?"-//OASIS//ELEMENTS DITA Topic//EN" ?"objectsp.mod" > %objectsp-type;
- HOW TO MAKE CHANGES IN DITA DTDS FOR SPECIALIZATION MAKING CHANGES IN DTDS FOR DOMAIN SPECIALIZATION
- … and the other existing ones
- ADDITIONAL INFORMATION: If we want to restrict multiple topic types in a single topic type we can create a new integration file and not pull in all the topic types together like we did in the current example.
Making changes in DTDs for domain specialization
For domain specialization, we need to create 2 DTD files. In first file we declare the specialized elements and in the second dtd we declare the entities for integration related information as domain specialized elements should be available where ever their base element is. We will take an example where user want to define 3 new domain specialized elements for image, prolog and link respectively.
The Steps to perform are :-
- Copy any existing MOD file and rename it. e.g. utilitiesDomain.mod to domainsp.mod.
- ADDITIONAL INFORMATION: In next 3 steps, remove the existing stuff in the respected heads and add the new elements related information. We copy existing DTDs mainly for the purpose that we get a formatted structure defined for declaring our new elements
- Open the new mod file e.g. domainsp.mod and in section “ELEMENT NAME ENTITIES”, declare the new entities for the specialized elements.
<!ENTITY % Dlink "Dlink" > <!ENTITY % Dprolog "Dprolog" > <!ENTITY % Dimage "Dimage" >
- Declare the new specialized elements.
<!ELEMENT Dimage (%alt;) > <!ATTLIST Dimage href CDATA #REQUIRED keyref NMTOKEN #IMPLIED alt CDATA #IMPLIED longdescref CDATA #IMPLIED height NMTOKEN #IMPLIED width NMTOKEN #IMPLIED align CDATA #IMPLIED scale NMTOKEN #IMPLIED placement (inline | break | -dita-use-conref-target) "inline" %univ-atts; outputclass CDATA #IMPLIED >
- … and so on for other elements.
- In “SPECIALIZATION ATTRIBUTE DECLARATIONS” section, declare the element from which the specialized element is derived from. We have to declared the hierarchy till the base topic/Map type (starting with a “+” for domain specialization) e.g. if the specialized element is derived from any other utility domain element, we have to define the complete hierarchy from specialized element to utilities domain to topic (as utilities domain is again specialized from topic).
<!ATTLIST Dprolog %global-atts; class CDATA "+ topic/prolog domainsp-d/Dprolog " > <!ATTLIST Dlink %global-atts; class CDATA "+ topic/link domainsp-d/Dlink " > <!ATTLIST Dimage %global-atts; class CDATA "+ topic/image domainsp-d/Dimage " >
- Next we need to define the ENT file which allows the elements to be substituted instead of being aggregated i.e. wherever the parent element is allowed, the specialized one should be allowed as well. Create a new ENT file (or copy any existing one).
- Open the ENT file and declare the entities for integration of new elements with the existing one (using domain extensions)
<!ENTITY % domainsp-d-image "Dimage" > <!ENTITY % domainsp-d-link "Dlink" > <!ENTITY % domainsp-d-prolog "Dprolog" >
- In same ENT file, decare the domain attribute entity to define the ancestry till the root from which the elements are derived. If you are specializing any element from some domain extension, then you need to declare till the top.
<!ENTITY domainsp-d-att "(topic ank-d)" >
- Integrate the new mod file with the existing ones by modifying ditabase.dtd. For domain specialization we need to integrate both element definition dtd and the ENT file we created so we need to modify at 4 different places
- First we need to do the vocabulary declaration and define the new domain.
<!ENTITY % domainsp-d-dec PUBLIC "-//domainsp//ENTITIES DITA domainsp Domain//EN" "domainsp.ent" > %domainsp-d-dec;
- … and the other existing ones.
- Do the vocabulary substitution and define the elements from the which the domain specialized elements are extending from.
<!ENTITY % image "image | %domainsp-d-image;" > <!ENTITY % prolog "prolog | %domainsp-d-prolog;" > <!ENTITY % link "link | %domainsp-d-link;" >
- … and the other existing ones
- Do the vocabulary attribute declaration.
<!ENTITY included-domains "&ui-d-att; &hi-d-att; &pr-d-att; &sw-d-att; &ut-d-att; &indexing-d-att; &domainsp-d-att;" >
- Finally put the vocabulary definition and pull in the mod file for domain element integration. It will pull in all the specialized elements declared in the mod file.
<!ENTITY % ank-d-def PUBLIC ?"-//domainsp//ELEMENTS DITA User Interface Domain//EN" "domainsp.mod" > %domainsp-d-def;
- … and the other existing ones
Ankur Singla, FrameMaker Engineering