user877329
user877329

Reputation: 6200

Turn doxygen xml into valid and semantic rich HTML

Consider this code generated by Doxygen:

<detaileddescription>
  <para>This function fills buffer with the content of $param_inline(template_string) by applying to the following rules:</para>
  <para>
    <itemizedlist>
      <listitem>
        <para>Any number less than the number of elements in $param_inline(strings) following a % in reffers to an index in $param_inline(strings).</para>
      </listitem>
      <listitem>
        <para>Any symbol following a % that is not a valid decimal digit will be prited as it is.</para>
      </listitem>
      <listitem>
        <para>If the resulting string including NULCHAR is longer than $param_inline(buffer_length), the string is truncated.</para>
      </listitem>
      <listitem>
        <para>If a number following a % cannot be converted, or the number is larger than or equal to the number of elements in $param_inline(strings), the function returns.</para>
      </listitem>
      <listitem>
        <para>In any case, buffer is terminated with a NULCHAR.</para>
      </listitem>
    </itemizedlist>
  </para>
  <para>
    <simplesect kind="return">
      <para>Non-zero if the function succeeded, zero otherwise.</para>
    </simplesect>
  </para>
</detaileddescription>

Using xslt, I want to turn this into clean HTML like this

<p>This function ...</p>
<ul>
     <li><p>Any number ...</p></li>
     <li><p>Any symbol ...</p></li>
     ...
</ul>
<p class="return">Non-zero if ...</p>

The problem is that Doxygen likes to enclose lists inside paragraphs or sections inside paragraphs.

I currently have this to match para:

<xsl:template match="para">
<p>
<xsl:apply-templates select="./*[not(self::simplesect|self::parameterlist |self::itemizedlist|self::orderedlist)] | text()"/>
</p>
<xsl:for-each select="./*">
     <xsl:apply-templates select="." />
</xsl:for-each>
</xsl:template>

It sort of works, but it generates empty p tags.

Upvotes: 1

Views: 459

Answers (2)

Rudramuni TP
Rudramuni TP

Reputation: 1278

Try this:

InPut XML:

<detaileddescription>
  <para>This function fills buffer with the content of $param_inline(template_string) by applying to the following rules:</para>
  <para>The list
    <itemizedlist>
      <listitem>
        <para>Any number less than the number of elements in $param_inline(strings) following a % in reffers to an index in $param_inline(strings).</para>
      </listitem>
      <listitem>
        <para>Any symbol following a % that is not a valid decimal digit will be prited as it is.</para>
      </listitem>
      <listitem>
        <para>If the resulting string including NULCHAR is longer than $param_inline(buffer_length), the string is truncated.</para>
      </listitem>
      <listitem>
        <para>If a number following a % cannot be converted, or the number is larger than or equal to the number of elements in $param_inline(strings), the function returns.</para>
      </listitem>
      <listitem>
        <para>In any case, buffer is terminated with a NULCHAR.</para>
      </listitem>
    </itemizedlist>
  </para>
  <para><i>Italic text</i></para>
  <para><i>Italic text</i> normal text</para>
  <para><b>Bold text</b></para>
  <para><b>Bold text</b> normal text</para>
  <para>
    <simplesect kind="return">
      <para>Non-zero if the function succeeded, zero otherwise.</para>
    </simplesect>
  </para>
</detaileddescription>

XSLT:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="para">
        <xsl:choose>
            <xsl:when test="child::*[not(name()='equation') and not(name()='itemizedlist')  and not(name()='simplesect')]"><!--Define child elements of inline elements of para-->
                <p><xsl:apply-templates/></p>
            </xsl:when>
            <xsl:when test="child::*[name()='i']">
                <p><xsl:apply-templates/></p>
            </xsl:when>
            <xsl:otherwise><xsl:apply-templates/></xsl:otherwise>
        </xsl:choose>
    </xsl:template>

    <xsl:template match="itemizedlist">
        <ul><xsl:apply-templates/></ul>
    </xsl:template>

    <xsl:template match="listitem">
        <li><xsl:apply-templates/></li>
    </xsl:template>

    <xsl:template match="equation">
        <p><xsl:apply-templates/></p>
    </xsl:template>

    <xsl:template match="i">
        <i><xsl:apply-templates/></i>
    </xsl:template>

    <xsl:template match="b">
        <b><xsl:apply-templates/></b>
    </xsl:template>

    <xsl:template match="para/text()[not(preceding-sibling::i) and not(following-sibling::i) and not(preceding-sibling::b) and not(following-sibling::b)]">
        <p><xsl:value-of select="."/></p>
    </xsl:template>

    <xsl:template match="simplesect/para">
        <xsl:apply-templates/>
    </xsl:template>

</xsl:stylesheet>

OutPut:

<p>This function fills buffer with the content of $param_inline(template_string) by applying to the following rules:</p>
<p>The list
    </p>
<ul>
   <li>
      <p>Any number less than the number of elements in $param_inline(strings) following a % in reffers to an index in $param_inline(strings).</p>
   </li>
   <li>
      <p>Any symbol following a % that is not a valid decimal digit will be prited as it is.</p>
   </li>
   <li>
      <p>If the resulting string including NULCHAR is longer than $param_inline(buffer_length), the string is truncated.</p>
   </li>
   <li>
      <p>If a number following a % cannot be converted, or the number is larger than or equal to the number of elements in $param_inline(strings), the function returns.</p>
   </li>
   <li>
      <p>In any case, buffer is terminated with a NULCHAR.</p>
   </li>
</ul>
<p>
   <i>Italic text</i>
</p>
<p>
   <i>Italic text</i> normal text</p>
<p>
   <b>Bold text</b>
</p>
<p>
   <b>Bold text</b> normal text</p>
<p>Non-zero if the function succeeded, zero otherwise.</p>

Upvotes: 1

michael.hor257k
michael.hor257k

Reputation: 116992

Would something like this work for you?

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"/>

<xsl:template match="/*">
    <html>
        <body>
            <xsl:apply-templates/>
        </body>
    </html>
</xsl:template>

<!-- rename -->
<xsl:template match="itemizedlist">
    <ul>
        <xsl:apply-templates/>
    </ul>
</xsl:template>

<!-- rename -->
<xsl:template match="listitem">
    <li>
        <xsl:apply-templates select="para/node()"/>
    </li>
</xsl:template>

<!-- default: keep as is -->
<xsl:template match="*">
    <xsl:copy>
        <xsl:apply-templates/>
    </xsl:copy>
</xsl:template>

<!-- exceptions: suppress -->
<xsl:template match="para[itemizedlist or descendant::para] | simplesect">
    <xsl:apply-templates/>
</xsl:template>

</xsl:stylesheet>

When applied to your input example, the result is:

<html>
   <body>
      <para>This function fills buffer with the content of $param_inline(template_string) by applying to the following rules:</para>
      <ul>
         <li>Any number less than the number of elements in $param_inline(strings) following a % in reffers to an index in $param_inline(strings).</li>
         <li>Any symbol following a % that is not a valid decimal digit will be prited as it is.</li>
         <li>If the resulting string including NULCHAR is longer than $param_inline(buffer_length), the string is truncated.</li>
         <li>If a number following a % cannot be converted, or the number is larger than or equal to the number of elements in $param_inline(strings),
            the function returns.
         </li>
         <li>In any case, buffer is terminated with a NULCHAR.</li>
      </ul>
      <para>Non-zero if the function succeeded, zero otherwise.</para>
   </body>
</html>

Upvotes: 1

Related Questions