Category Archives: plugins

QA Plugin XSLT: Locating Distinct Values for Duplicate IDs

Posted on by dpclark
1

As part of a new framework enhancement, I needed a method to ensure that certain DITA elements carried unique @id values. Our authoring tool does a good job identifying duplicate @id values within a topic, but does not indicate whether those values also exist in other topics referenced in the DITA map.

In this case, the best fit was to add a new check to the QA plugin.

The check should:

• Identify duplicate @id values on specific elements
• Return only distinct values (i.e. if 123 appears several times, then return 123 only once)

After some forum research, my first thought was to use a key match.

<xsl:key name="duplicateIds" match="elementName" use="@id" />

And reference it with

key('duplicateIds',@id)[2] and count(.|key('duplicateIds', @id)[1]) = 1

So the if statement for the check looked like

<xsl:for-each select="//parentElement">
<xsl:if test="key('duplicateIds',@id)[2] and count(.|key('duplicateIds', @id)[1]) = 1">
Remove duplicate elementName @id=<xsl:value-of select="@id"/>
</xsl:if>
</xsl:for-each>

Even though it met my requirements, it’s still an outdated approach that didn’t leave me with a job-well-done sense of completion. I wanted a cleaner solution that fit somewhere closer to the 2.0 realm.

I decided to use grouping to identify each distinct @id value. Then I could wrap an if statement to test for any groups that contained a second (duplicate) item. The result:

<xsl:for-each-group select="//elementName" group-by="@id">
<xsl:if test="current-group()[2]">
Remove duplicate elementName @id=<xsl:value-of select="@id"/>
</xsl:if>
</xsl:for-each-group>

Have a better approach? Leave a comment.

Posted in plugins, tools | Tagged 2.0, QA, XSLT | 1 Reply

Flattening HTML output

Posted on by bcolborn
Reply

My DITA repository has a number of subdirectories to keep maps and topics organized. This strategy is convenient, but it can be a drawback when I need to further process HTML output, as I had to do for a recent publishing project. The HTML output type in the DITA Open Toolkit retains the organization of the source files, so that every processing task turned into file tree navigation with tools that aren’t suited for it.

The DITA For Publishers HTML2 plugin provides a mechanism for flattening the output: the html2.file.organization.strategy Ant parameter. To make flattening a viable approach, there needs to be a provision for avoiding collisions. For example, say you have two directories, indir1 and indir2, each of which contain a topic file topic1.dita. The single-directory output, then, can’t be outdir/topic1.html because there are two topic1 files.

The plugin deals with this requirement by appending a string, created by generate-id(), to the file name. So indir1/topic1.dita would become outdir/topic1_d97.html and indir2/topic1.dita would become outdir/topic1_d84.html. The exact expression (in the get-result-topic-base-name-single-dir template) is

concat(relpath:getNamePart($topicUri), '_', generate-id(.))

While that’s a reasonable approach, it’s not the one that I want to use because the filenames ultimately get exposed to my customers. Since I don’t know the algorithm for generating the unique ID, it’s not deterministic enough, and a bookmarked link might become invalidated without my knowing. Instead, I’d like to prepend the parent directory name, so I modified the expression to this:

concat(relpath:getNamePart(relpath:getParent($topicUri)), '_', relpath:getNamePart($topicUri))

The result for the two example files then would be outdir/indir1_topic1.html and outdir/indir2_topic1.html. This approach has the added advantage that the output doesn’t lose information about its location in the source.

Posted in plugins | Leave a reply

Fixing part/chapter numbering in PDF

Posted on by bcolborn
Reply

Apparently part and chapter numbering for bookmaps has been broken in the Open Toolkit PDF output since the beginning. Instead of numbering the chapters in a series from beginning to end, chapter numbering resets to 1 for every part so the TOC looks like this:

  • Part I
    • Chapter 1
    • Chapter 2
    • Chapter 3
  • Part II
    • Chapter 1
    • Chapter 2
    • Chapter 3
  • Part III
    • Chapter 1
    • Chapter 2
    • Chapter 3

The correct behavior would be a single chapter series that goes from 1 to 9. OT issue 1418 indicates that this was fixed in OT 1.7 but I didn’t see any change when I tried it out. Instead I changed my PDF plugin and thought I’d document the change here for anyone else who might need to do it in the future since I wasn’t able to find the answer anywhere.

There are two templates that need to be updated: one for the TOC and one for the chapter first page.

The template for the TOC is below.

