Using C# XML comments to document

G

Guest

C# XML comments are great, and I way prefer in-code documentation to
out-of-code documentation, but what're some of the ways to generate
out-of-code docs?

I used to use NDoc, but support isn't great for C# 2.0

I remember an HTML document generator in VS 2003, but I can't seem to find
it in 2005.

Any suggestions appreciated.

-Andrew
 
K

Kevin Spencer

I use XSL.

--
HTH,

Kevin Spencer
Microsoft MVP
..Net Developer
We got a sick zebra a hat,
you ultimate tuna.
 
G

Guest

Nice.

So...... do you have your own transform.... wanna share it? What' the
output? HTML?

Any one else have an "easy to use" tool?

Thanks,

Andrew
 
K

Kevin Spencer

Hi Andrew,
So...... do you have your own transform.... wanna share it? What' the
output? HTML?

I do have my own transform. However, it uses some external string-handling
methods which I put into a class library. I am hoping that at some point I
might be able to sell the a package with the class libary and several
others, and the XSLT would accompany it. Still, I can give you the XSL
without the string-handling code (externally referenced), and you could
possibly write your own string-handling functions to go with it. Not exactly
"easy to use" without them, but it could be educational! ;-)

My transform does create an HTML document. I wanted to do a "frameless
frameset," which uses CSS and JavaScript to emulate a frameset in a single
document. Frames have always been a problem with ASP and ASP.Net, but have
some very nice features. It seemed like a good exercise, a solution I have
never seen anywhere else. It has a TOC "frame" on the left, and a Content
"frame" on the right. The "frames" are resizable, just like in a true
Frameset. And it looks and behaves exactly the same in both IE and Mozilla
(tested with FireFox). You can see some examples of the output from it at:

http://www.dynamicsystems.com/weatherservices/documentation/

Note that the page referenced is only a home page with links to the actual
generated HTML pages.

The string-handling methods used are *documented* at

http://www.dynamicsystems.com/weatherservices/documentation/DsiGlobal.htm

It is a class called DsiGlobal.Xml.Xslt.Documentation

.... but of course, the code must remain a secret!

The HTML pages were created using this transform, which I've reproduced
below.

--
HTH,

Kevin Spencer
Microsoft MVP
..Net Developer
We got a sick zebra a hat,
you ultimate tuna.

<!----------------------------------------------------vv--XSLT---vv--------------------------------------------------->

<!--
<?xml-stylesheet href="doc.xsl" type="text/xsl"?>
-->
<!DOCTYPE xsl:stylesheet [
<!ENTITY less-than "<xsl:text
disable-output-escaping='yes'>&lt;</xsl:text>">
<!ENTITY greater-than "<xsl:text
disable-output-escaping='yes'>&gt;</xsl:text>">
<!ENTITY line-break "<xsl:text
disable-output-escaping='yes'>&lt;br/&gt;</xsl:text>">
<!ENTITY space-marker "<xsl:text
disable-output-escaping='yes'>&amp;nbsp;</xsl:text>">
<!ENTITY break "<xsl:text
disable-output-escaping='yes'>
</xsl:text>">
]>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ms="urn:schemas-microsoft-com:xslt"
xmlns:ex="urn:doc-scripts"
xmlns:js="urn:javascript"
exclude-result-prefixes="ms ex">
<xsl:blush:utput method="html" omit-xml-declaration="yes" indent="yes"
media-type="text/html"/>

