[xsl] Generating point-numbered footnotes in MS Word with XSL

Subject: [xsl] Generating point-numbered footnotes in MS Word with XSL
From: "Borsz, Andy" <andy.borsz@xxxxxxxxxxxxxxxxx>
Date: Wed, 7 Feb 2007 17:11:05 -0500
Hello!
I'm trying to write an XSL stylesheet (version 1.0) that will fix a
footnote numbering problem I'm experiencing in MS Word 2003. When you
save a regular Word file as XML you have the opportunity to apply a XSL
Transform on it as you save, although I'm not sure which processor Word
uses, I suspect its Sablotron of Libxslt.

I want to automatically generate point-numbered footnotes by inserting
the text 'POINTNUMBER START' and 'POINTNUMBER END' into the footnote
text in the Word file. You can insert point-numbered footnotes in Word
by using 'Custom Mark', but this would be very time consuming to do lots
of these. My aim is to generate normal footnotes and then convert them
to point-numbered ones. I can make a stylesheet that copies everything
properly and strips out the point-numbering instructions strings easy
enough, but getting those 1.1's and 1.2's and so on are proving to be a
larger challenge than I thought.

Here's some of the XML from my Word test file:

         <w:r>
               <w:t>note</w:t>
            </w:r>
            <w:r>
               <w:rPr>
                  <w:rStyle w:val="FootnoteReference"/>
               </w:rPr>
               <w:footnote>
                  <w:p>
                     <w:pPr>
                        <w:pStyle w:val="FootnoteText"/>
                     </w:pPr>
                     <w:r>
                        <w:rPr>
                           <w:rStyle w:val="FootnoteReference"/>
                        </w:rPr>
                        <w:footnoteRef/>
                     </w:r>
                     <w:r>
                        <w:t> footnote</w:t>
                     </w:r>
                  </w:p>
               </w:footnote>
            </w:r>
            <w:r>
               <w:t> note</w:t>
            </w:r>
            <w:r>
               <w:rPr>
                  <w:rStyle w:val="FootnoteReference"/>
               </w:rPr>
               <w:footnote>
                  <w:p>
                     <w:pPr>
                        <w:pStyle w:val="FootnoteText"/>
                     </w:pPr>
                     <w:r>
                        <w:rPr>
                           <w:rStyle w:val="FootnoteReference"/>
                        </w:rPr>
                        <w:footnoteRef/>
                     </w:r>
                     <w:r>
                        <w:t> POINTNUMBER START</w:t>
                     </w:r>
                  </w:p>
               </w:footnote>
            </w:r>
            <w:r>
               <w:t> note</w:t>
            </w:r>
            <w:r>
               <w:rPr>
                  <w:rStyle w:val="FootnoteReference"/>
               </w:rPr>
               <w:footnote>
                  <w:p>
                     <w:pPr>
                        <w:pStyle w:val="FootnoteText"/>
                     </w:pPr>
                     <w:r>
                        <w:rPr>
                           <w:rStyle w:val="FootnoteReference"/>
                        </w:rPr>
                        <w:footnoteRef/>
                     </w:r>
                     <w:r>
                        <w:t> footnote</w:t>
                     </w:r>
                  </w:p>
               </w:footnote>
            </w:r>
            <w:r>
               <w:t> note</w:t>
            </w:r>
            <w:r>
               <w:rPr>
                  <w:rStyle w:val="FootnoteReference"/>
               </w:rPr>
               <w:footnote>
                  <w:p>
                     <w:pPr>
                        <w:pStyle w:val="FootnoteText"/>
                     </w:pPr>
                     <w:r>
                        <w:rPr>
                           <w:rStyle w:val="FootnoteReference"/>
                        </w:rPr>
                        <w:footnoteRef/>
                     </w:r>
                     <w:r>
                        <w:t> POINTNUMBER END</w:t>
                     </w:r>
                  </w:p>
               </w:footnote>
            </w:r>
            <w:r>
               <w:t> note</w:t>
            </w:r>
            <w:r>
               <w:rPr>
                  <w:rStyle w:val="FootnoteReference"/>
               </w:rPr>
               <w:footnote>
                  <w:p>
                     <w:pPr>
                        <w:pStyle w:val="FootnoteText"/>
                     </w:pPr>
                     <w:r>
                        <w:rPr>
                           <w:rStyle w:val="FootnoteReference"/>
                        </w:rPr>
                        <w:footnoteRef/>
                     </w:r>
                     <w:r>
                        <w:t> footnote</w:t>
                     </w:r>
                  </w:p>
               </w:footnote>
		</w:r>

Here's the desired result:

<w:r>
               <w:t>note</w:t>
            </w:r>
            <w:r>
               <w:rPr>
                  <w:rStyle w:val="FootnoteReference"/>
               </w:rPr>
               <w:footnote>
                  <w:p>
                     <w:pPr>
                        <w:pStyle w:val="FootnoteText"/>
                     </w:pPr>
                     <w:r>
                        <w:rPr>
                           <w:rStyle w:val="FootnoteReference"/>
                        </w:rPr>
                        <w:footnoteRef/>
                     </w:r>
                     <w:r>
                        <w:t> footnote</w:t>
                     </w:r>
                  </w:p>
               </w:footnote>
            </w:r>
            <w:r>
               <w:t> note</w:t>
            </w:r>
            <w:r>
               <w:rPr>
                  <w:rStyle w:val="FootnoteReference"/>
               </w:rPr>
               <w:footnote w:suppressRef="on">
                  <w:p>
                     <w:pPr>
                        <w:pStyle w:val="FootnoteText"/>
                     </w:pPr>
                     <w:r>
                        <w:rPr>
                           <w:rStyle w:val="FootnoteReference"/>
                        </w:rPr>
                        <w:t>1.1</w:t>
                     </w:r>
                     <w:r>
                        <w:t> </w:t>
                     </w:r>
                  </w:p>
               </w:footnote>
               <w:t>1.1</w:t>
            </w:r>
            <w:r>
               <w:t> note</w:t>
            </w:r>
            <w:r>
               <w:rPr>
                  <w:rStyle w:val="FootnoteReference"/>
               </w:rPr>
               <w:footnote w:suppressRef="on">
                  <w:p>
                     <w:pPr>
                        <w:pStyle w:val="FootnoteText"/>
                     </w:pPr>
                     <w:r>
                        <w:rPr>
                           <w:rStyle w:val="FootnoteReference"/>
                        </w:rPr>
                        <w:t>1.2</w:t>
                     </w:r>
                     <w:r>
                        <w:t> footnote</w:t>
                     </w:r>
                  </w:p>
               </w:footnote>
               <w:t>1.2</w:t>
            </w:r>
            <w:r>
               <w:t> note</w:t>
            </w:r>
            <w:r>
               <w:rPr>
                  <w:rStyle w:val="FootnoteReference"/>
               </w:rPr>
               <w:footnote w:suppressRef="on">
                  <w:p>
                     <w:pPr>
                        <w:pStyle w:val="FootnoteText"/>
                     </w:pPr>
                     <w:r>
                        <w:rPr>
                           <w:rStyle w:val="FootnoteReference"/>
                        </w:rPr>
                        <w:t>1.3</w:t>
                     </w:r>
                     <w:r>
                        <w:t> </w:t>
                     </w:r>
                  </w:p>
               </w:footnote>
               <w:t>1.3</w:t>
            </w:r>
            <w:r>
               <w:t> note</w:t>
            </w:r>
            <w:r>
               <w:rPr>
                  <w:rStyle w:val="FootnoteReference"/>
               </w:rPr>
               <w:footnote>
                  <w:p>
                     <w:pPr>
                        <w:pStyle w:val="FootnoteText"/>
                     </w:pPr>
                     <w:r>
                        <w:rPr>
                           <w:rStyle w:val="FootnoteReference"/>
                        </w:rPr>
                        <w:footnoteRef/>
                     </w:r>
                     <w:r>
                        <w:t> footnote</w:t>
                     </w:r>
                  </w:p>
               </w:footnote>
            </w:r>

The template I'm trying to get the renumbering from (which does not
really work much at all) is this:

<xsl:template match="w:footnote">

<xsl:variable name="count">
<xsl:value-of select="count(preceding::w:footnote[ancestor::w:body])"/>
</xsl:variable>

<xsl:choose>

<xsl:when test="contains(., 'POINTNUMBER START') and
following::w:footnote[contains(., 'POINTNUMBER END')] ">
<w:footnote w:suppressRef="on">
   <w:p>
     <w:pPr>
        <w:pStyle w:val="FootnoteText"/>
     </w:pPr>
   <w:r>
     <w:rPr>
        <w:rStyle w:val="FootnoteReference"/>
     </w:rPr>
     <w:t>
	<xsl:value-of select="$count"/>
      <xsl:number count="w:footnote[preceding::w:t[contains(.,
'POINTNUMBER START')] and following::w:footnote[contains(., 'POINTNUMBER
END')]]" level="any" format=".1"/>
     </w:t>
   </w:r>
<xsl:copy><xsl:apply-templates select="node()|@*"/></xsl:copy>
</w:p>
</w:footnote>
</xsl:when>

<xsl:when test="preceding::w:t[contains(., 'POINTNUMBER START')] and
following::w:footnote[contains(., 'POINTNUMBER END')] ">
<w:footnote w:suppressRef="on">
                  <w:p>
                     <w:pPr>
                        <w:pStyle w:val="FootnoteText"/>
                     </w:pPr>
                     <w:r>
                        <w:rPr>
                           <w:rStyle w:val="FootnoteReference"/>
                        </w:rPr>
                        <w:t>
                        <xsl:value-of select="$count"/>
                        <xsl:number count="w:footnote" level="any"
format=".1"/>
                        </w:t>
                     </w:r>
<xsl:copy><xsl:apply-templates select="node()|@*"/></xsl:copy>
</w:p>
</w:footnote>
</xsl:when>

<xsl:otherwise>
<xsl:copy><xsl:apply-templates select="node()|@*"/></xsl:copy>
</xsl:otherwise>

</xsl:choose>

</xsl:template>

This is a basic example of converting to point number though, as there
can be multiple 'points' and a user could try to insert new
point-numbering into existing point-numbering. Any insight or advice
would be very much appreciated, or if there's a non-XSL way to make
point-numbering footnotes easier in MS Word.

Thanks for your time and enjoy your day!
-Andy

Current Thread