<xsl:template match="*[contains(@class, ' bookmap/chapter ')] |
  *[contains(@class, ' boookmap/bookmap ')]/opentopic:map/*[contains(@class, ' map/topicref ')]" mode="tocPrefix" priority="-1">
  <xsl:call-template name="insertVariable">
    <xsl:with-param name="theVariableID" select="'Table of Contents Chapter'"/>
    <xsl:with-param name="theParameters">
        <number>
          <xsl:variable name="id" select="@id" />
          <xsl:variable name="topicChapters">
            <xsl:copy-of select="$map//*[contains(@class, ' bookmap/chapter ')]" />
          </xsl:variable>
          <xsl:variable name="chapterNumber">
            <xsl:number format="1"
              value="count($topicChapters/*[@id = $id]/preceding-sibling::*) + 1" />
          </xsl:variable>
          <xsl:value-of select="$chapterNumber" />
        </number>
    </xsl:with-param>
  </xsl:call-template>
</xsl:template>

The significant parts here are the $topicChapters and $chapterNumber variables.

The template for the chapter first page is insertChapterFirstpageStaticContent. It’s too long to reproduce in its entirety here, but the code is the same as what’s inside the number element in the TOC template. The number element that contains the $topicChapters and $chapterNumber variables needs to replace the one inside the xsl:when test="$type = 'chapter'" block.

Posted in plugins, tools | Leave a reply

Configuring Fonts for the Open Toolkit with Apache FOP

Posted on by bcolborn
3

While I can’t justify the cost for an expert stylesheet developer or a fancy PDF renderer, I don’t wan’t my PDFs to look like garbage either. Using Jarno Elivirta’s PDF plugin generator is a great place to start for PDF customization, and Apache FOP (bundled with the Open Toolkit) is my only option for a PDF renderer. Once I did a lot of the work in a PDF plugin, I got to the point where I wanted to change fonts. Although despite overuse there’s nothing too offensive about Times New Roman + Arial + Courier, that font set doesn’t conform to any branding guidelines that have been given any thought.

Should be pretty easy to do what I wanted, right?

Continue reading

Posted in plugins | 3 Replies

Installing and Customizing the QA Plugin

Posted on by paqman
10

spacer I’ve done a poor job of documenting the QA Plugin. This is my attempt to begin rectifying that mistake. In this article, you’ll find information on installing, running, and customizing the QA Plugin. Our next release will have significant changes; I’ll be sure to post new documentation here and on sourceforge.

Continue reading

Posted in plugins, tools | 10 Replies

QR Codes in DITA Ouput

Posted on by paqman
1

spacer Inspired by a thread started by Sean Healy, and building on the instructions posted by Kevin Brown, I added the ability to generate and insert QR Codes into PDF output to the mypdf plugin.

I ignore QR Codes in marketing, but I think they could be a great way to link to resources, such as videos, from printed technical documents. Readers can simply zap the codes with their phones to pull up the content.

Continue reading

Posted in authoring, plugins | 1 Reply

Example Constraints Plugin

Posted on by paqman
1

One of the most important features, in my opinion, of DITA 1.2 is the constraints mechanism. In short, constraints let you reduce the elements and attributes available to your authors. You can also specify when elements/attributes are required, and which tag structures are legal (and, therefore, which are illegal). Eliot Kimber wrote a great tutorial on how to set up constraints, but if you’d like an example plugin, you can download the one I’ve created off sourceforge.

Continue reading

Posted in authoring, plugins | 1 Reply

QA Plugin Report Breakdown

Posted on by the ditanauts team
11

spacer The QA Plugin is awesome. No, really! But that may be hard to believe until you’ve seen one of the reports (displays best in FireFox). After the “more” is a breakdown of the report, which now includes the word counts and an element count pie chart, in addition to the terminology and markup checks.

Continue reading

Posted in authoring, plugins | 11 Replies

Automagically Check Tagging, Terminology, and More

Posted on by the ditanauts team
Reply

If you have more than one writer on your team (and perhaps if you have exactly one), enforcing terminology, tagging, and other standards can be challenging. We wanted an easy way to catch simple issues, like lists nested inside paragraphs and the use of out-of-date console names. We also wanted to verify, across a large document set, that certain DITA attributes were used correctly in order to make our output as reliable as possible. We started with a PowerShell script written by Ben Colborn, which included a large number of xpath-based quality assurance checks. We’ve since ported those checks into an open toolkit plugin, and we are happy to say we can now share it here on sourceforge.

Continue reading

Posted in authoring, plugins | Leave a reply

Mobile DITA Content with jQuery

Posted on by paqman
16

spacer Hello ditaverse, I’ve started a new sourceforge project – creating a toolkit plugin to produce mobile- and tablet-friendly xHTML from DITA content. The plugin leverages the jQuery Mobile framework to create some pretty slick-looking pages. As it is currently set up, it takes a single map, with chunk set to-content, and produces a single HTML document with the appropriate jQuery Mobile markup to turn each topic into a mobile “page.”

Continue reading

Posted in plugins, tools | Tagged jquery, mobile | 16 Replies