<!-- String functions
*********************************************************** -->
<ms:script language="CSharp" implements-prefix="ex">
<ms:assembly href="bin/Debug/DSIGlobal.dll"/>
<ms:using namespace="DsiGlobal.Xml.Xslt"/>
<![CDATA[

Documentation doc = new Documentation();

// returns a class name based on the type of member (first character)
public string className(string fullName)
{
return doc.ClassName(fullName);
}

// returns the sort order based on member type
public int sortOrder(string fullName)
{
return doc.SortOrder(fullName);
}

public bool IsGeneric(string val)
{
return doc.IsGeneric(val);
}

// returns an Html-Encoded string, with line breaks replaced by "brxx" and
// spaces replaced by "spxx"
public string encodeAsHtml(string s)
{
return doc.EncodeAsHtml(s);
}

// returns a substring of "s" ending at the first "brxx" or "spxx" sequence
public string subStringChoose(string s)
{
return doc.SubStringChoose(s);
}

// returns the fully-qualified typeparam name value from either
// the node, or the class node to which the typeparamref in the node refers
public string GetTypeParam(XPathNavigator node, string refName)
{
return doc.GetTypeParam(node, refName);
}

// replaces all Generic references in a fully-qualified member name
public string GetGenerics(XPathNavigator node, string val)
{
return doc.GetGenerics(node, val);
}

// Identifies the string as that of a Constructor
public bool IsConstructor(string val)
{
return doc.IsConstructor(val);
}

// returns the namespace path of the member, without the name or parameters
// Includes className if IncludeClassName is true; otherwise namespace only
public string nameSpace(XPathNavigator node, bool IncludeClassName)
{
return doc.NameSpace(node, IncludeClassName);
}

// returns the parameters of a member, if any, including parentheses
// NOTE: Does *not* parse out the Generics from the value
public string buildParams(string parms, bool isMethod)
{
return doc.BuildParams(parms, isMethod);
}

// Strips parameters from a string
public string stripParameters(string val)
{
return doc.StripParameters(val);
}

// Strips the Type ID from the name attribute of an XML Comment
public string stripTypeId(string val)
{
return doc.StripTypeId(val);
}

// Strips constructor reference from a string
public string stripCtor(string val)
{
return doc.StripCtor(val);
}

// returns the fully-qualified name of the member, without parameters
public string fullName(XPathNavigator node)
{
return doc.FullName(node);
}

// returns the fully-qualified name of the member, including parameters
public string qualifiedName(XPathNavigator node)
{
return doc.QualifiedName(node);
}

// Overloaded. Returns the unqualified name of the member, without
parameters
public string baseName(XPathNavigator node)
{
return doc.BaseName(node);
}

// Overloaded. Returns the unqualified name of the member, without
parameters
public string baseName(XPathNavigator node, bool generics)
{
return doc.BaseName(node, generics);
}

// returns the non-qualified name of the member, indcluding parameters
public string memberName(XPathNavigator node)
{
return doc.MemberName(node);
}

// Returns the expanded member definition, including access modifiers,
// other modifiers, type or return type of member, inheritance
// references, and interface imeplementation references.
public string expandedName(XPathNavigator node)
{
return doc.ExpandedName(node);
}

// Replaces curly brackets with HTML-Encoding for angle
// brackets in a string
public string replaceCurlies(string s)
{
return doc.ReplaceCurlies(s);
}
]]>
</ms:script>

<!-- Keys
*********************************************************************** -->
<!-- NameSpace Key. Used to group members by NameSpace -->
<xsl:key name="keySpace" match="/doc/members/member" use="ex:nameSpace(.,
0)"/>

<!-- Class Key. Used to identify members that are classes in a Given
NameSpace -->
<xsl:key name="keyClass"
match="/doc/members/member[ex:className(string(@name)) = 'class']"
use="concat(ex:nameSpace(., 0), ex:baseName(.))"/>

<!-- Class Key. Used to identify members within a class by their name
attribute -->
<xsl:key name="keyName" match="/doc/members/member/param"
use="concat(string(ancestor::member/@name), string(@name))"/>

<!-- Type Parameter reference key. Used to identify a Generic Type parameter
matching a given name of a typeparamref tag
******************************** -->
<xsl:key name="keyTypeName" match="/doc/members/member/typeparam"
use="ex:GetTypeParam(ancestor::member, string(@name))"/>

<!-- Class Member Key. Used to identify members in a class by their class
and name attribute
********************************************************* -->
<xsl:key name="keyClassMember" match="/doc/members/member"
use="ex:nameSpace(., 1)"/>

