Create a custom transformation target

The IXIA CCMS Output Generator build files, also called the conductor files, contain the Apache Ant targets that direct the final output processing.

A conductor file is a standard Ant build file that contains one project and at least one target.

Targets are defined in your client conductor file, such as %OutputGenDir%/data/conductor-acme.xml in a <target> element.

Note: Conductor files are written in Ant, so this procedure assumes that you have some knowledge in programming Ant scripts. For basic information on Ant projects, targets, and tasks, see the Apache Ant Manual at the following URL: http://ant.apache.org/manual/using.html#projects. For information on the DITA Open Toolkit, see http://www.dita-ot.org/.

To run a transformation scenario, a target usually goes through the following process:

  1. Prepare the environment
  2. Prepare the content for the transformation
  3. Create the build.bat file and build.properties files
  4. Run build.bat
  5. Clean up the files
There are two essential directories when creating a transformation scenario:
  • Input directory retrieves the files from the Content Store and stores them in this directory, defined with the outgen.job.source.dir Ant property.

    Note: If you need to modify the files before transforming them, you need to modify them in the input directory.
    Note: If you are working with a branched map or a map that includes content from different cycles, such as authoring, published, and localization, you must call the flatten target before modifying the source files. The flatten target will copy all the files to the input directory so that you can modify them as required.
  • Output directory

    • For CCMS Desktop, it returns any file stored in this directory at the end of the transformation job in a zip file
    • For CCMS Web, it returns any file stored in this directory at the end of the transformation job to the app server
    Note: This directory is defined with the outgen.job.output.dir property. Regularly clear your directory and keep all the files you must return to the user.
The example dita2pdf.custom.wrapper target transforms DITA files into PDF format.
<target name="dita2pdf.custom.wrapper" depends="default_dependencies, flatten, resolve_container_keyref, extract_LowRes_images">
	<echostart>dita2pdf.custom.wrapper</echostart>

	<ot_build_add_pdfrenderer/>
        <ot_build_add_ditaval_ifpresent/>
	<ot_build_clean_ot_temp/>
        <ot_build_keep_topicfo/>

	<ot_build_set_parameter name="transtype" value="pdf2"/>
<!-- <ot_build_set_parameter name="args.rellinks" value="none"/> -->
<!-- <ot_build_set_parameter name="args.draft" value="no"/> -->
 
        <ot_build_set_parameter name="args.draft" value="${outgen.job.userparam.dita2.pdfcustom.args.draft}"/>
         <ot_build_set_parameter name="args.chapter.layout" value="${outgen.job.userparam.dita2pdf.custom.args.chapter.layout}"/>
          <ot_build_set_parameter name="args.rellinks" value="${outgen.job.userparam.dita2.pdfcustom.args.rellinks}"/>

	<dita_startcmd_ot_build/>

	<clean_ot_output/>

<!-- Set the property job.keep.temp to preserve the completed temp folder of the task -->
<!--<property name="job.keep.temp" value="yes"/>-->

	<echoend>dita2pdf.custom.wrapper</echoend>
</target>

Since conductor files are like programming files, each target is different and does not follow a specific structure, unlike output type or processor files. You can create a target that transforms DITA files to PDF using the DITA Open Toolkit, but you can create many different types of targets.

