[xsl] Man Page Transform and Modes

Subject: [xsl] Man Page Transform and Modes
From: Michael B Allen <mba2000@xxxxxxxxxx>
Date: Wed, 5 Apr 2006 17:48:14 -0400
Hello,

I'm writing a transform that generates a man page (troff macros). The
input is:

--8<-- INPUT.XML --8<--

  <root>
  <section>
  <interface name="test" short="just a test">
  <include>test.h</include>
 
  This is some text.

  <pre>
  typedef struct {
      int i;
  } astruct;
  </pre>

  <meth name="foo">
      <pre>int test_foo(astruct as, int flags);</pre>
      <param name="as"/>
      <param name="flags"/>
  The <ident>test_foo</ident> function blah, blah, blah.
      <ret>
  The <ident>test_foo</ident> function returns blah, blah, blah.
      </ret>
  </meth>

  <meth name="bar">
      <pre>int test_bar(void);</pre>
  The <ident>test_bar</ident> function blah, blah, blah.
  </meth>
  
  </interface>
  </section>
  </root>

--8<-- END INPUT.XML --8<--

The output should be something like the following:

--8<-- TROFF OUTPUT --8<--

  .TH test 3m "2006-04-05" "libfoo-1.2.3" "My Library Functions"
        
  .SH NAME
  test \- just a test
        
  .SH SYNOPSIS
  .nf   
  .B #include <test.h>
  .sp
  .BI "int test_foo(astruct *" as ", int " flags ");
  .br
  .BI "int test_bar(" void ");
  .br  
  .fi  
       
  .SH DESCRIPTION
  This is some text.
  .RS  
  .nf  
  .ta 4n 19n 31n 
  
  typedef struct {
      int i;  
  } astruct;
  
  .ta
  .fi
  .RE
  .TP
  .B foo
  The
  .BR "test_foo" (3m)
  function blah, blah, blah.
  .TP
  .B bar
  The
  .BR "test_bar" (3m)
  function blah, blah, blah.
  
  .SH RETURNS 
  .TP
  .B foo
  The
  .B test_foo
  function returns blah, blah, blah.
  .TP  
  .B bar
  The  
  .B test_bar
  function returns blah, blah, blah.

--8<-- END TROFF OUTPUT --8<--

Currently I have a mode for each section like:

  <xsl:template match="interface">
      <xsl:text>.TH </xsl:text>
      <xsl:value-of select="@name"/>
      ...
      <xsl:apply-templates select="." mode="synopsis"/>
      <xsl:apply-templates select="." mode="description"/>
      <xsl:apply-templates select="." mode="returns"/>
  </xsl:template>

and generic templates for things like <pre> tags:

  <xsl:template match="pre">
      <xsl:text>
  .RS
  .nf
  .ta 4n 19n 31n
  </xsl:text>
      <xsl:value-of select="."/>
      <xsl:text>
  .ta
  .fi
  .RE
  </xsl:text>
  </xsl:template>

Also, troff is sensitive to space so that needs to be normalized:

  <xsl:template match="text()">
      <xsl:value-of select="normalize-space(.)"/>
  </xsl:template>

But now for my problem - using a mode for each section causes the generic
templates to NOT match anything. Is there a way to indicate that the
generic templates should match regardless of the mode or must I copy
the generic templates for each possible mode?

Or would you use a completely different approach? If so, what?

Thanks,
Mike

--8<-- RESULTING MAN PAGE --8<--

test(3m)             My Library Functions                test(3m)

NAME
       test - just a test

SYNOPSIS
       #include <test.h>

       int test_foo(astruct *as, int flags);
       int test_bar(void);

DESCRIPTION
       This is some text.

              typedef struct {
                  int i;
              } astruct;

       foo    The test_foo(3m) function blah, blah, blah.

       bar    The test_bar(3m) function blah, blah, blah.

RETURNS
       foo    The test_foo function returns blah, blah, blah.

       bar    The test_bar function returns blah, blah, blah.

libfoo-1.2.3             2006-04-05                      test(3m)

Current Thread