<xsl:variable name="assy" select="string(//assembly/name)"/>
<!-- Master Template
************************************************************ -->
<xsl:template match="/">
<HTML>
<HEAD>
<TITLE>
Assembly: <xsl:value-of select="$assy"/>
</TITLE>
<meta http-equiv="pragma" content="no-cache"/>
<LINK rel="stylesheet" type="text/css" href="doc.css"/>
<script type="text/javascript" src="frameless_head.js"></script>
<script type="text/javascript" src="documentation.js"></script>
</HEAD>
<BODY>
<table id="waiting" class="waiting"><tr><td><img class="waiticon"
src="hourglass_icon.gif"/></td></tr></table>
<div id="outerDiv" class="outer-window">
<div id="windowDiv" class="window">
<div id="panelExplorer" class="panel-explorer"
onmousedown="canSelectToc=true" onscroll="scrollToc()">
<div id="toc" class="toc">
<h1>Table of Contents</h1>
<xsl:for-each select="/doc/members/member[generate-id() =
generate-id(key('keySpace',ex:nameSpace(., 0))[1])]">
<xsl:sort select="ex:nameSpace(., 0)"/>
<xsl:variable name="space" select="ex:nameSpace(., 0)"/>
<xsl:variable name="namespaceId" select="generate-id()"/>
<!-- NameSpace. Name of class to which the Member belongs
********************** -->
<xsl:element name="div">
<xsl:attribute name="class">toc-ns</xsl:attribute>
<xsl:attribute name="id"><xsl:value-of select="concat('_',
$namespaceId)"/></xsl:attribute>
<xsl:call-template name="linkImage"/>
<xsl:call-template name="clickAnchor">
<xsl:with-param name="target" select="$namespaceId"/>
<xsl:with-param name="innerText" select="$space"/>
</xsl:call-template>
<xsl:text disable-output-escaping="yes">&lt;/nobr&gt;</xsl:text>
<!-- Class links, with member links beneath them
*********************************-->
<xsl:for-each select="/doc/members/member[ex:nameSpace(., 0) =
$space]">
<xsl:sort select="ex:nameSpace(., 1)"/>
<xsl:sort select="ex:sortOrder(string(@name))"/>
<xsl:sort data-type="number" select="summary/@value"/>
<xsl:sort select="ex:baseName(.)"/>
<!-- Class Name. Name of class to which the Member belongs
********************** -->
<xsl:variable name="Class" select="ex:className(string(@name))"/>
<xsl:if test="position() > 1 and $Class = 'class'">
<xsl:text
disable-output-escaping="yes">&lt;/div&gt;</xsl:text>&break;
<xsl:text
disable-output-escaping="yes">&lt;/div&gt;</xsl:text>&break;
</xsl:if>
<xsl:if test="position() = 1">
&break;<xsl:text disable-output-escaping="yes">&lt;div
class="toc-class"</xsl:text> id="<xsl:value-of
select="concat('_', generate-id(@name))"/>"<xsl:text
disable-output-escaping="yes">&gt;</xsl:text>&break;
<xsl:call-template name="linkImage"/>
</xsl:if>
<xsl:choose>
<xsl:when test="$Class = 'class'">
<xsl:if test="position() > 1">
&break;<xsl:text disable-output-escaping="yes">&lt;div
class="toc-class"</xsl:text> id="<xsl:value-of
select="concat('_', generate-id(@name))"/>"<xsl:text
disable-output-escaping="yes">&gt;</xsl:text>&break;
<xsl:call-template name="linkImage"/>
</xsl:if>
<xsl:call-template name="clickAnchor">
<xsl:with-param name="target" select="generate-id(@name)"/>
<xsl:with-param name="innerText" select="ex:baseName(.)"/>
</xsl:call-template>
<xsl:text disable-output-escaping="yes">&lt;/nobr&gt;</xsl:text>
&break;<xsl:text disable-output-escaping="yes">&lt;div
class="toc-members"&gt;</xsl:text>
</xsl:when>
<xsl:blush:therwise>
&break;<div><xsl:call-template name="clickAnchor">
<xsl:with-param name="target" select="generate-id(@name)"/>
<xsl:with-param name="innerText" select="ex:baseName(.)"/>
</xsl:call-template></div>
</xsl:blush:therwise>
</xsl:choose>
</xsl:for-each>
<xsl:text
disable-output-escaping="yes">&lt;/div&gt;</xsl:text>&break;
<xsl:text
disable-output-escaping="yes">&lt;/div&gt;</xsl:text>&break;
</xsl:element><!-- /Div toc-ns-->
</xsl:for-each>
</div><!-- /toc -->
</div><!-- /panelExplorer -->
<div id="panelSizer" class="panel-sizer"
onmousedown="dragStart(event)"></div>
<div id="panelContent" class="panel-content"
onmouseover="enableScroll()"
onmousedown="canSelectContent=true" onscroll="scrollContent()">
<!-- Loop through all Members in this namespace
********************************* -->
<xsl:for-each select="/doc/members/member[generate-id() =
generate-id(key('keySpace',ex:nameSpace(., 0))[1])]">
<xsl:sort select="ex:nameSpace(., 0)"/>
<xsl:sort select="ex:nameSpace(., 1)"/>

<!-- Name of class to which the Member belongs
********************************** -->
<xsl:variable name="space" select="ex:nameSpace(., 0)"/>
<xsl:element name="a">
<xsl:attribute name="name"><xsl:value-of
select="generate-id()"/></xsl:attribute>
<xsl:attribute name="id"><xsl:value-of
select="generate-id()"/></xsl:attribute>
</xsl:element>
<div class="namespace">
NameSpace: <xsl:value-of select="$space"/>
</div>
 <xsl:text disable-output-escaping="yes">&lt;div