To create a custom transformation target:

  1. Open your client conductor file, such as %OutputGenDir%/data/conductor-acme.xml.
    Note: One <project> element, which is known as a conductor, provides the project name, default target, and base directory. The <project> attributes are as follows for a conductor file:
    • name: Specify the file name without the extension
    • default: Keep the value specified in the template
    • basedir: Keep the value specified in the template
    Note: You can also create a new client conductor file. Conductor files must be stored directly in the %OutputGenDir%/data directory.
  2. Locate a target element you want to add to a conductor file.

    Targets include one or more Ant tasks, which are small pieces of code that can run. They can be Ant built-in tasks, IXIA CCMS tasks, or your own custom tasks. For example, the export target above uses the <copydir> Ant built-in task.

    Note: A target can run other targets. It can also depend on other targets to run.
  3. Create a target element and specify the name of the target.
    For the sample Acme company, add the "Custom" as part of the default target file name:acme.dita2xHtmlwrapper. When you add your company name before the target file name, it helps you differentiate between default targets and customized targets.
    <target name="dita2pdf.custom.wrapper"
  4. Add the required dependencies.
    The depends attribute defines the four custom targets on which this target depends.
    <target name="dita2pdf.custom.wrapper" depends="default_dependencies, flatten, resolve_container_keyref, extract_LowRes_images">
    • default_dependencies prepares the environment by running a set of targets that perform the following functions:

      • Set up properties specific to the job, such as the transformation scenario initiation

      • Configure default values for some properties

      • Load the user parameters into Ant properties for use in Ant scripts

      Note: The default_dependencies must be present for all transformation targets.
    • flatten prepares the content for the transformation by flattening the directory structure. This is required for branched maps, which contain objects in the Authoring cycle and objects in the Published cycle. The flatten target combines these objects in a single directory so that the DITA-OT can access the source files to transform.
      Note: The flatten target has no impact on non-branched content, so you can specify it even if you do not have branched content at this point. This ensures that you don't have to add this target later on should you branch your content.
    • resolve_container_keyref examines all the keys defined in the source and resolves those key references
    • extract_LowRes_images prepares the content for the transformation by extracting the images in LowRes format, if available, instead of the default format.
      Note: The extract_LowRes_images target ensures that the DITA Open Toolkit can read the image files.
    Note: Upon initiation of a target, it first calls the targets specified with the depends property in the order they appear, which moves from left to right.

    You can also use properties in your targets. Again, these can be Ant built-in properties, CCMS properties, or your own properties, which you access at ${property}.

    You can run a target if an earlier target depends on it if it specifies the depends property. For more information, see the Apache documentation at https://ant.apache.org/manual/targets.html.

  5. Add the ditaval file.
    This macro sets the DITA-OT args.filter parameter to the value of the ditaval path and filename in the build.properties file whenever a user specifies the given ditaval file.
    <ot_build_add_ditaval_ifpresent/>
    Important: A target can run other targets. It can also depend on other targets to run it.
  6. Clean out the job's temp folder after the output is complete.

    This macro sets the DITA-OT clean.temp parameter in the build.properties file to the value of the outgen.job.clean.ot.temp property.

    <ot_build_clean_ot_temp/>
  7. Set the transformation type.
    This transtype must correspond to the transtype defined for a plug-in in the DITA-OT used for the output.
    <ot_build_set_parameter name="transtype" value="xhtml"/>
  8. Configure properties that are specific to this job.
    <dita_startcmd_ot_build/>

    Since multiple jobs can be running at the same time, you must set some properties per transformation target so that they do not conflict between jobs. The dita_startcmd_ot_build macro sets the following properties:

    • outgen.job.ot.dita.command sets the location of the dita command within the DITA-OT
    • outgen.job.ot.command.logfile sets the name of the log file
    • outgen.job.ot.command.propertyfile specifies that the property file to be used is named build.properties and is located in the outgen.job.dir
    • outgen.job.ot.command.input specifies the input, usually the selected ditamap
    • outgen.job.ot.command.output.dir specifies the output location
    • outgen.job.ot.command.format specifies the transtype
    • outgen.job.ot.command.dita.dir specifies the DITA-OT to be used
    • outgen.job.ot.command.dita.temp.dir specifies the temp directory for the job
    • outgen.job.ot.properties
  9. Record the build properties in the build.properties file.
    Users specify the properties in the target in the Generate Output dialog using the dita_startcmd_ot_build macro.
    <echoproperties destfile="${outgen.job.ot.command.propertyfile}">
    	<propertyset>
    		<propertyref prefix="outgen.job.ot.properties."/>
    		<mapper type="glob" from="outgen.job.ot.properties.*" to="*"/>
    	</propertyset>
    </echoproperties>

    For the list of all DITA Open Toolkit Ant parameters, see the DITA Open Toolkit documentation at %OutputGenDir%/data/dita-ot-2.5.4/doc/parameters/index.html.

  10. Create the build.bat file:
    The dita_startcmd_ot_build macro also constructs the build.bat file from some of the listed properties.
    <property name="outgen.job.ot.batchfile.content" ¶
    value="&quot;${outgen.job.ot.dita.command}&quot; ¶ 
    -i &quot;${outgen.job.ot.command.input}&quot; ¶ 
    -f ${outgen.job.ot.command.format} ¶ 
    -o &quot;${outgen.job.ot.command.output.dir}&quot; ¶ 
    -propertyfile &quot;${outgen.job.ot.command.propertyfile}&quot; -v"/>
    Note: The ¶ symbol indicates a line break inserted in the code sample for clarity and readability. In an actual build.bat file, there are no line breaks.
  11. Run build.bat or build.sh, depending on whether you have Windows or Linux, respectively.
    Depending on the detected operating system, the dita_startcmd_ot_build macro launches one of two other macros.
    <switch value="${outgen.os.family}">
    	<case value="windows">
    		<dita_startcmd_ot_build_windows/>
    	</case>
    	<case value="unix">
    		<dita_startcmd_ot_build_linux/>
    	</case>
    	<default>
    		<fail message="No DITA command for the OS family ${outgen.os.family}"/>
    	</default>
    </switch>

    The dita_startcmd_ot_build_windows macro.

    <macrodef name="dita_startcmd_ot_build_windows">
    	<sequential>
    		<echostart>dita_startcmd_ot_build_windows</echostart>
    
    		<property name="outgen.job.ot.batchfile" location="${outgen.job.dir}/build.bat"/>
    
    		<!-- Do not indent the lines inside the "echo" element -->
    		<echo file="${outgen.job.ot.batchfile}">@echo off
    ${outgen.job.ot.batchfile.content}</echo>
    
    		<exec executable="cmd.exe" output="${outgen.job.ot.command.logfile}" ¶
    		      append="true" dir="${outgen.job.dir}" failonerror="false" ¶
    			  resultproperty="outgen.job.ot.return.code">
    			<arg value="/c"/>
    			<arg value="${outgen.job.ot.batchfile}"/>
    			<arg value="2&gt;&amp;1"/>
    		</exec>
    
    		<echoend>dita_startcmd_ot_build_windows</echoend>
    	</sequential>
    </macrodef>

    The dita_startcmd_ot_build_linux macro.

    <macrodef name="dita_startcmd_ot_build_linux">
    	<sequential>
    		<echostart>dita_startcmd_ot_build_linux</echostart>
    
    		<property name="outgen.job.ot.batchfile" location="${outgen.job.dir}/build.sh"/>
    
    		<!-- Do not indent the lines inside the "echo" element -->
    		<echo file="${outgen.job.ot.batchfile}">#!/bin/bash
    export JAVA_HOME=${outgen.job.ant.java.home}
    ${outgen.job.ot.batchfile.content}</echo>
    
    		<chmod file="${outgen.job.ot.dita.command}" perm="755"/>
    		<chmod file="${outgen.job.ot.batchfile}" perm="755"/>
    		<exec executable="${outgen.job.ot.batchfile}" output="${outgen.job.ot.command.logfile}" ¶
    		      append="true" dir="${outgen.job.dir}" failonerror="false" ¶
    			  resultproperty="outgen.job.ot.return.code">
    			<arg value="2&gt;&amp;1"/>
    		</exec>
    
    		<echoend>dita_startcmd_ot_build_linux</echoend>
    	</sequential>
    </macrodef>
  12. Clean up the DITA-OT outputdir folder.
    <clean_ot_output/>
    CCMS Output Generator returns to the original dita2pdf.custom.wrapper target after the DITA-OT transformation is complete. CCMS Output Generator then cleans up the files by calling the clean_ot_output macro. This removes all unnecessary files left over by the DITA Open Toolkit in the output directory before it zips the output. For CCMS Desktop, it returns the zip file to the end user. For CCMS Web, it saves the zip file to the app server.