[PATCH] monodocs2html support for cross-type hyperlinks
Jonathan Pryor <[email protected]> Wed, 20 Sep 2006 17:34:43 -0400
| Newsgroups | gmane.comp.gnome.mono.documentation |
|---|---|
| Message-ID | <[email protected]> |
Attached is a patch to support to monodocs2html for cross-type hyperlinks. In short, it allows you to use <see cref="M:Foo.Bar" /> from within the Baz type comments and have it turn into a hyperlink to Foo.html#Foo.Bar. It requires removing the generate-id() XSLT calls to use full type +member names instead. For an example of this in action, compare the new file: http://balthasar.jprl.com/~jon/Projects/mono-fuse/docs/Mono.Fuse/FileSystem.html to the original output: http://www.jprl.com/Projects/mono-fuse/docs/Mono.Fuse/FileSystem.html It also uses <h2>...<h4> elements instead of <div> elements everywhere, as this provides additional content structure. (I also have an XSLT that uses h1..h3 to generate a table-of-contents, and I'd like to use this XSLT in the future.) Permission to commit? Thanks, - Jon _______________________________________________ Mono-docs-list maillist - [email protected] http://lists.ximian.com/mailman/listinfo/mono-docs-list
monodocs2html.patch
(text/x-patch, 15.1 KB)
Index: ChangeLog =================================================================== --- ChangeLog (revision 65740) +++ ChangeLog (working copy) @@ -1,3 +1,14 @@ +2006-09-20 Joshua Tauberer <[email protected]> + + * defaulttemplate.xsl: Add additional CSS styles so that the tr/@bgcolor + attribute isn't needed (makes XHTML validators happier). + * overview.xsl: Use <h2/> instead of <div/>. + * stylesheet.xsl: Use <h2/>..<h4/> instead of <div/> -- provides better + structure. Implement more support for <see cref="" /> handling, so that + you can now reference members in other types within the same assembly, and + have them become proper hyperlinks. Don't use generate-id(), and create + link names manually so that cross-page hyperlinks work. + 2006-04-01 Joshua Tauberer <[email protected]> * monodocs2html.cs: Skip files that are missing. Index: defaulttemplate.xsl =================================================================== --- defaulttemplate.xsl (revision 65740) +++ defaulttemplate.xsl (working copy) @@ -41,6 +41,8 @@ .MembersListing td { margin: 0px; border: 1px solid black; padding: .25em } .TypesListing td { margin: 0px; padding: .25em } + .InnerSignatureTable tr { background-color: #f2f2f2; } + .TypePermissionsTable tr { background-color: #f2f2f2; } </style> Index: overview.xsl =================================================================== --- overview.xsl (revision 65740) +++ overview.xsl (working copy) @@ -79,7 +79,7 @@ <Remarks> <xsl:for-each select="Types/Namespace[@Name=$namespace or $namespace='all' or count(parent::*/Namespace)=1][count(Type)>0]"> <xsl:if test="$namespace='all' or count(parent::*/Namespace)=1"> - <div class="Section"><xsl:value-of select="@Name"/> Namespace</div> + <h2 class="Section"><xsl:value-of select="@Name"/> Namespace</h2> </xsl:if> <p><xsl:apply-templates select="document(concat(@Name,'.xml'), .)/Namespace/Docs/remarks" mode="notoppara"/></p> Index: stylesheet.xsl =================================================================== --- stylesheet.xsl (revision 65740) +++ stylesheet.xsl (working copy) @@ -19,6 +19,8 @@ <!-- The namespace that the current type belongs to. --> <xsl:variable name="TypeNamespace" select="substring(/Type/@FullName, 1, string-length(/Type/@FullName) - string-length(/Type/@Name) - 1)"/> + <xsl:variable name="TypeFullName" select="/Type/@FullName"/> + <xsl:variable name="mono-docs">http://www.go-mono.com/docs/monodoc.ashx?link=</xsl:variable> <!-- THE MAIN RENDERING TEMPLATE --> @@ -66,7 +68,7 @@ <table class="SignatureTable" cellspacing="0" width="100%"> <tr><td> <table class="InnerSignatureTable" cellpadding="10" cellspacing="0" width="100%"> - <tr bgcolor="#f2f2f2"><td> + <tr><td> <xsl:choose> <xsl:when test="$language='C#'"> @@ -190,7 +192,7 @@ <!-- MEMBER LISTING --> <xsl:if test="not(Base/BaseTypeName='System.Delegate' or Base/BaseTypeName='System.MulticastDelegate' or Base/BaseTypeName='System.Enum')"> - <div class="Section">Members</div> + <h2 class="Section">Members</h2> <div class="SectionBox"> @@ -268,15 +270,21 @@ <xsl:if test="not(Base/BaseTypeName='System.Delegate' or Base/BaseTypeName='System.MulticastDelegate' or Base/BaseTypeName='System.Enum')"> <xsl:variable name="Type" select="."/> - <div class="Section">Member Details</div> + <h2 class="Section">Member Details</h2> <div class="SectionBox"> <xsl:for-each select="Members/Member"> - <a name="member_{generate-id(.)}"></a> + <xsl:variable name="linkname"><xsl:call-template name="GetLinkName" + ><xsl:with-param name="type" select="../.." + /><xsl:with-param name="member" select="." /></xsl:call-template></xsl:variable> + <xsl:variable name="linkid"><xsl:call-template name="GetLinkId" + ><xsl:with-param name="type" select="../.." + /><xsl:with-param name="member" select="." /></xsl:call-template></xsl:variable> + <a name="{$linkname}"></a> - <div class="MemberName"> + <h3 id="{$linkid}" class="MemberName"> <xsl:choose> <xsl:when test="MemberType='Constructor'"> <xsl:value-of select="$Type/@Name"/> Constructor @@ -288,7 +296,7 @@ <xsl:value-of select="@MemberName"/> </xsl:otherwise> </xsl:choose> - </div> + </h3> <div class="MemberSignature"> <!-- recreate the signature --> @@ -485,7 +493,7 @@ <!-- alt member: not sure what these are for, actually --> <xsl:if test="count(Docs/altmember)"> - <div class="Subsection">See Also</div> + <h4 class="Subsection">See Also</h4> <div class="SubsectionBox"> <xsl:for-each select="Docs/altmember"> <div><xsl:apply-templates select="@cref" mode="cref"/></div> @@ -496,7 +504,7 @@ <!-- parameters & return & value --> <xsl:if test="count(Docs/param)"> - <div class="Subsection">Parameters</div> + <h4 class="Subsection">Parameters</h4> <div class="SubsectionBox"> <dl> <xsl:for-each select="Docs/param"> @@ -509,13 +517,13 @@ </div> </xsl:if> <xsl:if test="count(Docs/returns)"> - <div class="Subsection">Returns</div> + <h4 class="Subsection">Returns</h4> <div class="SubsectionBox"> <xsl:apply-templates select="Docs/returns" mode="notoppara"/> </div> </xsl:if> <xsl:if test="count(Docs/value)"> - <div class="Subsection">Value</div> + <h4 class="Subsection">Value</h4> <div class="SubsectionBox"> <xsl:apply-templates select="Docs/value" mode="notoppara"/> </div> @@ -524,7 +532,7 @@ <!-- thread safety --> <xsl:if test="count(ThreadingSafetyStatement)"> - <div class="Subsection">Thread Safety</div> + <h4 class="Subsection">Thread Safety</h4> <div class="SubsectionBox"> <xsl:apply-templates select="ThreadingSafetyStatement" mode="notoppara"/> </div> @@ -534,10 +542,10 @@ <!-- permissions --> <xsl:if test="count(Docs/permission)"> - <div>Permissions</div> + <h4>Permissions</h4> <div class="SubsectionBox"> <table class="TypePermissionsTable" border="1" cellpadding="6"> - <tr bgcolor="#f2f2f2"><th>Type</th><th>Reason</th></tr> + <tr><th>Type</th><th>Reason</th></tr> <xsl:for-each select="Docs/permission"> <tr valign="top"> <td><xsl:apply-templates select="@cref" mode="typelink"><xsl:with-param name="wrt" select="$TypeNamespace"/></xsl:apply-templates></td> @@ -553,7 +561,7 @@ <!-- method/property/constructor exceptions --> <xsl:if test="count(Docs/exception)"> - <div class="Subsection">Exceptions</div> + <h4 class="Subsection">Exceptions</h4> <div class="SubsectionBox"> <table class="ExceptionsTable"> <tr><th>Type</th><th>Condition</th></tr> @@ -572,7 +580,7 @@ <!-- remarks --> <xsl:if test="count(Docs/remarks)"> - <div class="Subsection">Remarks</div> + <h4 class="Subsection">Remarks</h4> <div class="SubsectionBox"> <xsl:apply-templates select="Docs/remarks" mode="notoppara"/> </div> @@ -678,12 +686,10 @@ <xsl:when test="count($typeentry)"> <xsl:value-of select="concat($basepath,$typeentry/parent::Namespace/@Name, '/', $typeentry/@Name)"/>.<xsl:value-of select="$ext"/> </xsl:when> - <xsl:when test="starts-with($T, 'System.')"> - http://mono.ximian.com:8080/monodoc.ashx?link=T:<xsl:value-of select="$T"/> - </xsl:when> - <xsl:otherwise> - javascript:alert("Documentation not found.") - </xsl:otherwise> + <xsl:when test="starts-with($T, 'System.')" + ><xsl:value-of select="$mono-docs" />T:<xsl:value-of select="$T" + /></xsl:when> + <xsl:otherwise>javascript:alert("Documentation not found.")</xsl:otherwise> </xsl:choose> </xsl:attribute> @@ -740,11 +746,81 @@ </xsl:choose> </xsl:template> + <xsl:template name="makememberlink"> + <xsl:param name="cref"/> + + <xsl:variable name="anchor" select="substring($cref, 3)" /> + + <xsl:variable name="fullname" + ><xsl:choose><xsl:when test="starts-with($cref, 'C:')" + ><xsl:value-of select="substring($cref, 3)" + /></xsl:when><xsl:otherwise><xsl:call-template name="GetTypeName" + ><xsl:with-param name="type" select="substring($cref, 3)" + /></xsl:call-template></xsl:otherwise></xsl:choose> + </xsl:variable> + + <xsl:variable name="memberName" + ><xsl:choose><xsl:when test="starts-with($cref, 'C:')" + ></xsl:when><xsl:otherwise>.<xsl:call-template name="GetMemberName" + ><xsl:with-param name="type" select="substring($cref, 3)" + /></xsl:call-template></xsl:otherwise></xsl:choose> + </xsl:variable> + + <xsl:variable name="T" select="$fullname"/> + <a> + <!-- Search for type in the index.xml file. --> + <xsl:variable name="typeentry" select="document('index.xml')/Overview/Types/Namespace/Type[concat(parent::Namespace/@Name,'.',@Name) = $T]"/> + + <xsl:attribute name="href"> + <xsl:choose> + <xsl:when test="count($typeentry)"> + <xsl:value-of select="concat($basepath,$typeentry/parent::Namespace/@Name, '/', $typeentry/@Name)"/>.<xsl:value-of select="$ext"/>#<xsl:value-of select="$anchor" /> + </xsl:when> + <xsl:when test="starts-with($T, 'System.')" + ><xsl:value-of select="$mono-docs" />T:<xsl:value-of select="$T" + /></xsl:when> + <xsl:otherwise>javascript:alert("Documentation not found.")</xsl:otherwise> + </xsl:choose> + </xsl:attribute> + <xsl:value-of select="concat($fullname, $memberName)" /> + </a> + </xsl:template> + + <xsl:template name="GetTypeName"> + <xsl:param name="type" /> + <xsl:variable name="prefix" select="substring-before($type, '.')" /> + <xsl:variable name="suffix" select="substring-after($type, '.')" /> + <xsl:choose> + <xsl:when test="not(contains($suffix, '.'))"><xsl:value-of + select="$prefix" /></xsl:when> + <xsl:otherwise><xsl:value-of select="$prefix" + />.<xsl:call-template name="GetTypeName"><xsl:with-param name="type" + select="$suffix" /></xsl:call-template></xsl:otherwise> + </xsl:choose> + </xsl:template> + + <xsl:template name="GetMemberName"> + <xsl:param name="type" /> + <xsl:variable name="prefix" select="substring-before($type, '.')" /> + <xsl:variable name="suffix" select="substring-after($type, '.')" /> + <xsl:choose> + <xsl:when test="not(contains($suffix, '.'))"><xsl:value-of + select="$suffix" /></xsl:when> + <xsl:otherwise><xsl:call-template name="GetMemberName"><xsl:with-param name="type" + select="$suffix" /></xsl:call-template></xsl:otherwise> + </xsl:choose> + </xsl:template> + <!-- Transforms the contents of the selected node containing a cref into a hyperlink. --> <xsl:template match="*|@*" mode="cref"> + <xsl:call-template name="makememberlink"> + <xsl:with-param name="cref" select="."/> + </xsl:call-template> + <!-- <a> <xsl:attribute name="href"><xsl:value-of select="."/></xsl:attribute> <xsl:value-of select="substring-after(., ':')"/></a> + --> </xsl:template> <xsl:template name="membertypeplural"> @@ -901,22 +977,22 @@ </xsl:template> <xsl:template match="list[@type='bullet']"> - <UL> + <ul> <xsl:for-each select="item"> - <LI> + <li> <xsl:apply-templates select="term" mode="notoppara"/> - </LI> + </li> </xsl:for-each> - </UL> + </ul> </xsl:template> <xsl:template match="list[@type='number']"> - <OL> + <ol> <xsl:for-each select="item"> - <LI> + <li> <xsl:apply-templates select="term" mode="notoppara"/> - </LI> + </li> </xsl:for-each> - </OL> + </ol> </xsl:template> <xsl:template match="list"> @@ -935,7 +1011,9 @@ </xsl:call-template> </xsl:when> <xsl:otherwise> - <xsl:value-of select="substring-after(@cref, ':')"/> + <xsl:call-template name="makememberlink"> + <xsl:with-param name="cref" select="@cref"/> + </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:template> @@ -973,13 +1051,13 @@ <xsl:if test="count($MEMBERS)"> <!-- header --> - <div class="Subsection" style="margin-bottom: .75em"> + <h3> <xsl:if test="$showprotected">Protected </xsl:if> <xsl:call-template name="membertypeplural"><xsl:with-param name="name" select="$listmembertype"/></xsl:call-template> - </div> + </h3> <div class="SubsectionBox"> - <table Class="MembersListing"> + <table class="MembersListing"> <xsl:for-each select="$MEMBERS"> <!--<xsl:sort select="contains(MemberSignature[@Language='C#']/@Value,' static ')" data-type="text"/>--> @@ -988,7 +1066,11 @@ <xsl:sort select="count(Parameters/Parameter)"/> <xsl:sort select="Parameters/Parameter/@Type"/> - <xsl:variable name="linkname" select="generate-id(.)"/> + <!-- <xsl:variable name="linkname" select="generate-id(.)"/> --> + + <xsl:variable name="linkid"><xsl:call-template name="GetLinkId" + ><xsl:with-param name="type" select="../.." + /><xsl:with-param name="member" select="." /></xsl:call-template></xsl:variable> <tr valign="top"> @@ -999,7 +1081,7 @@ <td> <div> <b> - <a href="#member_{$linkname}"> + <a href="#{$linkid}"> <xsl:value-of select="$TypeName"/> </a> </b> @@ -1030,7 +1112,7 @@ <!-- link to member page --> <b> - <a href="#member_{$linkname}"> + <a href="#{$linkid}"> <xsl:value-of select="@MemberName"/> </a> </b> @@ -1101,7 +1183,7 @@ <!-- link to method page --> <b> - <a href="#member_{$linkname}"> + <a href="#{$linkid}"> <xsl:value-of select="@MemberName"/> </a> </b> @@ -1142,7 +1224,7 @@ <xsl:choose> <xsl:when test="@MemberName='op_Implicit' or @MemberName='op_Explicit'"> <b> - <a href="#member_{$linkname}"> + <a href="#{$linkid}"> Conversion <xsl:choose> <xsl:when test="ReturnValue/ReturnType = //Type/@FullName"> @@ -1166,14 +1248,14 @@ </xsl:when> <xsl:when test="count(Parameters/Parameter)=1"> <b> - <a href="#member_{$linkname}"> + <a href="#{$linkid}"> <xsl:value-of select="substring-after(@MemberName, 'op_')"/> </a> </b> </xsl:when> <xsl:otherwise> <b> - <a href="#member_{$linkname}"> + <a href="#{$linkid}"> <xsl:value-of select="substring-after(@MemberName, 'op_')"/> </a> </b> @@ -1202,7 +1284,7 @@ <xsl:otherwise> <!-- Other types: just provide a link --> - <a href="#member_{$linkname}"> + <a href="#{$linkid}"> <xsl:value-of select="@MemberName"/> </a> </xsl:otherwise> @@ -1219,7 +1301,24 @@ </xsl:if> </xsl:template> + <xsl:template name="GetLinkName"> + <xsl:param name="type"/> + <xsl:param name="member" + /><xsl:value-of select="concat($type/@FullName, '.', $member/@MemberName)" + /></xsl:template> + <xsl:template name="GetLinkId"> + <xsl:param name="type"/> + <xsl:param name="member" + /><xsl:value-of select="concat($type/@FullName, '.', $member/@MemberName)" + /><xsl:if test="count($member/Parameters/Parameter) > 0" + ><xsl:value-of select="'('" + /><xsl:for-each select="Parameters/Parameter" + ><xsl:if test="not(position()=1)">, </xsl:if + ><xsl:value-of select="@Type" + /></xsl:for-each><xsl:value-of select="')'" + /></xsl:if></xsl:template> + <xsl:template name="getmodifiers"> <xsl:param name="sig"/> <xsl:param name="protection" select="true()"/>