class="wrap"&gt;</xsl:text> 
<xsl:call-template name="member" >
<xsl:with-param name="space" select="$space"/>
</xsl:call-template>
&break;<xsl:text
disable-output-escaping="yes">&lt;/div&gt;</xsl:text>&break;
</xsl:for-each>
</div>&break;<!-- /panelContent -->
</div>&break;<!-- /windowDiv -->
</div>&break;<!-- /outerDiv -->
<script type="text/javascript" src="frameless_foot.js"></script>&break;
</BODY>
</HTML>
</xsl:template>

<!-- linkImage - A hyperlinked TOC Image
***************************************** -->
<xsl:template name="linkImage">
<xsl:text disable-output-escaping="yes">&lt;nobr&gt;</xsl:text><img
src="/documentation/expand.gif" alt="Show Contents" width="9" height="9"
onclick="toggleToc(this)"/>&break;
</xsl:template>

<!-- clickAnchor - An anchor with an onclick handler
***************************** -->
<xsl:template name="clickAnchor">
<xsl:param name="target"/>
<xsl:param name="innerText"/>
<xsl:element name="a">
<xsl:attribute name="onmousedown">tocScrollLeft =
tocDiv.scrollLeft</xsl:attribute>
<xsl:attribute name="onclick">return aclick(this, 1)</xsl:attribute>
<xsl:attribute name="href">#<xsl:value-of
select="$target"/></xsl:attribute><xsl:value-of
disable-output-escaping="yes" select="$innerText"/></xsl:element>
</xsl:template>

<!-- Member Template - Processes members by NameSpace, ordered by
NameSpace, Class Name, Member Type, and Member Name
************************ -->
<xsl:template name="member">
<xsl:param name="space"/>
<xsl:for-each select="//member[ex:nameSpace(., 0) = $space]">
<xsl:sort select="ex:nameSpace(., 1)"/>
<xsl:sort select="ex:sortOrder(string(@name))"/>
<xsl:sort data-type="number" select="summary/@value"/>
<xsl:sort select="ex:baseName(.)"/>

<!-- Variables used by several different elements
******************************* -->
<!-- Class Name. Name of class to which the Member belongs
********************** -->
<xsl:variable name="Class" select="ex:className(string(@name))"/>

