WordML: generate PRE element from multiple paragraphs

In my Word-to-Blogger converter, I wanted to convert a block of paragraphs with the code style into a single PRE element. As Word does not generate a grouping of paragraphs of the same style, I had to develop a pretty convoluted solution:

  • A special template matches paragraphs with the code style.
  • The template performs the translation only if the preceding paragraph does not have the same style. This ensures the subsequent paragraphs with the code style don’t generate extra PRE elements.
  • The template generates the PRE element and sends the current element through another translation using pre mode.
<xsl:template match="w:p[w:pPr/w:pStyle/@w:val = 'code']">
<xsl:if test="not(preceding-sibling::w:p[1]/w:pPr/w:pStyle/@w:val = 'code')">
<pre class='{w:pPr/w:pStyle/@w:val}'>
<xsl:apply-templates select='.' mode="pre" />

The paragraph matching with mode=’pre’ is quite simple:

  • Child elements are processed (producing translated paragraph text).
  • If the following sibling has the code style (we haven’t reached the end of the PRE block), a newline element is appended with the xsl:text instruction and the sibling (the next code paragraph) is translated with mode=’pre’.
<xsl:template match="w:p[w:pPr/w:pStyle/@w:val = 'code']" mode="pre">
<xsl:apply-templates />
<xsl:if test="following-sibling::*[1]/w:pPr/w:pStyle/@w:val = 'code'">
<xsl:apply-templates mode="pre" select="following-sibling::*[1]" />

The default template for mode=’pre’ is empty, ensuring that non-paragraph entities accidentally translated with mode=’pre’ do not generate output text.

<xsl:template match="*" mode="pre" />

The solution could be made easier if I would have used the wx:pBdrGroup element that Word inserts around my code paragraphs (I’ve configured a border on the paragraph style), but the wx:pBdrGroup-based approach would fail if someone decided to change the border of the code style.

No comments:

Post a Comment