<!-- Div containing Member name with anchor to the qualified-id for the
element * -->
<!-- Adds a link to the TOC (#top) and parent NameSpace -->
<xsl:if test="position() > 1 and $Class = 'class'">
&break;<xsl:text
disable-output-escaping="yes">&lt;/div&gt;</xsl:text>&break;
<div class="nav-box">
<xsl:element name="a">
<xsl:attribute name="class">nav</xsl:attribute>
<xsl:attribute name="onclick">return aclick(this, 1)</xsl:attribute>
<xsl:attribute name="href">#<xsl:value-of
select="generate-id(key('keySpace',$space))"/></xsl:attribute>
^ <xsl:value-of select="$space"/> NameSpace
</xsl:element>
</div>
&break;<xsl:text disable-output-escaping="yes">&lt;div
class="wrap"&gt;</xsl:text>&break;
</xsl:if>
<xsl:element name="a">
<xsl:attribute name="name"><xsl:value-of
select="generate-id(@name)"/></xsl:attribute>
<xsl:attribute name="id"><xsl:value-of
select="generate-id(@name)"/></xsl:attribute>
</xsl:element>&break;
<xsl:element name="div">
<xsl:attribute name="class">
<xsl:choose>
<xsl:when test="$Class = 'class'">class</xsl:when>
<xsl:when test="$Class = 'event'">event</xsl:when>
<xsl:blush:therwise>member</xsl:blush:therwise>
</xsl:choose>
</xsl:attribute>
<xsl:if test="$Class = 'class'">
&break;<xsl:text disable-output-escaping="yes">&lt;div
class="title-box"&gt;</xsl:text>&break;
</xsl:if>
<xsl:element name="div">
<xsl:attribute name="class">
<xsl:choose>
<!-- Class, Enum, or Type Header Label
****************************************** -->
<xsl:when test="$Class = 'class'">class-title</xsl:when>
<!-- Non-type Member Header Label
*********************************************** -->
<xsl:blush:therwise>member-title</xsl:blush:therwise>
</xsl:choose>
</xsl:attribute>
<!-- Call Line Break Encoder
*****************************************************-->
<xsl:call-template name="encoder">
<xsl:with-param name="str" select="ex:expandedName(.)"/>
<xsl:with-param name="class">line-indent</xsl:with-param>
<xsl:with-param name="index" select="number(0)"/>
<xsl:with-param name="hasParams" select="starts-with(@name, 'M')"/>
</xsl:call-template>
<xsl:if test="$Class = 'class'">
<xsl:element name="div">
<xsl:attribute name="class">nsBox</xsl:attribute>
<xsl:element name="a">
<xsl:attribute name="class">nsLink</xsl:attribute>
<xsl:attribute name="onclick">return aclick(this, 1)</xsl:attribute>
<xsl:attribute name="href">#<xsl:value-of
select="generate-id(key('keySpace',$space))"/></xsl:attribute>
<xsl:value-of select="$space"/></xsl:element></xsl:element>
</xsl:if>
</xsl:element>
<xsl:if test="$Class = 'class'">
&break;<xsl:text
disable-output-escaping="yes">&lt;/div&gt;</xsl:text>&break;
</xsl:if>
<xsl:choose>

<!-- Class Information
********************************************************** -->
<xsl:when test="$Class = 'class'">
<xsl:apply-templates select="summary"/>
<xsl:apply-templates select="remarks"/>
<xsl:if test="typeparam">
<xsl:apply-templates select="param|typeparam"/>
</xsl:if>
<xsl:apply-templates select="example"/>
<xsl:apply-templates select="permission"/>
<xsl:if test="seealso">
<div class="seeAlso">See Also</div>
<xsl:apply-templates select="seealso"/>
</xsl:if>
</xsl:when>

<!-- Method Information
********************************************************* -->
<xsl:when test="$Class = 'method'">
<xsl:apply-templates select="summary"/>
<xsl:if test="param|typeparam">
<xsl:apply-templates select="param|typeparam"/>
</xsl:if>
<xsl:apply-templates select="returns"/>
<xsl:if test="exception">
<xsl:apply-templates select="exception"/>
</xsl:if>
<xsl:apply-templates select="remarks"/>
<xsl:apply-templates select="example"/>
<xsl:apply-templates select="permission"/>
<xsl:if test="seealso">
<div class="seeAlso">See Also</div>
<xsl:apply-templates select="seealso"/>
</xsl:if>
</xsl:when>

<!-- Property Information
****************************************************** -->
<xsl:when test="$Class = 'property'">
<xsl:apply-templates select="summary"/>
<xsl:if test="param|typeparam">
<xsl:apply-templates select="param|typeparam"/>
</xsl:if>
<xsl:apply-templates select="value"/>
<xsl:if test="exception">
<xsl:apply-templates select="exception"/>
</xsl:if>
<xsl:apply-templates select="remarks"/>
<xsl:apply-templates select="example"/>
<xsl:apply-templates select="permission"/>
<xsl:if test="seealso">
<div class="seeAlso">See Also</div>
<xsl:apply-templates select="seealso"/>
</xsl:if>
</xsl:when>

<!-- Any other Member Information
*********************************************** -->
<xsl:blush:therwise>
<xsl:apply-templates select="summary"/>
<xsl:if test="typeparam">
<xsl:apply-templates select="param|typeparam"/>
</xsl:if>
<xsl:apply-templates select="remarks"/>
<xsl:apply-templates select="example"/>
<xsl:apply-templates select="permission"/>
<xsl:if test="seealso">
<div class="seeAlso">See Also</div>
<xsl:apply-templates select="seealso"/>
</xsl:if>
</xsl:blush:therwise>
</xsl:choose>
</xsl:element>
</xsl:for-each>
</xsl:template>

<!-- Template to generate a relative link to a reference to a member in a
file -->
<xsl:template name="href">
<xsl:param name="assembly"/>
<xsl:param name="target"/>
<xsl:choose>
<xsl:when test="$assembly = $assy">
<xsl:value-of select="concat('#', $target)"/>
</xsl:when>
<xsl:blush:therwise>
<xsl:value-of select="concat(concat($assembly, '.htm#'), $target)"/>
</xsl:blush:therwise>
</xsl:choose>
</xsl:template>

<!-- Template to insert a line break in text parsed via script
******************* -->
<xsl:template name="encoder">
<xsl:param name="str"/>
<xsl:param name="class"/>
<xsl:param name="index"/>
<xsl:param name="hasParams"/>

<!-- Length of string from index (end of last break) to end
********************** -->
<xsl:variable name="len" select="string-length($str) - $index"/>
<xsl:if test="$len > 0">
<!-- Substring from index to end of str (substring to begin with)
**************** -->
<xsl:variable name="substr" select="substring($str, $index)"/>
<!-- Substring between index and next occurrence of 'brxx'
*********************** -->
<xsl:variable name="startstr" select="substring-before($substr,
'brxx')"/>
<xsl:choose>
<!-- No Breaks in
line************************************************************ -->
<xsl:when test="$len = string-length($str) and $startstr = ''">
<xsl:value-of disable-output-escaping="yes" select="$str"/>
</xsl:when>
<!-- Breaks in line, first line (No Span to offset, but break after)
************* -->
<xsl:when test="$startstr != '' and $index = 0">
<xsl:value-of disable-output-escaping="yes"
select="$startstr"/>&line-break; 
<xsl:call-template name="encoder">
<xsl:with-param name="str" select="$str"/>
<xsl:with-param name="class" select="$class"/>
<xsl:with-param name="hasParams" select="$hasParams"/>
<!-- Next index begins after this occurrence of 'brxx'
***************************-->
<xsl:with-param name="index" select="$index + string-length($startstr)
+ 5"/>
</xsl:call-template>
</xsl:when>
<!-- Breaks in line, but not last line of broken lines (Span with break
after) *** -->
<xsl:when test="$startstr != ''">
<!-- Span with $startstr & line break
******************************************** -->
<xsl:element name="span">
<xsl:attribute name="class">
<xsl:value-of select="$class"/>
</xsl:attribute>
<xsl:value-of disable-output-escaping="yes" select="$startstr"/>
</xsl:element>&line-break; 
<xsl:call-template name="encoder">
<xsl:with-param name="str" select="$str"/>
<xsl:with-param name="class" select="$class"/>
<xsl:with-param name="hasParams" select="$hasParams"/>
<!-- Next index begins after this occurrence of 'brxxk'
***************************-->
<xsl:with-param name="index" select="$index + string-length($startstr)
+ 5"/>
</xsl:call-template>
</xsl:when>
<xsl:blush:therwise>
<!-- Last of broken lines (Span only)
******************************************** -->
<xsl:element name="span">
<xsl:if test="$class != 'none'">
<xsl:attribute name="class">
<xsl:value-of select="$class"/>
</xsl:attribute>
</xsl:if>
<xsl:choose>
<xsl:when test="$hasParams">
<xsl:value-of disable-output-escaping="yes"
select="substring-before($substr, ')')"/>
</xsl:when>
<xsl:blush:therwise>
<xsl:value-of disable-output-escaping="yes" select="$substr"/>
</xsl:blush:therwise>
</xsl:choose>
</xsl:element>
<xsl:if test="$hasParams">
&line-break; 
<xsl:element name="span">
<xsl:attribute name="class">
<xsl:value-of select="$class"/>
</xsl:attribute>)
</xsl:element>
</xsl:if>
</xsl:blush:therwise>
</xsl:choose>
</xsl:if>
</xsl:template>

<!-- Template to replace "brxx" with "<br>" and " " with "&nbsp;" in a
string *** -->
<xsl:template name="htmlEncoder">
<xsl:param name="str"/>
<xsl:param name="index"/>

<!-- Length of string from index (end of last break) to end
********************** -->
<xsl:variable name="len" select="string-length($str) - $index"/>
<xsl:if test="$len > 0">
<!-- Substring from index to end of str (substring to begin with)
**************** -->
<xsl:variable name="substr" select="substring($str, $index)"/>
<!-- Substring between index and next occurrence of 'brxx' or 'spxx'
************* -->
<xsl:variable name="firstSequence" select="ex:subStringChoose($substr)"/>
<xsl:variable name="startstr" select="substring-before($substr,
$firstSequence)"/>
<xsl:choose>
<!-- No Breaks in
line************************************************************ -->
<xsl:when test="$firstSequence = ''">
<xsl:value-of disable-output-escaping="yes" select="$str"/>
</xsl:when>
<!-- Breaks in line, but not last line of broken lines
*************************** -->
<xsl:blush:therwise>
<!-- $startstr & line break or space marker
************************************** -->
<xsl:value-of disable-output-escaping="yes" select="$startstr"/>
<xsl:choose>
<xsl:when test="$firstSequence =
'brxx'">&line-break;&break;</xsl:when>
<xsl:blush:therwise>&space-marker;</xsl:blush:therwise>
</xsl:choose>
<xsl:call-template name="htmlEncoder">
<xsl:with-param name="str" select="$str"/>
<!-- Next index begins after this occurrence of 'brxx' or spxx
*******************-->
<xsl:with-param name="index" select="$index + string-length($startstr)
+ 4"/>
</xsl:call-template>
</xsl:blush:therwise>
</xsl:choose>
</xsl:if>
</xsl:template>

<!-- Template for Summary, Remarks, Returns, or Value tags
********************** -->
<xsl:template match="summary|remarks|returns|value">
<xsl:element name="table">
<xsl:attribute name="class">
<xsl:choose>
<xsl:when test="starts-with(../@name, 'T')">class-details</xsl:when>
<xsl:blush:therwise>details</xsl:blush:therwise>
</xsl:choose>
</xsl:attribute>
<tr>
<td class="label">
<xsl:choose>
<xsl:when test="local-name() = 'summary'">Summary:</xsl:when>
<xsl:when test="local-name() = 'remarks'">Remarks:</xsl:when>
<xsl:when test="local-name() = 'value'">Value:</xsl:when>
<xsl:blush:therwise>Returns:</xsl:blush:therwise>
</xsl:choose>
</td>
<td class="textbox">
<xsl:apply-templates/>
</td>
</tr>
</xsl:element>
</xsl:template>

<!-- Tamplate for param or typeparam tags
*************************************** -->
<xsl:template match="param|typeparam">
<xsl:if test="position() = 1">
&break;<xsl:text disable-output-escaping="yes">&lt;table
class="details"&gt;</xsl:text>&break;
<tr>
<td class="label" colspan="3">Parameters:</td>
</tr>
</xsl:if>
<tr>
<td class="paramTd">&space-marker;</td>
<td class="paramName">
<xsl:element name="a">
<xsl:attribute name="name"><xsl:value-of
select="generate-id()"/></xsl:attribute>
<xsl:attribute name="id"><xsl:value-of
select="generate-id()"/></xsl:attribute>
</xsl:element>
<xsl:value-of select="@name"/>
</td>
<td class="textbox">
<xsl:apply-templates/>
</td>
</tr>
<xsl:if test="position() = last()">
&break;<xsl:text
disable-output-escaping="yes">&lt;/table&gt;</xsl:text>&break;
</xsl:if>
</xsl:template>

<!-- Template for paramref tags (tags that link to a parameter)
***************** -->
<xsl:template match="paramref">
&break;<xsl:element name="a">
<xsl:attribute name="class">paramref</xsl:attribute>
<xsl:attribute name="onclick">return aclick(this, 1)</xsl:attribute>
<xsl:attribute name="href">#<xsl:value-of
select="generate-id(key('keyName', concat(string(ancestor::member/@name),
string(@name))))"/></xsl:attribute>
<xsl:attribute name="style">color: #20b2aa</xsl:attribute>
<xsl:value-of select="@name"/>
</xsl:element>
</xsl:template>

<!-- Template for typeparamref tags (tags that link to Generic Type
parameters) * -->
<xsl:template match="typeparamref">
&break;<xsl:element name="a">
<xsl:attribute name="class">paramref</xsl:attribute>
<xsl:attribute name="onclick">return aclick(this, 1)</xsl:attribute>
<xsl:attribute name="href">#<xsl:value-of
select="generate-id(key('keyTypeName', ex:GetTypeParam(ancestor::member,
string(@name))))"/></xsl:attribute>
<xsl:attribute name="style">color: #20b2aa</xsl:attribute>
<xsl:value-of select="@name"/>
</xsl:element>
</xsl:template>

<!-- Template for Exception tags
************************************************ -->
<xsl:template match="exception">
<table class="details">
<xsl:if test="position() = 1">
<tr>
<td class="label" colspan="3">Exceptions:</td>
</tr>
</xsl:if>
<tr>
<td class="paramTd">&space-marker;</td>
<td colspan="2" class="paramName">
<xsl:element name="a">
<xsl:attribute name="name"><xsl:value-of
select="generate-id()"/></xsl:attribute>
<xsl:attribute name="id"><xsl:value-of
select="generate-id()"/></xsl:attribute>
</xsl:element>
<xsl:value-of select="substring(@cref, 3)"/>
</td>
</tr>
<tr>
<td>&space-marker;</td><td class="spaceTd">&space-marker;</td>
<td class="textbox">
<xsl:apply-templates/>
</td>
</tr>
</table>
</xsl:template>

<!-- Template for Example tags
************************************************** -->
<xsl:template match="example">
<table class="details">
<tr>
<td colspan="2" class="label">Example:
</td>
</tr>
<tr>
<td class="paramTd">&space-marker;</td>
<td class="example"><xsl:apply-templates/></td>
</tr>
</table>
</xsl:template>

<!--Template for code (code) tags
*********************************************** -->
<xsl:template match="code" xml:space="preserve">
<div class="code"><xsl:call-template name="htmlEncoder">
<xsl:with-param name="str" select="ex:encodeAsHtml(.)"/>
<xsl:with-param name="index" select="number(1)"/>
</xsl:call-template></div>
</xsl:template>

<!-- Template for Inline Code (c) tags
****************************************** -->
<xsl:template match="c">
<span class="coderef">
<xsl:value-of select="."/>
</span>
</xsl:template>

<!-- Template for paragraph tags
************************************************ -->
<xsl:template match="para">
<p>
<xsl:apply-templates/>
</p>
</xsl:template>

<!-- Template for list tags
***************************************************** -->
<xsl:template match="list">
<xsl:choose>
<xsl:when test="@type = 'bullet'">
<ul>
<xsl:apply-templates mode="list"/>
</ul>
</xsl:when>
<xsl:when test="@type = 'number'">
<ol>
<xsl:apply-templates mode="list"/>
</ol>
</xsl:when>
<xsl:when test="@type = 'table'">
<table>
<xsl:apply-templates mode="table"/>
</table>
</xsl:when>
</xsl:choose>
</xsl:template>

<!-- Template for list table header row tags ('item name="table"')
************** -->
<xsl:template match="listheader">
<tr>
<xsl:apply-templates/>
</tr>
</xsl:template>

<!-- Template for list item ('list type="bullet|number"') tags
****************** -->
<xsl:template match="item" mode="list">
<li>
<span class="list-item"><xsl:value-of select="text()"/></span>
<xsl:apply-templates select="description" mode="list"/>
</li>
</xsl:template>

<!-- Template for Dictionary Description (dd) tags ('list type="?"')
************ -->
<xsl:template match="description" mode="list">
<span><xsl:value-of select="text()"/></span>
</xsl:template>

<!-- Template for list table ('list type="table"') tags
************************* -->
<xsl:template match="item" mode="table">
<tr>
<span class="list-item"><xsl:value-of select="text()"/></span>
<xsl:apply-templates select="description" mode="table"/>
</tr>
</xsl:template>

<!-- Template for table description cell ('list type="?"') tags
***************** -->
<xsl:template match="description" mode="table">
<td>
<span class="list-item"><xsl:value-of select="text()"/></span>
</td>
</xsl:template>

<!-- Template for Dictionary Term (dt) ('item name=""') tags
******************** -->
<xsl:template match="term">
<td>
<xsl:apply-templates/>
</td>
</xsl:template>

<!-- Template for see tags (tags that link to members
*************************** -->
<xsl:template match="see">
<xsl:apply-templates select="@cref"/>
</xsl:template>

<!-- Template for all tags that contain a cref attribute not handled
in the template
************************************************************ -->
<xsl:template match="@cref">
<xsl:variable name="cref" select="."/>
<xsl:element name="a">
<xsl:attribute name="onclick">return aclick(this, 1)</xsl:attribute>
<xsl:attribute name="href">#<xsl:value-of
select="generate-id(//member[@name=$cref]/@name)"/></xsl:attribute>
<xsl:apply-templates select="../*"/>
<xsl:apply-templates select="../child::node()"/>
</xsl:element>
</xsl:template>

<!-- Template for SeeAlso tags (tags that link at the bottom of the page
******** -->
<xsl:template match="seealso">
<xsl:element name="a">
<xsl:attribute name="onclick">return aclick(this, 1)</xsl:attribute>
<xsl:attribute name="href">#<xsl:value-of
select="ex:fullName(ancestor::member)"/></xsl:attribute>
<xsl:value-of select="ex:fullName(ancestor::member)"/>
</xsl:element> 
</xsl:template>

<!-- Template for permission tags
*********************************************** -->
<xsl:template match="permission">
<table class="details">
<tr>
<td class="security" colspan="2">.NET Framework Security</td>
</tr>
<tr>
<td style="width:115PX;">&space-marker;</td>
<td class="textbox">
<xsl:apply-templates/>
</td>
</tr>
</table>
</xsl:template>

<!-- Template for local variable tags
******************************************* -->
<xsl:template match="var">
<var><xsl:value-of select="."/></var>
</xsl:template>

<!-- Template for unmodified InnerText
****************************************** -->
<xsl:template match="text()">
<span><xsl:value-of select="ex:replaceCurlies(string(.))"/></span>
</xsl:template>

</xsl:stylesheet>

<!----------------------------------------------------^^--XSLT--^^---------------------------------------------------->
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top