summaryrefslogtreecommitdiffstats
path: root/tools/Sandcastle/ProductionTransforms
diff options
context:
space:
mode:
Diffstat (limited to 'tools/Sandcastle/ProductionTransforms')
-rw-r--r--tools/Sandcastle/ProductionTransforms/AddFriendlyFilenames.xsl97
-rw-r--r--tools/Sandcastle/ProductionTransforms/AddGuidFilenames.xsl47
-rw-r--r--tools/Sandcastle/ProductionTransforms/AddXamlSyntaxData.xsl141
-rw-r--r--tools/Sandcastle/ProductionTransforms/ApplyPrototypeDocModel.xsl259
-rw-r--r--tools/Sandcastle/ProductionTransforms/ApplyVSDocModel.xsl767
-rw-r--r--tools/Sandcastle/ProductionTransforms/CreateHxC.xsl38
-rw-r--r--tools/Sandcastle/ProductionTransforms/CreatePrototypeToc.xsl142
-rw-r--r--tools/Sandcastle/ProductionTransforms/CreateVSToc.xsl207
-rw-r--r--tools/Sandcastle/ProductionTransforms/DsManifestToManifest.xsl23
-rw-r--r--tools/Sandcastle/ProductionTransforms/DsTocToManifest.xsl23
-rw-r--r--tools/Sandcastle/ProductionTransforms/DsTocToSitemap.xsl88
-rw-r--r--tools/Sandcastle/ProductionTransforms/DsTocToToc.xsl33
-rw-r--r--tools/Sandcastle/ProductionTransforms/FixScriptSharp.xsl87
-rw-r--r--tools/Sandcastle/ProductionTransforms/MergeDuplicates.xsl166
-rw-r--r--tools/Sandcastle/ProductionTransforms/MergeHxF.xsl28
-rw-r--r--tools/Sandcastle/ProductionTransforms/ReflectionToCDocML.xsl845
-rw-r--r--tools/Sandcastle/ProductionTransforms/ReflectionToChmIndex.xsl77
-rw-r--r--tools/Sandcastle/ProductionTransforms/ReflectionToChmProject.xsl47
-rw-r--r--tools/Sandcastle/ProductionTransforms/ReflectionToManifest.xsl21
-rw-r--r--tools/Sandcastle/ProductionTransforms/TocToChmContents.xsl79
-rw-r--r--tools/Sandcastle/ProductionTransforms/TocToHxsContents.xsl54
-rw-r--r--tools/Sandcastle/ProductionTransforms/Vs2005TocToDsToc.xsl41
22 files changed, 3310 insertions, 0 deletions
diff --git a/tools/Sandcastle/ProductionTransforms/AddFriendlyFilenames.xsl b/tools/Sandcastle/ProductionTransforms/AddFriendlyFilenames.xsl
new file mode 100644
index 0000000..4873c00
--- /dev/null
+++ b/tools/Sandcastle/ProductionTransforms/AddFriendlyFilenames.xsl
@@ -0,0 +1,97 @@
+<?xml version="1.0"?>
+<xsl:stylesheet
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:msxsl="urn:schemas-microsoft-com:xslt"
+ xmlns:ddue="urn:ddue-extensions"
+ version="1.1">
+
+ <msxsl:script language="C#" implements-prefix="ddue">
+ <msxsl:using namespace="System" />
+ <![CDATA[
+ public static string getFileName(string id) {
+ string fileName = id.Replace(':', '_').Replace('<', '_').Replace('>', '_');
+
+ if (fileName.IndexOf(".#ctor") != -1 && fileName.IndexOf("Overload") == -1)
+ {
+ fileName = "C_" + fileName.Substring(2);
+ fileName = fileName.Replace(".#ctor", ".ctor");
+ }
+ else if (fileName.IndexOf(".#ctor") != -1 && fileName.IndexOf("Overload") != -1)
+ {
+ fileName = fileName.Replace("Overload", "O_T");
+ fileName = fileName.Replace(".#ctor", ".ctor");
+ }
+ else if (fileName.IndexOf(".#cctor") != -1 && fileName.IndexOf("Overload") == -1)
+ {
+ fileName = "C_" + fileName.Substring(2);
+ fileName = fileName.Replace(".#cctor", ".cctor");
+ }
+ else if (fileName.IndexOf(".#cctor") != -1 && fileName.IndexOf("Overload") != -1)
+ {
+ fileName = fileName.Replace("Overload", "O_T");
+ fileName = fileName.Replace(".#cctor", ".cctor");
+ }
+ else if (fileName.IndexOf("Overload") != -1)
+ {
+ fileName = fileName.Replace("Overload", "O_T");
+ }
+
+ fileName = fileName.Replace('.', '_').Replace('#', '_');
+
+ int paramStart = fileName.IndexOf('(');
+ if(paramStart != -1)
+ {
+ fileName = fileName.Substring(0, paramStart) + GenerateParametersCode(id.Substring(paramStart));
+ }
+
+ return fileName;
+ }
+
+ private static string GenerateParametersCode(string parameterSection)
+ {
+ // TODO: figure out a consistent algorithm that works regardless of runtime version
+ int code = parameterSection.GetHashCode();
+
+ int parameterCount = 1;
+
+ for(int count = 0; count < parameterSection.Length; count += 1)
+ {
+ int c = (int) parameterSection[count];
+
+ if(c == ',')
+ ++parameterCount;
+ }
+
+ // format as (# of parameters)_(semi-unique hex code)
+ return string.Format("_{1}_{0:x8}", code, parameterCount);
+ }
+ ]]>
+ </msxsl:script>
+
+ <xsl:output indent="yes" encoding="UTF-8" />
+
+ <xsl:template match="/">
+ <reflection>
+ <xsl:apply-templates select="/*/assemblies" />
+ <xsl:apply-templates select="/*/apis" />
+ </reflection>
+ </xsl:template>
+
+ <xsl:template match="assemblies">
+ <xsl:copy-of select="." />
+ </xsl:template>
+
+ <xsl:template match="apis">
+ <apis>
+ <xsl:apply-templates select="api" />
+ </apis>
+ </xsl:template>
+
+ <xsl:template match="api">
+ <api id="{@id}">
+ <xsl:copy-of select="*" />
+ <file name="{ddue:getFileName(@id)}" />
+ </api>
+ </xsl:template>
+
+</xsl:stylesheet>
diff --git a/tools/Sandcastle/ProductionTransforms/AddGuidFilenames.xsl b/tools/Sandcastle/ProductionTransforms/AddGuidFilenames.xsl
new file mode 100644
index 0000000..f6dcd0b
--- /dev/null
+++ b/tools/Sandcastle/ProductionTransforms/AddGuidFilenames.xsl
@@ -0,0 +1,47 @@
+<?xml version="1.0"?>
+<xsl:stylesheet
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:msxsl="urn:schemas-microsoft-com:xslt"
+ xmlns:ddue="urn:ddue-extensions"
+ version="1.1">
+
+ <msxsl:script language="C#" implements-prefix="ddue">
+ <msxsl:using namespace="System.Security.Cryptography" />
+ <![CDATA[
+ public static string getFileName(string id) {
+ HashAlgorithm md5 = HashAlgorithm.Create("MD5");
+ byte[] input = Encoding.UTF8.GetBytes(id);
+ byte[] output = md5.ComputeHash(input);
+ Guid guid = new Guid(output);
+ return( guid.ToString() );
+ }
+ ]]>
+ </msxsl:script>
+
+ <xsl:output indent="yes" encoding="UTF-8" />
+
+ <xsl:template match="/">
+ <reflection>
+ <xsl:apply-templates select="/reflection/assemblies" />
+ <xsl:apply-templates select="/reflection/apis" />
+ </reflection>
+ </xsl:template>
+
+ <xsl:template match="assemblies">
+ <xsl:copy-of select="." />
+ </xsl:template>
+
+ <xsl:template match="apis">
+ <apis>
+ <xsl:apply-templates select="api" />
+ </apis>
+ </xsl:template>
+
+ <xsl:template match="api">
+ <api id="{@id}">
+ <xsl:copy-of select="*" />
+ <file name="{ddue:getFileName(@id)}" />
+ </api>
+ </xsl:template>
+
+</xsl:stylesheet>
diff --git a/tools/Sandcastle/ProductionTransforms/AddXamlSyntaxData.xsl b/tools/Sandcastle/ProductionTransforms/AddXamlSyntaxData.xsl
new file mode 100644
index 0000000..e0c7ecd
--- /dev/null
+++ b/tools/Sandcastle/ProductionTransforms/AddXamlSyntaxData.xsl
@@ -0,0 +1,141 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.1" xmlns:msxsl="urn:schemas-microsoft-com:xslt">
+
+ <xsl:output indent="yes" encoding="UTF-8" />
+
+ <!-- <xsl:key name="typeIndex" match="/reflection/types/type" use="@id" /> -->
+ <xsl:key name="defaultContructorIndex" match="/*/apis/api[apidata[@subgroup='constructor'] and not(parameters) and memberdata[@visibility='public']]" use="@id" />
+ <xsl:key name="typeIndex" match="/*/apis/api[apidata[@group='type']]" use="@id" />
+
+ <xsl:key name="settablePropertyIndex" match="/*/apis/api[apidata[@subgroup='property']][propertydata[@set='true']][(memberdata[@visibility='public'] and not(propertydata[@set-visibility!='public'])) or propertydata[@set-visibility='public']]" use="@id" />
+
+ <xsl:template match="/">
+ <reflection>
+
+ <!-- assemblies and namespaces get copied undisturbed -->
+ <xsl:copy-of select="/*/assemblies" />
+
+ <apis>
+ <xsl:apply-templates select="/*/apis/api" />
+ </apis>
+
+ </reflection>
+ </xsl:template>
+
+ <xsl:template match="api">
+ <xsl:choose>
+ <xsl:when test="apidata[@group='type']">
+ <xsl:call-template name="updateTypeNode"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:copy-of select="." />
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template name="GetContentProperty">
+ <xsl:if test="apidata[@subgroup='class' or @subgroup='structure']">
+ <xsl:variable name="contentPropertyName">
+ <xsl:value-of select="attributes/attribute[type[contains(@api,'.ContentPropertyAttribute')]]/argument/value"/>
+ </xsl:variable>
+ <xsl:if test="$contentPropertyName!=''">
+ <xsl:value-of select="concat('P:',substring-after(@id,'T:'),'.',$contentPropertyName)"/>
+ </xsl:if>
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template name="updateTypeNode">
+ <xsl:variable name="defaultConstructor">
+ <xsl:if test="apidata[@subgroup='class' or @subgroup='structure']">
+ <xsl:for-each select="elements/element">
+ <xsl:if test="key('defaultContructorIndex',@api)">
+ <xsl:value-of select="@api"/>
+ </xsl:if>
+ </xsl:for-each>
+ </xsl:if>
+ </xsl:variable>
+ <xsl:variable name="hasSettableProperties">
+ <xsl:if test="apidata[@subgroup='structure']">
+ <xsl:for-each select="elements/element">
+ <xsl:if test="key('settablePropertyIndex',@api)">true</xsl:if>
+ </xsl:for-each>
+ </xsl:if>
+ </xsl:variable>
+ <xsl:variable name="contentPropertyId">
+ <xsl:call-template name="GetContentProperty"/>
+ </xsl:variable>
+ <xsl:variable name="typeSubGroup">
+ <xsl:value-of select="apidata/@subgroup"/>
+ </xsl:variable>
+ <api>
+ <xsl:copy-of select="@*"/>
+ <xsl:for-each select="*">
+ <xsl:choose>
+ <xsl:when test="local-name()='typedata'">
+ <typedata>
+ <xsl:copy-of select="@*"/>
+ <xsl:if test="normalize-space($defaultConstructor)!=''">
+ <xsl:attribute name="defaultConstructor">
+ <xsl:value-of select="normalize-space($defaultConstructor)"/>
+ </xsl:attribute>
+ </xsl:if>
+ <xsl:if test="$contentPropertyId!=''">
+ <xsl:attribute name="contentProperty">
+ <xsl:value-of select="$contentPropertyId"/>
+ </xsl:attribute>
+ </xsl:if>
+ <xsl:if test="$typeSubGroup='structure' and normalize-space($hasSettableProperties)=''">
+ <xsl:attribute name="noSettableProperties">
+ <xsl:value-of select="'true'"/>
+ </xsl:attribute>
+ </xsl:if>
+ <xsl:copy-of select="*"/>
+ </typedata>
+ </xsl:when>
+ <xsl:when test="local-name()='family'">
+ <xsl:choose>
+ <xsl:when test="$contentPropertyId=''">
+ <family>
+ <xsl:for-each select="*">
+ <xsl:choose>
+ <xsl:when test="local-name()='ancestors'">
+ <ancestors>
+ <xsl:for-each select="type">
+ <xsl:variable name="ancestorContentPropertyId">
+ <xsl:for-each select="key('typeIndex', @api)">
+ <xsl:call-template name="GetContentProperty"/>
+ </xsl:for-each>
+ </xsl:variable>
+ <type>
+ <xsl:copy-of select="@*"/>
+ <xsl:if test="$ancestorContentPropertyId!=''">
+ <xsl:attribute name="contentProperty">
+ <xsl:value-of select="$ancestorContentPropertyId"/>
+ </xsl:attribute>
+ </xsl:if>
+ <xsl:copy-of select="*"/>
+ </type>
+ </xsl:for-each>
+ </ancestors>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:copy-of select="."/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:for-each>
+ </family>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:copy-of select="."/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:copy-of select="."/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:for-each>
+ </api>
+ </xsl:template>
+
+</xsl:stylesheet>
diff --git a/tools/Sandcastle/ProductionTransforms/ApplyPrototypeDocModel.xsl b/tools/Sandcastle/ProductionTransforms/ApplyPrototypeDocModel.xsl
new file mode 100644
index 0000000..c22626a
--- /dev/null
+++ b/tools/Sandcastle/ProductionTransforms/ApplyPrototypeDocModel.xsl
@@ -0,0 +1,259 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" version="1.1">
+
+ <xsl:output indent="yes" encoding="UTF-8" />
+
+ <xsl:param name="project" select="string('Project')" />
+
+ <xsl:key name="index" match="/*/apis/api" use="@id" />
+
+ <xsl:variable name="types">
+ <xsl:call-template name="types" />
+ </xsl:variable>
+
+ <xsl:template match="/">
+ <reflection>
+ <!--
+ <xsl:call-template name="types" />
+ -->
+ <xsl:apply-templates select="/*/assemblies" />
+ <xsl:apply-templates select="/*/apis" />
+ </reflection>
+ </xsl:template>
+
+
+ <xsl:template match="assemblies">
+ <xsl:copy-of select="." />
+ </xsl:template>
+
+ <xsl:template match="apis">
+ <apis>
+ <xsl:apply-templates select="api" />
+ <xsl:call-template name="projectTopic" />
+ </apis>
+ </xsl:template>
+
+
+ <!-- by default, an api is just copied and topicdata added -->
+ <xsl:template match="api">
+ <xsl:call-template name="apiTopic" />
+ </xsl:template>
+
+ <!-- for type apis, we also generate overload pages -->
+ <xsl:template match="api[apidata/@group='type']">
+ <!-- first reproduce the type API -->
+ <xsl:call-template name="apiTopic" />
+ <!-- now create overload APIs -->
+ <xsl:variable name="type" select="." />
+ <xsl:variable name="typeId" select="@id" />
+ <xsl:for-each select="msxsl:node-set($types)/type[@api=$typeId]/overload">
+ <api>
+ <xsl:attribute name="id">
+ <xsl:call-template name="overloadIdentifier">
+ <xsl:with-param name="typeId" select="$typeId" />
+ <xsl:with-param name="memberName" select="@name" />
+ </xsl:call-template>
+ </xsl:attribute>
+ <topicdata group="list" subgroup="overload" />
+ <apidata name="{@name}" group="member" subgroup="{@subgroup}" />
+ <containers>
+ <xsl:copy-of select="$type/containers/library"/>
+ <xsl:copy-of select="$type/containers/namespace"/>
+ <type api="{$typeId}">
+ <xsl:copy-of select="$type/containers/type"/>
+ </type>
+ </containers>
+ <elements>
+ <xsl:for-each select="member">
+ <element>
+ <xsl:copy-of select="@api|@display-api"/>
+ </element>
+ </xsl:for-each>
+ </elements>
+ </api>
+ </xsl:for-each>
+ <!--
+ <xsl:variable name="members" select="key('index',elements/element/@api)" />
+ <xsl:for-each select="$members">
+ <xsl:variable name="name" select="apidata/@name" />
+ <xsl:variable name="subgroup" select="apidata/@subgroup" />
+ <xsl:variable name="set" select="$members[apidata/@name=$name and apidata/@subgroup=$subgroup]" />
+ <xsl:if test="(count($set) &gt; 1) and (($set[containers/type/@api=$typeId][1]/@id)=@id)">
+ <api>
+ <xsl:attribute name="id">
+ <xsl:call-template name="overloadId">
+ <xsl:with-param name="memberId" select="@id" />
+ </xsl:call-template>
+ </xsl:attribute>
+ <topicdata group="list" />
+ <apidata name="{apidata/@name}" group="{apidata/@group}" subgroup="{apidata/@subgroup}" />
+ <containers>
+ <library assembly="{containers/library/@assembly}" module="{containers/library/@module}"/>
+ <namespace api="{containers/namespace/@api}" />
+ <type api="{containers/type/@api}" />
+ </containers>
+ <elements>
+ <xsl:for-each select="$set">
+ <element api="{@id}" />
+ </xsl:for-each>
+ </elements>
+ </api>
+ </xsl:if>
+ </xsl:for-each>
+ -->
+ </xsl:template>
+
+ <!-- for member apis, we add an overload element if the member is overloaded -->
+ <xsl:template match="api[apidata/@group='member']">
+ <xsl:variable name="typeId" select="containers/type/@api" />
+ <xsl:variable name="memberId" select="@id" />
+ <xsl:if test="not(key('index',$typeId)/apidata/@subgroup='enumeration')">
+ <api id="{$memberId}">
+ <topicdata group="api" />
+ <xsl:copy-of select="*" />
+ <xsl:variable name="overloadId" select="msxsl:node-set($types)/type[@api=$typeId]//member[@api=$memberId]/parent::overload/@api" />
+ <xsl:if test="$overloadId">
+ <overload api="{$overloadId}" />
+ </xsl:if>
+ </api>
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template name="apiTopic">
+ <api id="{@id}">
+ <topicdata group="api" />
+ <xsl:copy-of select="*" />
+ </api>
+ </xsl:template>
+
+ <xsl:template name="projectTopic">
+ <api id="R:{$project}">
+ <topicdata group="list" subgroup="namespaces" />
+ <elements>
+ <xsl:for-each select="/*/apis/api[apidata/@group='namespace']">
+ <element api="{@id}" />
+ </xsl:for-each>
+ </elements>
+ </api>
+ </xsl:template>
+
+ <!--
+ <xsl:template name="overloadId">
+ <xsl:param name="memberId" />
+ <xsl:text>Overload:</xsl:text>
+ <xsl:variable name="noParameters">
+ <xsl:choose>
+ <xsl:when test="contains($memberId,'(')">
+ <xsl:value-of select="substring-before($memberId,'(')" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$memberId" />
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:variable name="noGeneric">
+ <xsl:choose>
+ <xsl:when test="contains($noParameters,'``')">
+ <xsl:value-of select="substring-before($noParameters,'``')" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$noParameters" />
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:value-of select="substring($noGeneric,3)" />
+ </xsl:template>
+ -->
+
+ <!-- logic to construct an in-memory tree that represents types and members organized into overload sets -->
+
+ <!-- create a list of types with member elements organized by overload set -->
+ <xsl:template name="types">
+ <xsl:for-each select="/*/apis/api[apidata/@group='type']">
+ <type api="{@id}">
+ <xsl:call-template name="overloads" />
+ </type>
+ </xsl:for-each>
+ </xsl:template>
+
+ <!-- organize member list into overload sets -->
+ <!-- overload sets share a name and subgroup -->
+ <xsl:template name="overloads">
+ <xsl:variable name="typeId" select="@id" />
+ <xsl:variable name="members">
+ <xsl:call-template name="members" />
+ </xsl:variable>
+ <xsl:for-each select="msxsl:node-set($members)/member">
+ <xsl:variable name="name" select="@name" />
+ <!-- on the first occurence of a member name... -->
+ <xsl:if test="not(preceding-sibling::member[@name=$name])">
+ <xsl:choose>
+ <!-- ...if there are subsequent members with that name, create an overload set -->
+ <xsl:when test="following-sibling::member[@name=$name]">
+ <overload name="{$name}" subgroup="{@subgroup}">
+ <xsl:attribute name="api">
+ <xsl:call-template name="overloadIdentifier">
+ <xsl:with-param name="typeId" select="$typeId" />
+ <xsl:with-param name="memberName" select="$name" />
+ </xsl:call-template>
+ </xsl:attribute>
+ <xsl:for-each select="../member[@name=$name]">
+ <member>
+ <xsl:copy-of select="@api|@display-api"/>
+ </member>
+ </xsl:for-each>
+ </overload>
+ </xsl:when>
+ <!-- otherwise, just copy the member entry -->
+ <xsl:otherwise>
+ <member api="{@api}" />
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:if>
+ </xsl:for-each>
+ </xsl:template>
+
+ <!-- collect list of members for a given type -->
+ <!-- each member lists api id, name, subgroup, and display-api -->
+ <xsl:template name="members">
+ <xsl:for-each select="elements/element">
+ <member api="{@api}">
+ <xsl:if test="@display-api">
+ <xsl:attribute name="display-api">
+ <xsl:value-of select="@display-api"/>
+ </xsl:attribute>
+ </xsl:if>
+ <xsl:choose>
+ <xsl:when test="apidata">
+ <xsl:attribute name="name">
+ <xsl:value-of select="apidata/@name" />
+ </xsl:attribute>
+ <xsl:attribute name="subgroup">
+ <xsl:value-of select="apidata/@subgroup" />
+ </xsl:attribute>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:variable name="api" select="key('index',@api)" />
+ <xsl:attribute name="name">
+ <xsl:value-of select="$api/apidata/@name"/>
+ </xsl:attribute>
+ <xsl:attribute name="subgroup">
+ <xsl:value-of select="$api/apidata/@subgroup"/>
+ </xsl:attribute>
+ </xsl:otherwise>
+ </xsl:choose>
+ </member>
+ </xsl:for-each>
+ </xsl:template>
+
+ <!-- given a type and a member name, construct an overload identifier -->
+ <xsl:template name="overloadIdentifier">
+ <xsl:param name="typeId" />
+ <xsl:param name="memberName" />
+ <xsl:text>Overload:</xsl:text>
+ <xsl:value-of select="substring($typeId,3)"/>
+ <xsl:text>.</xsl:text>
+ <xsl:value-of select="$memberName"/>
+ </xsl:template>
+
+</xsl:stylesheet>
diff --git a/tools/Sandcastle/ProductionTransforms/ApplyVSDocModel.xsl b/tools/Sandcastle/ProductionTransforms/ApplyVSDocModel.xsl
new file mode 100644
index 0000000..18b3aa3
--- /dev/null
+++ b/tools/Sandcastle/ProductionTransforms/ApplyVSDocModel.xsl
@@ -0,0 +1,767 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt"
+ xmlns:ms="urn:schemas-microsoft-com:xslt"
+ exclude-result-prefixes="ms"
+ version="1.1">
+
+ <xsl:output indent="yes" encoding="UTF-8" />
+ <xsl:param name="derivedTypesLimit" />
+ <xsl:param name="project" />
+
+ <!-- Set to true for vs2005; set to false for vsorcas/prototype. -->
+ <xsl:param name="IncludeAllMembersTopic" select="'false'" />
+
+ <!-- If member list topics handle overloads with one row that points to an overload topic, set IncludeInheritedOverloadTopics to false. -->
+ <!-- If member list topics show a separate row for each overload signature, set IncludeInheritedOverloadTopics to false. -->
+ <xsl:param name="IncludeInheritedOverloadTopics" select="'true'" />
+
+ <xsl:key name="index" match="/reflection/apis/api" use="@id" />
+
+ <xsl:template match="/">
+ <reflection>
+ <xsl:apply-templates select="/reflection/assemblies" />
+ <xsl:apply-templates select="/reflection/apis" />
+ </reflection>
+ </xsl:template>
+
+ <xsl:template match="assemblies">
+ <xsl:copy-of select="." />
+ </xsl:template>
+
+ <xsl:template match="apis">
+ <apis>
+ <xsl:apply-templates select="api" />
+ <xsl:if test="normalize-space($project)">
+ <xsl:call-template name="projectTopic" />
+ </xsl:if>
+ </apis>
+ </xsl:template>
+
+ <!-- Process a generic API (for namespaces and members; types and overloads are handled explicitly below) -->
+
+ <xsl:template match="api">
+ <xsl:call-template name="updateApiNode" />
+ </xsl:template>
+
+ <xsl:template match="api[apidata/@group='member']">
+ <xsl:call-template name="updateApiNode" />
+ </xsl:template>
+
+ <xsl:template name="updateApiNode">
+ <xsl:variable name="name" select="apidata/@name"/>
+ <xsl:variable name="subgroup" select="apidata/@subgroup"/>
+ <xsl:variable name="subsubgroup" select="apidata/@subsubgroup"/>
+ <xsl:variable name="typeId" select="containers/type/@api"/>
+ <xsl:variable name="isEII" select="proceduredata/@eii"/>
+ <api>
+ <xsl:copy-of select="@*"/>
+ <topicdata group="api">
+ <xsl:if test="key('index',containers/type/@api)[apidata/@subgroup='enumeration']">
+ <!-- enum members do not get separate topics; mark them so they are excluded from the manifest -->
+ <xsl:attribute name="notopic"/>
+ </xsl:if>
+ </topicdata>
+ <xsl:for-each select="*">
+ <xsl:choose>
+ <xsl:when test="local-name(.)='containers'">
+ <xsl:variable name="assembly" select="library/@assembly"/>
+ <xsl:choose>
+ <xsl:when test="not(/*/assemblies/assembly[@name=$assembly]/attributes/attribute[type/@api='T:System.Security.AllowPartiallyTrustedCallersAttribute'])">
+ <containers>
+ <library>
+ <xsl:copy-of select="library/@*"/>
+ <noAptca/>
+ </library>
+ <xsl:copy-of select="namespace"/>
+ <xsl:copy-of select="type"/>
+ </containers>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:copy-of select="."/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ <xsl:when test="local-name(.)='memberdata'">
+ <xsl:choose>
+ <xsl:when test="$isEII='true'">
+ <xsl:copy-of select="."/>
+ </xsl:when>
+ <xsl:otherwise>
+ <memberdata>
+ <xsl:copy-of select="@*"/>
+ <!-- if the member is overloaded, add @overload = id of overload topic, if any -->
+ <xsl:choose>
+ <!-- skip this processing for members that cannot be overloaded -->
+ <xsl:when test="$subgroup='field'"/>
+ <xsl:otherwise>
+ <xsl:variable name="siblingElements" select="key('index',$typeId)/elements"/>
+ <xsl:variable name="siblingApiInfo" select="key('index',$siblingElements/element[not(apidata)]/@api) | $siblingElements/element[apidata]" />
+ <xsl:variable name="overloadSet" select="$siblingApiInfo[not(proceduredata/@eii='true') and apidata[@name=$name and @subgroup=$subgroup and (@subsubgroup=$subsubgroup or (not(boolean($subsubgroup)) and not(@subsubgroup)))]]" />
+ <xsl:variable name="signatureSet">
+ <xsl:call-template name="GetSignatureSet">
+ <xsl:with-param name="name" select="$name" />
+ <xsl:with-param name="overloadSet" select="$overloadSet"/>
+ <xsl:with-param name="typeId" select="$typeId"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:if test="count(msxsl:node-set($signatureSet)/*) &gt; 1">
+ <!-- the api is overloaded, so add @overload = idOfOverloadTopic -->
+ <xsl:attribute name="overload">
+ <xsl:call-template name="overloadId">
+ <xsl:with-param name="typeId" select="$typeId"/>
+ <xsl:with-param name="name" select="$name"/>
+ <xsl:with-param name="subgroup" select="$subgroup"/>
+ <xsl:with-param name="subsubgroup" select="$subsubgroup"/>
+ </xsl:call-template>
+ </xsl:attribute>
+ </xsl:if>
+
+ </xsl:otherwise>
+ </xsl:choose>
+ <!-- memberdata shouldn't have any children, but copy just in case -->
+ <xsl:copy-of select="*"/>
+ </memberdata>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:copy-of select="."/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:for-each>
+ </api>
+ </xsl:template>
+
+ <!-- Special logic for type APIs -->
+
+ <xsl:template name="UpdateTypeApiNode">
+ <xsl:param name="derivedTypesTopicId" />
+ <xsl:param name="allMembersTopicId" />
+ <xsl:variable name="typeId" select="@id"/>
+ <api>
+ <xsl:copy-of select="@*"/>
+ <xsl:choose>
+ <xsl:when test="normalize-space($allMembersTopicId)">
+ <topicdata group="api" allMembersTopicId="{$allMembersTopicId}"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <topicdata group="api" />
+ </xsl:otherwise>
+ </xsl:choose>
+
+ <xsl:for-each select="*">
+ <xsl:choose>
+ <xsl:when test="self::elements">
+ <xsl:choose>
+ <xsl:when test="../apidata/@subgroup='enumeration'">
+ <xsl:copy-of select="."/>
+ </xsl:when>
+ <xsl:when test="not(normalize-space($allMembersTopicId))">
+ <xsl:if test="element">
+ <xsl:call-template name="memberListElements">
+ <xsl:with-param name="typeId" select="$typeId"/>
+ </xsl:call-template>
+ </xsl:if>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:when>
+ <xsl:when test="local-name(.)='family' and $derivedTypesTopicId!=''">
+ <family>
+ <!-- copy the ancestors node -->
+ <xsl:copy-of select="ancestors"/>
+ <!-- Modify the descendents node -->
+ <descendents>
+ <xsl:attribute name="derivedTypes">
+ <xsl:value-of select="$derivedTypesTopicId"/>
+ </xsl:attribute>
+ <type>
+ <xsl:attribute name="api">
+ <xsl:value-of select="$derivedTypesTopicId"/>
+ </xsl:attribute>
+ <xsl:attribute name="ref">
+ <xsl:value-of select="'true'"/>
+ </xsl:attribute>
+ </type>
+ </descendents>
+ </family>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:copy-of select="."/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:for-each>
+ </api>
+ </xsl:template>
+
+ <!-- Type logic; types get a lot of massaging to create member list pages, overload pages, etc. -->
+
+ <xsl:template match="api[apidata/@group='type']">
+
+ <xsl:variable name="typeId" select="@id" />
+
+ <xsl:variable name="allMembersTopicId">
+ <xsl:if test="$IncludeAllMembersTopic!='false' and (count(elements/*) &gt; 0) and apidata[not(@subgroup='enumeration')]">
+ <xsl:value-of select="concat('AllMembers.', $typeId)"/>
+ </xsl:if>
+ </xsl:variable>
+
+ <xsl:variable name="derivedTypesTopicId">
+ <xsl:if test="count(family/descendents/*) &gt; $derivedTypesLimit">
+ <xsl:value-of select="concat('DerivedTypes.', $typeId)"/>
+ </xsl:if>
+ </xsl:variable>
+
+ <!-- a topic for the type overview -->
+ <xsl:call-template name="UpdateTypeApiNode">
+ <xsl:with-param name="derivedTypesTopicId" select="$derivedTypesTopicId" />
+ <xsl:with-param name="allMembersTopicId" select="$allMembersTopicId" />
+ </xsl:call-template>
+
+ <!-- enumerations don't get all these extra topics -->
+ <xsl:if test="not(apidata[@subgroup='enumeration'])">
+
+ <!-- derived types topic -->
+ <xsl:if test="$derivedTypesTopicId!=''">
+ <api>
+ <xsl:attribute name="id">
+ <xsl:text>DerivedTypes.</xsl:text>
+ <xsl:value-of select="$typeId"/>
+ </xsl:attribute>
+ <topicdata name="{apidata/@name}" group="list" subgroup="DerivedTypeList" typeTopicId="{@id}" allMembersTopicId="{$allMembersTopicId}" />
+ <xsl:copy-of select="apidata" />
+ <xsl:copy-of select="typedata" />
+ <xsl:copy-of select="templates" />
+ <elements>
+ <xsl:for-each select="family/descendents/*">
+ <element api="{@api}" />
+ </xsl:for-each>
+ </elements>
+ <xsl:copy-of select="containers" />
+ </api>
+ </xsl:if>
+
+ <!-- all members topic -->
+ <xsl:if test="$allMembersTopicId!=''">
+ <api>
+ <xsl:attribute name="id">
+ <xsl:text>AllMembers.</xsl:text>
+ <xsl:value-of select="$typeId"/>
+ </xsl:attribute>
+ <topicdata name="{apidata/@name}" group="list" subgroup="members" typeTopicId="{@id}" />
+ <xsl:copy-of select="apidata" />
+ <xsl:copy-of select="typedata" />
+ <xsl:copy-of select="templates" />
+ <!-- elements -->
+ <xsl:for-each select="elements[element]">
+ <xsl:call-template name="memberListElements">
+ <xsl:with-param name="typeId" select="$typeId"/>
+ </xsl:call-template>
+ </xsl:for-each>
+ <xsl:copy-of select="containers" />
+ </api>
+ </xsl:if>
+
+ <!-- method/operator list topic -->
+ <!-- pass in $declaredMembers and $members so subsubgroup=operator is not exclude -->
+ <xsl:variable name="declaredPrefix" select="concat(substring-after($typeId,':'), '.')"/>
+ <xsl:call-template name="AddMemberlistAPI">
+ <xsl:with-param name="subgroup">method</xsl:with-param>
+ <xsl:with-param name="topicSubgroup">Methods</xsl:with-param>
+ <xsl:with-param name="typeId" select="$typeId" />
+ <xsl:with-param name="declaredMembers" select="key('index',elements/element[not(apidata)][starts-with(substring-after(@api,':'), $declaredPrefix)]/@api)[apidata[@subgroup='method']]
+ | elements/element[starts-with(substring-after(@api,':'), $declaredPrefix)][apidata[@subgroup='method']]"/>
+ <xsl:with-param name="members" select="key('index',elements/element[not(apidata)]/@api)[apidata[@subgroup='method']]
+ | elements/element[apidata[@subgroup='method']]"/>
+ </xsl:call-template>
+
+ <!-- propety list topic -->
+ <xsl:call-template name="AddMemberlistAPI">
+ <xsl:with-param name="subgroup">property</xsl:with-param>
+ <xsl:with-param name="topicSubgroup">Properties</xsl:with-param>
+ <xsl:with-param name="typeId" select="$typeId" />
+ </xsl:call-template>
+
+ <!-- event list topic -->
+ <xsl:call-template name="AddMemberlistAPI">
+ <xsl:with-param name="subgroup">event</xsl:with-param>
+ <xsl:with-param name="topicSubgroup">Events</xsl:with-param>
+ <xsl:with-param name="typeId" select="$typeId" />
+ </xsl:call-template>
+
+ <!-- field list topic -->
+ <xsl:call-template name="AddMemberlistAPI">
+ <xsl:with-param name="subgroup">field</xsl:with-param>
+ <xsl:with-param name="topicSubgroup">Fields</xsl:with-param>
+ <xsl:with-param name="typeId" select="$typeId" />
+ </xsl:call-template>
+
+ <!-- attached properties topic -->
+ <xsl:call-template name="AddMemberlistAPI">
+ <xsl:with-param name="subsubgroup">attachedProperty</xsl:with-param>
+ <xsl:with-param name="topicSubgroup">AttachedProperties</xsl:with-param>
+ <xsl:with-param name="typeId" select="$typeId" />
+ </xsl:call-template>
+
+ <!-- attached events topic -->
+ <xsl:call-template name="AddMemberlistAPI">
+ <xsl:with-param name="subsubgroup">attachedEvent</xsl:with-param>
+ <xsl:with-param name="topicSubgroup">AttachedEvents</xsl:with-param>
+ <xsl:with-param name="typeId" select="$typeId" />
+ </xsl:call-template>
+
+ <!-- overload topics -->
+ <xsl:call-template name="overloadTopics">
+ <xsl:with-param name="allMembersTopicId" select="$allMembersTopicId"/>
+ </xsl:call-template>
+
+ </xsl:if>
+
+ </xsl:template>
+
+ <!-- overload topics -->
+
+ <xsl:template name="overloadTopics">
+ <xsl:param name="allMembersTopicId"/>
+ <xsl:variable name="typeId" select="@id"/>
+ <xsl:variable name="members" select="key('index',elements/element[not(apidata)]/@api) | elements/element[apidata]" />
+ <xsl:variable name="declaredPrefix" select="concat(substring($typeId,2), '.')"/>
+
+ <xsl:for-each select="$members">
+ <xsl:variable name="name" select="apidata/@name" />
+ <xsl:variable name="memberId" select="@id | @api"/>
+ <xsl:variable name="subgroup" select="apidata/@subgroup" />
+ <xsl:variable name="subsubgroup" select="apidata/@subsubgroup" />
+
+ <!-- EII members are not treated as overloads -->
+ <xsl:if test="not(proceduredata/@eii='true')">
+ <!-- get the set of non-EII members with same name and subgroup -->
+ <xsl:variable name="overloadSet" select="$members[not(proceduredata/@eii='true') and apidata[@name=$name and @subgroup=$subgroup and (@subsubgroup=$subsubgroup or (not(boolean($subsubgroup)) and not(@subsubgroup)))]]" />
+
+ <!-- are there any declared members in the overload set? -->
+ <xsl:variable name="declaredMembers" select="$overloadSet[starts-with(substring(@id,2),$declaredPrefix)]" />
+
+ <!-- if more than one member in overloadSet, add an overload topic if necessary -->
+ <xsl:if test="(count($overloadSet) &gt; 1) and $overloadSet[1][@id=$memberId or @api=$memberId]">
+ <!-- When merging multiple versions, an overload set may have multiple members with the same signature,
+ e.g. when one version inherits a member and another version overrides it.
+ We want an overload topic only when there are multiple signatures. -->
+ <!-- get the set of unique signatures for this overload set -->
+ <xsl:variable name="signatureSet">
+ <xsl:call-template name="GetSignatureSet">
+ <xsl:with-param name="overloadSet" select="$overloadSet"/>
+ <xsl:with-param name="typeId" select="$typeId"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:choose>
+ <!-- don't need an overload topic if only one signature -->
+ <xsl:when test="count(msxsl:node-set($signatureSet)/*) &lt; 2"/>
+ <!-- don't need an overload topic if all overloads are inherited and config'd to omit overload topics when all are inherited -->
+ <xsl:when test="(not(boolean($declaredMembers)) and $IncludeInheritedOverloadTopics='false')"/>
+ <xsl:otherwise>
+ <api>
+ <xsl:attribute name="id">
+ <xsl:call-template name="overloadId">
+ <xsl:with-param name="typeId" select="$typeId"/>
+ <xsl:with-param name="name" select="$name"/>
+ <xsl:with-param name="subgroup" select="$subgroup"/>
+ <xsl:with-param name="subsubgroup" select="$subsubgroup"/>
+ </xsl:call-template>
+ </xsl:attribute>
+ <topicdata name="{apidata/@name}" group="list" subgroup="overload" memberSubgroup="{$subgroup}" pseudo="true" allMembersTopicId="{$allMembersTopicId}">
+ <xsl:if test="not(boolean($declaredMembers))">
+ <xsl:attribute name="allInherited">true</xsl:attribute>
+ </xsl:if>
+ </topicdata>
+ <xsl:copy-of select="apidata" />
+ <!-- elements -->
+ <elements>
+ <xsl:for-each select="msxsl:node-set($signatureSet)/*">
+ <xsl:copy-of select="."/>
+ </xsl:for-each>
+ </elements>
+ <!-- containers -->
+ <xsl:choose>
+ <xsl:when test="boolean($declaredMembers)">
+ <xsl:copy-of select="$declaredMembers[1]/containers"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <containers>
+ <xsl:copy-of select="key('index',$typeId)/containers/library"/>
+ <xsl:copy-of select="key('index',$typeId)/containers/namespace"/>
+ <type api="{$typeId}"/>
+ </containers>
+ </xsl:otherwise>
+ </xsl:choose>
+ </api>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:if>
+ </xsl:if>
+ </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template name="WriteElementNode">
+ <xsl:param name="typeId"/>
+ <xsl:choose>
+ <xsl:when test="local-name()='element'">
+ <xsl:copy-of select="."/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:variable name="elementId" select="@id"/>
+ <xsl:copy-of select="key('index', $typeId)/elements/element[@api=$elementId]"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template name="GetSignatureSet">
+ <xsl:param name="name" select="apidata/@name" />
+ <xsl:param name="overloadSet"/>
+ <xsl:param name="typeId"/>
+
+ <xsl:choose>
+ <xsl:when test="count($overloadSet) = 1">
+ <xsl:for-each select="$overloadSet">
+ <xsl:call-template name="WriteElementNode">
+ <xsl:with-param name="typeId" select="$typeId"/>
+ </xsl:call-template>
+ </xsl:for-each>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:for-each select="$overloadSet">
+ <xsl:sort select="count(parameters/parameter)"/>
+ <xsl:sort select="key('index', parameters/parameter[1]//type[1]/@api)/apidata/@name"/>
+ <xsl:variable name="memberId" select="@id | @api"/>
+ <xsl:variable name="signature">
+ <xsl:call-template name="GetSignature">
+ <xsl:with-param name="name" select="$name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="sameParamSignatureSet" select="$overloadSet[contains(@id|@api,$signature) and string-length(substring-after(@id|@api,$signature))=0]"/>
+ <!-- make sure all elements in the sameParamSignatureSet have the same return value -->
+ <xsl:variable name="returnsType" select="string(returns//type[1]/@api)"/>
+ <xsl:variable name="sameSignatureSet" select="$sameParamSignatureSet[(returns//type[1][@api=$returnsType]) or ($returnsType='' and not(returns//type))]"/>
+ <xsl:choose>
+ <xsl:when test="count(msxsl:node-set($sameSignatureSet)) &gt; 1">
+ <xsl:if test="$sameSignatureSet[1][@id=$memberId or @api=$memberId]">
+ <!-- $sameSignatureSet is set of api nodes; for version check we need the corresponding set of element nodes -->
+ <xsl:variable name="elementSet">
+ <xsl:for-each select="$sameSignatureSet">
+ <xsl:call-template name="WriteElementNode">
+ <xsl:with-param name="typeId" select="$typeId"/>
+ </xsl:call-template>
+ </xsl:for-each>
+ </xsl:variable>
+ <!-- The first versions/versions node determines the primary version group, e.g. 'netfw'. -->
+ <xsl:variable name="primaryVersionGroup" select="versions/versions[1]/@name"/>
+ <!-- The primary element is the one with the most recent version for the primary version group. -->
+ <xsl:variable name="primaryVersionMemberId">
+ <xsl:call-template name="GetSignatureWithLatestVersion">
+ <xsl:with-param name="versionGroup" select="$primaryVersionGroup"/>
+ <xsl:with-param name="signatureset" select="$elementSet"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="primaryMemberId">
+ <xsl:choose>
+ <xsl:when test="normalize-space($primaryVersionMemberId)!=''">
+ <xsl:value-of select="normalize-space(substring-before($primaryVersionMemberId,';'))"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$sameSignatureSet[1]/@id|@api"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:for-each select="$sameSignatureSet[@id=$primaryMemberId or @api=$primaryMemberId]">
+ <element api="{$primaryMemberId}" signatureset="">
+ <!-- copy attributes and innerxml from the original element node -->
+ <xsl:choose>
+ <xsl:when test="local-name()='element'">
+ <xsl:copy-of select="@*"/>
+ <xsl:copy-of select="*"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:copy-of select="key('index', $typeId)/elements/element[@api=$primaryMemberId]/@*"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ <!-- for the secondary version groups, copy in the signatureset's latest member (if different from primary member) -->
+ <xsl:call-template name="nonPrimaryVersionElements">
+ <xsl:with-param name="usedIds" select="concat($primaryMemberId,';')"/>
+ <xsl:with-param name="elementSet" select="$elementSet"/>
+ <xsl:with-param name="sameSignatureSet" select="$sameSignatureSet"/>
+ <xsl:with-param name="typeId" select="$typeId"/>
+ </xsl:call-template>
+ </element>
+ </xsl:for-each>
+ </xsl:if>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="WriteElementNode">
+ <xsl:with-param name="typeId" select="$typeId"/>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:for-each>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template name="nonPrimaryVersionElements">
+ <xsl:param name="usedIds"/>
+ <xsl:param name="elementSet"/>
+ <xsl:param name="sameSignatureSet"/>
+ <xsl:param name="typeId"/>
+
+ <xsl:if test="count(versions/versions)&gt;1">
+ <xsl:variable name="versionGroupId2" select="versions/versions[2]/@name"/>
+ <xsl:variable name="versionMemberIdSet2">
+ <xsl:call-template name="GetSignatureWithLatestVersion">
+ <xsl:with-param name="versionGroup" select="$versionGroupId2"/>
+ <xsl:with-param name="signatureset" select="$elementSet"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="versionMemberId2">
+ <xsl:value-of select="normalize-space(substring-before($versionMemberIdSet2,';'))"/>
+ </xsl:variable>
+ <xsl:if test="(normalize-space($versionMemberId2)!='') and not(contains($usedIds,concat($versionMemberId2,';')))">
+ <xsl:for-each select="$sameSignatureSet[@id=$versionMemberId2 or @api=$versionMemberId2]">
+ <xsl:call-template name="WriteElementNode">
+ <xsl:with-param name="typeId" select="$typeId"/>
+ </xsl:call-template>
+ </xsl:for-each>
+ </xsl:if>
+
+ <xsl:if test="count(versions/versions)&gt;2">
+ <xsl:variable name="usedIds2" select="concat($usedIds,$versionMemberId2,';')"/>
+ <xsl:variable name="versionGroupId3" select="versions/versions[3]/@name"/>
+ <xsl:variable name="versionMemberIdSet3">
+ <xsl:call-template name="GetSignatureWithLatestVersion">
+ <xsl:with-param name="versionGroup" select="$versionGroupId3"/>
+ <xsl:with-param name="signatureset" select="$elementSet"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="versionMemberId3">
+ <xsl:value-of select="normalize-space(substring-before($versionMemberIdSet3,';'))"/>
+ </xsl:variable>
+ <xsl:if test="(normalize-space($versionMemberId3)!='') and not(contains($usedIds2,concat($versionMemberId3,';')))">
+ <xsl:for-each select="$sameSignatureSet[@id=$versionMemberId3 or @api=$versionMemberId3]">
+ <xsl:call-template name="WriteElementNode">
+ <xsl:with-param name="typeId" select="$typeId"/>
+ </xsl:call-template>
+ </xsl:for-each>
+ </xsl:if>
+ </xsl:if>
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template name="GetSignatureWithLatestVersion">
+ <xsl:param name="versionGroup"/>
+ <xsl:param name="signatureset"/>
+ <xsl:for-each select="msxsl:node-set($signatureset)/*[@*[local-name()=$versionGroup]]">
+ <xsl:variable name="currVersion" select="@*[local-name()=$versionGroup]"/>
+ <xsl:variable name="isLatest">
+ <xsl:call-template name="IsLatestVersion">
+ <xsl:with-param name="version" select="$currVersion"/>
+ <xsl:with-param name="versionGroup" select="$versionGroup"/>
+ <xsl:with-param name="signatureset" select="$signatureset"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <!-- IsLatestVersion returns '' if this is the latest version number -->
+ <xsl:if test="normalize-space($isLatest)=''"><xsl:value-of select="@api"/><xsl:text>;</xsl:text></xsl:if>
+ </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template name="IsLatestVersion">
+ <xsl:param name="version"/>
+ <xsl:param name="versionGroup"/>
+ <xsl:param name="signatureset"/>
+ <!-- loop through the versions; output is '' if there are no lower versions -->
+ <xsl:for-each select="msxsl:node-set($signatureset)/*[@*[local-name()=$versionGroup]]">
+ <xsl:variable name="currVersion" select="@*[local-name()=$versionGroup]"/>
+ <xsl:if test="ms:string-compare($currVersion, $version) = 1">false</xsl:if>
+ </xsl:for-each>
+ </xsl:template>
+
+ <!-- -->
+ <xsl:template name="GetSignature">
+ <xsl:param name="name" />
+ <xsl:param name="memberId" select="@id | @api"/>
+ <xsl:variable name="paramString" select="substring-after($memberId,'(')"/>
+ <xsl:variable name="tickString" select="substring-after($memberId,'``')"/>
+ <xsl:variable name="memberName">
+ <xsl:choose>
+ <xsl:when test="$name='.ctor' or $name='.cctor'">ctor</xsl:when>
+ <!-- for explicit interface implementation members, return the membername with # instead of ., so it matches cref ids -->
+ <xsl:when test="memberdata[@visibility='private'] and proceduredata[@virtual = 'true']">
+ <xsl:value-of select="translate($name,'.','#')"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$name"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:choose>
+ <xsl:when test="string-length($tickString) &gt; string-length($paramString)">
+ <xsl:value-of select="concat('.',$memberName,'``',$tickString)"/>
+ </xsl:when>
+ <xsl:when test="boolean($paramString)">
+ <xsl:value-of select="concat('.',$memberName,'(',$paramString)"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="concat('.',$memberName)"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <!-- member list topics -->
+
+ <xsl:template name="AddMemberlistAPI">
+ <xsl:param name="subgroup"/>
+ <xsl:param name="subsubgroup"/>
+ <xsl:param name="topicSubgroup"/>
+ <xsl:param name="typeId" />
+ <xsl:param name="declaredPrefix" select="concat(substring-after($typeId,':'), '.')"/>
+ <!-- get the type's declared members for this subgroup -->
+ <xsl:param name="declaredMembers" select="key('index',elements/element[not(apidata)][starts-with(substring-after(@api,':'), $declaredPrefix)]/@api)[apidata[($subgroup='' and @subsubgroup=$subsubgroup) or ($subsubgroup='' and not(@subsubgroup) and @subgroup=$subgroup)]]
+ | elements/element[starts-with(substring-after(@api,':'), $declaredPrefix)][apidata[($subgroup='' and @subsubgroup=$subsubgroup) or ($subsubgroup='' and not(@subsubgroup) and @subgroup=$subgroup)]]"/>
+ <!-- get all the type's members for this subgroup -->
+ <xsl:param name="members" select="key('index',elements/element[not(apidata)]/@api)[apidata[($subgroup='' and @subsubgroup=$subsubgroup) or ($subsubgroup='' and not(@subsubgroup) and @subgroup=$subgroup)]]
+ | elements/element[apidata[($subgroup='' and @subsubgroup=$subsubgroup) or ($subsubgroup='' and not(@subsubgroup) and @subgroup=$subgroup)]]"/>
+
+ <!-- add a member list topic only if the type has declared members -->
+ <xsl:if test="count($declaredMembers) &gt; 0">
+ <api>
+ <xsl:attribute name="id">
+ <xsl:value-of select="concat($topicSubgroup, '.', $typeId)"/>
+ </xsl:attribute>
+ <topicdata name="{apidata/@name}" group="list" subgroup="{$topicSubgroup}">
+ <xsl:if test="boolean($subsubgroup)">
+ <xsl:attribute name="subsubgroup">
+ <xsl:value-of select="$topicSubgroup"/>
+ </xsl:attribute>
+ </xsl:if>
+ <xsl:attribute name="typeTopicId">
+ <xsl:value-of select="$typeId"/>
+ </xsl:attribute>
+ </topicdata>
+ <xsl:copy-of select="apidata" />
+ <xsl:copy-of select="typedata" />
+ <xsl:copy-of select="templates" />
+ <!-- elements -->
+ <xsl:call-template name="memberListElements">
+ <xsl:with-param name="members" select="$members"/>
+ <xsl:with-param name="typeId" select="$typeId"/>
+ </xsl:call-template>
+ <xsl:copy-of select="containers" />
+ </api>
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template name="memberListElements">
+ <xsl:param name="members" select="key('index',element[not(apidata)]/@api) | element[apidata]" />
+ <xsl:param name="typeId" />
+ <xsl:variable name="declaredPrefix" select="concat(substring($typeId,2), '.')"/>
+
+ <elements>
+ <xsl:for-each select="$members">
+ <xsl:variable name="name" select="apidata/@name" />
+ <xsl:variable name="subgroup" select="apidata/@subgroup" />
+ <xsl:variable name="subsubgroup" select="apidata/@subsubgroup" />
+ <xsl:variable name="memberId" select="@id | @api"/>
+
+ <xsl:choose>
+ <!-- EII members are not treated as overloads -->
+ <xsl:when test="proceduredata/@eii='true'">
+ <xsl:call-template name="WriteElementNode">
+ <xsl:with-param name="typeId" select="$typeId"/>
+ </xsl:call-template>
+ </xsl:when>
+
+ <!-- field members cannot be overloaded, so skip the overload logic and just write the element node -->
+ <xsl:when test="$subgroup='field'">
+ <xsl:call-template name="WriteElementNode">
+ <xsl:with-param name="typeId" select="$typeId"/>
+ </xsl:call-template>
+ </xsl:when>
+
+ <!-- for non-EII members, handle overloads and signature sets -->
+ <xsl:otherwise>
+ <!-- get the set of overloads: non-EII members with same name and subgroup -->
+ <xsl:variable name="overloadSet" select="$members[not(proceduredata/@eii='true') and apidata[@name=$name and @subgroup=$subgroup and (@subsubgroup=$subsubgroup or (not(boolean($subsubgroup)) and not(@subsubgroup)))]]"/>
+
+ <!-- are there any declared members in the overload set? -->
+ <xsl:variable name="declaredMembers" select="$overloadSet[starts-with(substring(@id,2),$declaredPrefix)]" />
+
+ <xsl:variable name="signatureSet">
+ <xsl:call-template name="GetSignatureSet">
+ <xsl:with-param name="overloadSet" select="$overloadSet"/>
+ <xsl:with-param name="typeId" select="$typeId"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <!-- make sure we add to the list only once -->
+ <xsl:if test="$overloadSet[1][@id=$memberId or @api=$memberId]">
+ <!-- When merging multiple versions, an overload set may have multiple members with the same signature,
+ e.g. when one version inherits a member and another version overrides it.
+ We want an overload topic only when there are multiple signatures. -->
+ <!-- get the set of unique signatures for this overload set -->
+ <!--
+ -->
+ <xsl:choose>
+ <!-- don't need an overload topic if only one signature -->
+ <xsl:when test="count(msxsl:node-set($signatureSet)/*) = 1">
+ <xsl:copy-of select="msxsl:node-set($signatureSet)/*"/>
+ </xsl:when>
+ <!-- just copy the elements if all overloads are inherited and config'd to omit overload topics when all are inherited -->
+ <xsl:when test="(not(boolean($declaredMembers)) and $IncludeInheritedOverloadTopics='false')">
+ <xsl:copy-of select="msxsl:node-set($signatureSet)/*"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <element>
+ <xsl:attribute name="api">
+ <xsl:call-template name="overloadId">
+ <xsl:with-param name="typeId" select="$typeId"/>
+ <xsl:with-param name="name" select="$name"/>
+ <xsl:with-param name="subgroup" select="$subgroup"/>
+ <xsl:with-param name="subsubgroup" select="$subsubgroup"/>
+ </xsl:call-template>
+ </xsl:attribute>
+ <xsl:copy-of select="msxsl:node-set($signatureSet)/*"/>
+ </element>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:if>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:for-each>
+ </elements>
+ </xsl:template>
+
+ <xsl:template name="overloadId">
+ <xsl:param name="typeId"/>
+ <xsl:param name="name"/>
+ <xsl:param name="subgroup"/>
+ <xsl:param name="subsubgroup"/>
+ <xsl:choose>
+ <xsl:when test="$subgroup='constructor'">
+ <xsl:value-of select="concat('Overload:',substring($typeId,3),'.#ctor')"/>
+ </xsl:when>
+ <xsl:when test="$subsubgroup='operator'">
+ <xsl:value-of select="concat('Overload:',substring($typeId,3),'.op_',$name)"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="concat('Overload:',substring($typeId,3),'.',$name)"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template name="projectTopic">
+ <api id="R:{$project}">
+ <topicdata group="root" />
+ <elements>
+ <xsl:for-each select="/*/apis/api[apidata/@group='namespace']">
+ <element api="{@id}" />
+ </xsl:for-each>
+ </elements>
+ </api>
+ </xsl:template>
+
+</xsl:stylesheet>
diff --git a/tools/Sandcastle/ProductionTransforms/CreateHxC.xsl b/tools/Sandcastle/ProductionTransforms/CreateHxC.xsl
new file mode 100644
index 0000000..a3d1c5b
--- /dev/null
+++ b/tools/Sandcastle/ProductionTransforms/CreateHxC.xsl
@@ -0,0 +1,38 @@
+<?xml version="1.0"?>
+<xsl:stylesheet
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ version="1.1">
+
+ <!-- Create HxC project file for hxcomp.exe. The input can be any well formed
+ XML file; it is used only to satisfy XslTransform, which needs an input
+ file to run the transform. Make sure to set the fileNamePrefix. -->
+
+ <xsl:output doctype-system="MS-Help://Hx/Resources/HelpCollection.dtd" indent="yes" encoding="utf-8" />
+
+ <!-- $fileNamePrefix is the prefix used for all files names. -->
+ <xsl:param name="fileNamePrefix">test</xsl:param>
+
+ <xsl:template match="/">
+ <HelpCollection DTDVersion="1.0" FileVersion="08.00.50720.2102" LangId="1033" Title="Common Scripts" Copyright="© 2005 Microsoft Corporation. All rights reserved.">
+ <CompilerOptions OutputFile="{$fileNamePrefix}.HxS" CreateFullTextIndex="Yes" CompileResult="Hxs">
+ <IncludeFile File="{$fileNamePrefix}.HxF" />
+ </CompilerOptions>
+ <TOCDef File="{$fileNamePrefix}.HxT" />
+ <KeywordIndexDef File="{$fileNamePrefix}_A.HxK" />
+ <KeywordIndexDef File="{$fileNamePrefix}_K.HxK" />
+ <KeywordIndexDef File="{$fileNamePrefix}_F.HxK" />
+ <KeywordIndexDef File="{$fileNamePrefix}_N.HxK" />
+ <KeywordIndexDef File="{$fileNamePrefix}_S.HxK" />
+ <KeywordIndexDef File="{$fileNamePrefix}_B.HxK" />
+ <ItemMoniker Name="!DefaultTOC" ProgId="HxDs.HxHierarchy" InitData="AnyString" />
+ <ItemMoniker Name="!DefaultFullTextSearch" ProgId="HxDs.HxFullTextSearch" InitData="AnyString" />
+ <ItemMoniker Name="!DefaultAssociativeIndex" ProgId="HxDs.HxIndex" InitData="A" />
+ <ItemMoniker Name="!DefaultKeywordIndex" ProgId="HxDs.HxIndex" InitData="K" />
+ <ItemMoniker Name="!DefaultContextWindowIndex" ProgId="HxDs.HxIndex" InitData="F" />
+ <ItemMoniker Name="!DefaultNamedUrlIndex" ProgId="HxDs.HxIndex" InitData="NamedUrl" />
+ <ItemMoniker Name="!DefaultSearchWindowIndex" ProgId="HxDs.HxIndex" InitData="S" />
+ <ItemMoniker Name="!DefaultDynamicLinkIndex" ProgId="HxDs.HxIndex" InitData="B" />
+ </HelpCollection>
+ </xsl:template>
+
+</xsl:stylesheet> \ No newline at end of file
diff --git a/tools/Sandcastle/ProductionTransforms/CreatePrototypeToc.xsl b/tools/Sandcastle/ProductionTransforms/CreatePrototypeToc.xsl
new file mode 100644
index 0000000..b02df2e
--- /dev/null
+++ b/tools/Sandcastle/ProductionTransforms/CreatePrototypeToc.xsl
@@ -0,0 +1,142 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.1">
+
+ <xsl:param name="segregated" select="false()" />
+
+ <xsl:output indent="yes" />
+
+ <xsl:key name="index" match="/reflection/apis/api" use="@id" />
+
+ <xsl:template match="/">
+ <topics>
+ <xsl:choose>
+ <xsl:when test="count(/reflection/apis/api[apidata/@group='root']) > 0">
+ <xsl:apply-templates select="/reflection/apis/api[apidata/@group='root']" />
+ </xsl:when>
+ <xsl:when test="count(/reflection/apis/api[apidata/@group='namespace']) > 0">
+ <xsl:apply-templates select="/reflection/apis/api[apidata/@group='namespace']">
+ <xsl:sort select="apidata/@name" />
+ </xsl:apply-templates>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates select="/reflection/apis/api[apidata/@group='type']">
+ <xsl:sort select="apidata/@name" />
+ </xsl:apply-templates>
+ </xsl:otherwise>
+ </xsl:choose>
+ </topics>
+ </xsl:template>
+
+ <!-- create a root entry and namespace sub-entries -->
+ <xsl:template match="api[apidata/@group='root']">
+ <topic id="{@id}" file="{file/@name}">
+ <xsl:apply-templates select="key('index',elements/element/@api)">
+ <xsl:sort select="apidata/@name" />
+ </xsl:apply-templates>
+ </topic>
+ </xsl:template>
+
+
+ <!-- for each namespace, create namespace entry and type sub-entries -->
+ <xsl:template match="api[apidata/@group='namespace']">
+ <topic id="{@id}" file="{file/@name}">
+ <xsl:apply-templates select="key('index',elements/element/@api)">
+ <xsl:sort select="@id" />
+ </xsl:apply-templates>
+ </topic>
+ </xsl:template>
+
+ <!-- for each type, create type entry and either overload entries or member entries as sub-entries -->
+ <xsl:template match="api[apidata/@group='type']">
+ <xsl:choose>
+ <xsl:when test="$segregated">
+ <stopic id="{@id}" project="{containers/library/@assembly}" file="{file/@name}">
+ <xsl:call-template name="processType" />
+ </stopic>
+ </xsl:when>
+ <xsl:otherwise>
+ <topic id="{@id}" file="{file/@name}">
+ <xsl:call-template name="processType" />
+ </topic>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template name="processType">
+ <xsl:variable name="typeId" select="@id" />
+ <xsl:variable name="members" select="key('index',elements/element/@api)[containers/type/@api=$typeId]" />
+ <xsl:for-each select="$members">
+ <xsl:sort select="apidata/@name" />
+ <xsl:variable name="name" select="apidata/@name" />
+ <xsl:variable name="subgroup" select="apidata/@subgroup" />
+ <xsl:variable name="set" select="$members[apidata/@name=$name and apidata/@subgroup=$subgroup]" />
+ <xsl:choose>
+ <xsl:when test="count($set) &gt; 1">
+ <xsl:if test="($set[1]/@id)=@id">
+ <xsl:variable name="overloadId">
+ <xsl:value-of select="overload/@api" />
+ </xsl:variable>
+ <xsl:choose>
+ <xsl:when test="$segregated">
+ <stopic id="{@id}" project="{containers/library/@assembly}" file="{key('index',$overloadId)/file/@name}">
+ <xsl:for-each select="$set">
+ <xsl:apply-templates select="." />
+ </xsl:for-each>
+ </stopic>
+ </xsl:when>
+ <xsl:otherwise>
+ <topic id="{@id}" file="{key('index',$overloadId)/file/@name}">
+ <xsl:for-each select="$set">
+ <xsl:apply-templates select="." />
+ </xsl:for-each>
+ </topic>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:if>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates select="." />
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:for-each>
+ </xsl:template>
+
+ <!-- for each member, create a leaf entry -->
+ <xsl:template match="api[apidata/@group='member']">
+ <xsl:choose>
+ <xsl:when test="$segregated">
+ <stopic id="{@id}" project="{containers/library/@assembly}" file="{file/@name}" />
+ </xsl:when>
+ <xsl:otherwise>
+ <topic id="{@id}" file="{file/@name}" />
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template name="overloadId">
+ <xsl:param name="memberId" />
+ <xsl:text>Overload:</xsl:text>
+ <xsl:variable name="noParameters">
+ <xsl:choose>
+ <xsl:when test="contains($memberId,'(')">
+ <xsl:value-of select="substring-before($memberId,'(')" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$memberId" />
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:variable name="noGeneric">
+ <xsl:choose>
+ <xsl:when test="contains($noParameters,'``')">
+ <xsl:value-of select="substring-before($noParameters,'``')" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$noParameters" />
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:value-of select="substring($noGeneric,3)" />
+ </xsl:template>
+
+</xsl:stylesheet>
diff --git a/tools/Sandcastle/ProductionTransforms/CreateVSToc.xsl b/tools/Sandcastle/ProductionTransforms/CreateVSToc.xsl
new file mode 100644
index 0000000..afec23d
--- /dev/null
+++ b/tools/Sandcastle/ProductionTransforms/CreateVSToc.xsl
@@ -0,0 +1,207 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.1">
+
+ <xsl:param name="projectName" />
+ <xsl:param name="maxProjectNameLength" select="49" /> <!-- default provided by paorear, bug 230840 -->
+ <xsl:variable name="leftLength" select="$maxProjectNameLength div 2 - 1" />
+ <xsl:variable name="rightLength" select="$maxProjectNameLength - $leftLength - 2" />
+ <xsl:variable name="projectPrefix">
+ <xsl:if test="boolean($projectName)">
+ <xsl:value-of select="concat($projectName,'_')"/>
+ </xsl:if>
+ </xsl:variable>
+
+ <xsl:output indent="yes" encoding="UTF-8" />
+
+ <xsl:key name="index" match="/reflection/apis/api" use="@id" />
+
+ <xsl:template match="/">
+ <topics>
+ <xsl:choose>
+ <xsl:when test="count(/reflection/apis/api[apidata/@group='root']) > 0">
+ <xsl:apply-templates select="/reflection/apis/api[apidata/@group='root']" />
+ </xsl:when>
+ <xsl:when test="count(/reflection/apis/api[topicdata/@group='root']) > 0">
+ <xsl:apply-templates select="/reflection/apis/api[topicdata/@group='root']" />
+ </xsl:when>
+ <xsl:when test="count(/reflection/apis/api[apidata/@group='namespace']) > 0">
+ <xsl:apply-templates select="/reflection/apis/api[apidata/@group='namespace']">
+ <xsl:sort select="apidata/@name" />
+ </xsl:apply-templates>
+ </xsl:when>
+ <xsl:when test="count(/reflection/apis/api[apidata/@group='type']) > 0">
+ <xsl:apply-templates select="/reflection/apis/api[apidata/@group='type'][topicdata[@group='api']]">
+ <xsl:sort select="@id" />
+ </xsl:apply-templates>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates select="/reflection/apis/api[apidata/@group='member']">
+ <xsl:sort select="@id" />
+ </xsl:apply-templates>
+ </xsl:otherwise>
+ </xsl:choose>
+ </topics>
+ </xsl:template>
+
+ <!-- create a root entry and namespace sub-entries -->
+ <xsl:template match="api[apidata/@group='root'] | api[topicdata/@group='root']">
+ <topic id="{@id}" project="{$projectName}" file="{file/@name}">
+ <xsl:apply-templates select="key('index',elements/element/@api)">
+ <xsl:sort select="apidata/@name" />
+ </xsl:apply-templates>
+ </topic>
+ </xsl:template>
+
+ <!-- for each namespace, create namespace entry and type sub-entries -->
+ <xsl:template match="api[apidata/@group='namespace']">
+ <topic id="{@id}" project="{$projectName}_Namespaces" file="{file/@name}">
+ <xsl:apply-templates select="key('index',elements/element/@api)">
+ <xsl:sort select="@id" />
+ </xsl:apply-templates>
+ </topic>
+ </xsl:template>
+
+ <!-- logic to shorten component names if needed -->
+ <xsl:template name="GetComponentName">
+ <xsl:param name="initialName" select="containers/library/@assembly" />
+ <xsl:variable name="componentNameLength" select="string-length($initialName)" />
+ <xsl:choose>
+ <xsl:when test="$componentNameLength > $maxProjectNameLength">
+ <xsl:variable name="left" select="substring($initialName, 1, $leftLength)" />
+ <xsl:variable name="right" select="substring($initialName, $componentNameLength - $rightLength)" />
+ <xsl:value-of select="concat($left,'_',$right)" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$initialName" />
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <!-- for each type, create type entry and either overload entries or member entries as sub-entries -->
+ <xsl:template match="api[apidata/@group='type'][topicdata[@group='api']]">
+ <xsl:variable name="componentName">
+ <xsl:call-template name="GetComponentName">
+ <xsl:with-param name="initialName" select="concat($projectPrefix,containers/library/@assembly)" />
+ </xsl:call-template>
+ </xsl:variable>
+ <topic id="{@id}" project="{$componentName}" file="{file/@name}">
+ <xsl:call-template name="AddMemberListTopics"/>
+ </topic>
+ </xsl:template>
+
+ <!-- For class, struct, and interface, insert nodes for the member list topics,
+ and insert nodes for the declared member topics under the appropriate list topic. -->
+ <xsl:template name="AddMemberListTopics">
+ <xsl:variable name="typeId" select="@id" />
+ <xsl:variable name="declaredPrefix" select="concat(substring($typeId,3), '.')"/>
+ <xsl:variable name="componentName">
+ <xsl:call-template name="GetComponentName">
+ <xsl:with-param name="initialName" select="concat($projectPrefix,containers/library/@assembly)" />
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:if test="apidata[@subgroup='class' or @subgroup='structure' or @subgroup='interface']">
+ <!-- insert the all members topic, if present -->
+ <xsl:for-each select="key('index', topicdata/@allMembersTopicId)">
+ <topic id="{@id}" project="{$componentName}" file="{file/@name}"/>
+ </xsl:for-each>
+
+ <!-- insert constructors -->
+ <!-- the context now is the type's api node, which has an element list in vsorcas docmodel, but not in vs2005 -->
+ <xsl:choose>
+ <xsl:when test="topicdata/@allMembersTopicId">
+ <xsl:for-each select="key('index', key('index', topicdata/@allMembersTopicId)/elements/*[starts-with(substring-after(@api,':'), $declaredPrefix)]/@api)[apidata[@subgroup='constructor']]">
+ <xsl:call-template name="AddMember">
+ <xsl:with-param name="declaredPrefix" select="$declaredPrefix"/>
+ </xsl:call-template>
+ </xsl:for-each>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:for-each select="key('index', elements/*[starts-with(substring-after(@api,':'), $declaredPrefix)]/@api)[apidata[@subgroup='constructor']]">
+ <xsl:call-template name="AddMember">
+ <xsl:with-param name="declaredPrefix" select="$declaredPrefix"/>
+ </xsl:call-template>
+ </xsl:for-each>
+ </xsl:otherwise>
+ </xsl:choose>
+
+ <!-- insert the Fields topic, if present -->
+ <xsl:for-each select="key('index', concat('Fields.', $typeId))">
+ <xsl:call-template name="AddMemberListTree"/>
+ </xsl:for-each>
+
+ <!-- insert the Methods topic, if present -->
+ <xsl:for-each select="key('index', concat('Methods.', $typeId))">
+ <xsl:call-template name="AddMemberListTree"/>
+ </xsl:for-each>
+
+ <!-- insert the Properties topic, if present -->
+ <xsl:for-each select="key('index', concat('Properties.', $typeId))">
+ <xsl:call-template name="AddMemberListTree"/>
+ </xsl:for-each>
+
+ <!-- insert the Events topic, if present -->
+ <xsl:for-each select="key('index', concat('Events.', $typeId))">
+ <xsl:call-template name="AddMemberListTree"/>
+ </xsl:for-each>
+
+ <!-- insert the AttachedProperties topic, if present -->
+ <xsl:for-each select="key('index', concat('AttachedProperties.', $typeId))">
+ <xsl:call-template name="AddMemberListTree"/>
+ </xsl:for-each>
+
+ <!-- insert the AttachedEvents topic, if present -->
+ <xsl:for-each select="key('index', concat('AttachedEvents.', $typeId))">
+ <xsl:call-template name="AddMemberListTree"/>
+ </xsl:for-each>
+
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template name="AddMemberListTree">
+ <xsl:variable name="componentName">
+ <xsl:call-template name="GetComponentName">
+ <xsl:with-param name="initialName" select="concat($projectPrefix,containers/library/@assembly)" />
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="declaredPrefix" select="concat(substring(topicdata/@typeTopicId,3), '.')"/>
+ <topic id="{@id}" project="{$componentName}" file="{file/@name}">
+ <!-- recurse to get declared child element topics, if any -->
+ <xsl:for-each select="key('index', elements/*[starts-with(substring-after(@api,':'), $declaredPrefix)]/@api)">
+ <!-- sort the elements in a member list topic by name -->
+ <xsl:sort select="apidata/@name" />
+ <xsl:call-template name="AddMember">
+ <xsl:with-param name="declaredPrefix" select="$declaredPrefix"/>
+ </xsl:call-template>
+ </xsl:for-each>
+ </topic>
+ </xsl:template>
+
+ <xsl:template name="AddMember">
+ <xsl:param name="declaredPrefix" />
+ <xsl:variable name="componentName">
+ <xsl:call-template name="GetComponentName">
+ <xsl:with-param name="initialName" select="concat($projectPrefix,containers/library/@assembly)" />
+ </xsl:call-template>
+ </xsl:variable>
+ <topic id="{@id}" project="{$componentName}" file="{file/@name}">
+ <!-- loop throught the declared elements, if any, which are already pre-sorted by the ApplyVsDocModel transform;
+ if you were to loop through the key('index', elements) as in the AddMemberListTree template,
+ you'd lose the pre-sort and get the order of apis in the document
+ -->
+ <xsl:for-each select="elements/*[starts-with(substring-after(@api,':'), $declaredPrefix)]">
+ <xsl:for-each select="key('index',@api)">
+ <xsl:call-template name="AddMember">
+ <xsl:with-param name="declaredPrefix" select="$declaredPrefix"/>
+ </xsl:call-template>
+ </xsl:for-each>
+ </xsl:for-each>
+ </topic>
+ </xsl:template>
+
+ <!-- if only members are present, create toc entries for them (this should never be a visible toc) -->
+ <xsl:template match="api[apidata/@group='member']">
+ <topic id="{@id}" project="{$projectName}" file="{file/@name}" />
+ </xsl:template>
+
+</xsl:stylesheet>
diff --git a/tools/Sandcastle/ProductionTransforms/DsManifestToManifest.xsl b/tools/Sandcastle/ProductionTransforms/DsManifestToManifest.xsl
new file mode 100644
index 0000000..da42b4b
--- /dev/null
+++ b/tools/Sandcastle/ProductionTransforms/DsManifestToManifest.xsl
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.1">
+
+ <xsl:output indent="yes" encoding="utf-8" />
+
+ <xsl:template match="/">
+ <topics>
+ <xsl:apply-templates select="/manifest/manifestExecution/assetDetail/fileAsset" />
+ </topics>
+ </xsl:template>
+
+ <xsl:template match="fileAsset[@assetType='Topic']">
+ <topic>
+ <xsl:attribute name="id">
+ <xsl:value-of select="@fileAssetGuid" />
+ </xsl:attribute>
+ </topic>
+ <xsl:apply-templates select="topic" />
+ </xsl:template>
+
+ <xsl:template match="fileAsset" />
+
+</xsl:stylesheet>
diff --git a/tools/Sandcastle/ProductionTransforms/DsTocToManifest.xsl b/tools/Sandcastle/ProductionTransforms/DsTocToManifest.xsl
new file mode 100644
index 0000000..be4149f
--- /dev/null
+++ b/tools/Sandcastle/ProductionTransforms/DsTocToManifest.xsl
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.1">
+
+ <xsl:output indent="yes" encoding="utf-8" />
+
+ <xsl:key name="index" match="/apis/api" use="@id" />
+
+ <xsl:template match="/">
+ <topics>
+ <xsl:apply-templates select="/tableOfContents/topic" />
+ </topics>
+ </xsl:template>
+
+ <xsl:template match="topic">
+ <topic>
+ <xsl:attribute name="id">
+ <xsl:value-of select="@id" />
+ </xsl:attribute>
+ </topic>
+ <xsl:apply-templates select="topic" />
+ </xsl:template>
+
+</xsl:stylesheet>
diff --git a/tools/Sandcastle/ProductionTransforms/DsTocToSitemap.xsl b/tools/Sandcastle/ProductionTransforms/DsTocToSitemap.xsl
new file mode 100644
index 0000000..5440d5a
--- /dev/null
+++ b/tools/Sandcastle/ProductionTransforms/DsTocToSitemap.xsl
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- Doc Studio Contents to Sitemap Transform
+
+ Invoke with: xsltransform TocToSitemap.xsl toc.xml [/arg:comments=comments-dir] /out:web.sitemap
+
+ - topicInfo - specifies the directory where the comment files are stored. The default is
+ 'Temp\TopicInfo'.
+-->
+
+<xsl:stylesheet version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:ddue="http://ddue.schemas.microsoft.com/authoring/2003/5">
+
+ <xsl:param name="topicInfo" select="'Temp\TopicInfo'"/>
+
+ <xsl:output indent="yes" encoding="utf-8"/>
+
+ <xsl:namespace-alias stylesheet-prefix="ddue" result-prefix="#default"/>
+
+ <xsl:key name="index" match="/apis/api" use="@id"/>
+
+ <xsl:template match="/">
+ <siteMap>
+ <!--<siteMapNode>-->
+ <xsl:apply-templates select="/tableOfContents/topic"/>
+ <!--</siteMapNode>-->
+ </siteMap>
+ </xsl:template>
+
+ <xsl:template match="topic">
+ <siteMapNode>
+ <xsl:if test="@isCategoryOnly != 'True' or @url">
+ <xsl:attribute name="url">
+ <xsl:choose>
+ <xsl:when test="@url">
+ <xsl:value-of select="@url"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="document(concat($topicInfo, '/', @id, '.xml'))//pageUrl[1]"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:attribute>
+ </xsl:if>
+ <xsl:call-template name="tocTitleAttr"/>
+ <xsl:apply-templates/>
+ </siteMapNode>
+ </xsl:template>
+
+ <xsl:template match="sharedTopic">
+ <siteMapNode>
+ <xsl:if test="@isCategoryOnly != 'True' or @url">
+ <xsl:attribute name="url">
+ <xsl:choose>
+ <xsl:when test="@url">
+ <xsl:value-of select="@url"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="concat(document(concat($topicInfo, '/', @id, '.xml'))//pageUrl[1], '#', generate-id())"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:attribute>
+ </xsl:if>
+ <xsl:call-template name="tocTitleAttr"/>
+ <xsl:apply-templates/>
+ </siteMapNode>
+ </xsl:template>
+
+ <xsl:template name="tocTitleAttr">
+ <xsl:attribute name="title">
+ <xsl:choose>
+ <xsl:when test="@title">
+ <xsl:value-of select="@title"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="document(concat($topicInfo, '/', @id, '.xml'))//tableOfContentsTitle[1]"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ <!-- Not needed if the build uses the custom .cmp.xml files produced by GetTopicInfo.exe.
+ Those files contain a copy of the title in the tableOfContentsTitle element as needed.
+ <xsl:if test="not(document(concat($topicInfo, '/', @id, '.xml'))//tableOfContentsTitle[1])">
+ <xsl:value-of select="document(concat($topicInfo, '/', @id, '.xml'))//title[1]"/>
+ </xsl:if>
+ -->
+ </xsl:attribute>
+ </xsl:template>
+
+</xsl:stylesheet>
diff --git a/tools/Sandcastle/ProductionTransforms/DsTocToToc.xsl b/tools/Sandcastle/ProductionTransforms/DsTocToToc.xsl
new file mode 100644
index 0000000..fdf799f
--- /dev/null
+++ b/tools/Sandcastle/ProductionTransforms/DsTocToToc.xsl
@@ -0,0 +1,33 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.1">
+
+ <xsl:output indent="yes" />
+
+ <xsl:template match="/">
+ <topics>
+ <xsl:apply-templates select="/*" />
+ </topics>
+ </xsl:template>
+
+ <xsl:template match="topic">
+ <topic id="{@id}">
+ <xsl:if test="not(@isCategoryOnly='True')">
+ <xsl:attribute name="file">
+ <xsl:value-of select="@id" />
+ </xsl:attribute>
+ </xsl:if>
+ <xsl:apply-templates />
+ </topic>
+ </xsl:template>
+
+ <xsl:template match="sharedTOC|sharedManagedReferenceTOC">
+ <stoc project="{@projectName}" />
+ </xsl:template>
+
+ <xsl:template match="sharedTopic">
+ <stopic project="{@projectName}" id="{@id}" file="{@id}">
+ <xsl:apply-templates />
+ </stopic>
+ </xsl:template>
+
+</xsl:stylesheet>
diff --git a/tools/Sandcastle/ProductionTransforms/FixScriptSharp.xsl b/tools/Sandcastle/ProductionTransforms/FixScriptSharp.xsl
new file mode 100644
index 0000000..c375c78
--- /dev/null
+++ b/tools/Sandcastle/ProductionTransforms/FixScriptSharp.xsl
@@ -0,0 +1,87 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.1">
+
+ <xsl:output indent="yes" encoding="UTF-8" />
+
+ <xsl:template match="node() | @*">
+ <xsl:copy>
+ <xsl:apply-templates select="node() | @*" />
+ </xsl:copy>
+ </xsl:template>
+
+ <!-- Fix subgroups for enumerations -->
+ <xsl:template match="reflection/apis/api[apidata/@group='type' and family/ancestors/type/@api='T:System.Enum']/apidata/@subgroup">
+ <xsl:attribute name="subgroup">
+ <xsl:value-of select="'enumeration'"/>
+ </xsl:attribute>
+ </xsl:template>
+
+ <!-- Strip ancestors from enumerations -->
+ <xsl:template match="reflection/apis/api[apidata/@group='type' and family/ancestors/type/@api='T:System.Enum']/family">
+ </xsl:template>
+
+ <!-- Strip invalid members from enumerations -->
+ <xsl:template match="reflection/apis/api[apidata/@group='type' and family/ancestors/type/@api='T:System.Enum']/elements">
+ <elements>
+ <xsl:for-each select="element">
+ <xsl:if test="(starts-with(@api, 'F:') and not(contains(@api, 'value__')))">
+ <xsl:copy>
+ <xsl:apply-templates select="node() | @*" />
+ </xsl:copy>
+ </xsl:if>
+ </xsl:for-each>
+ </elements>
+ </xsl:template>
+
+ <!-- Fix subgroups for enumerations -->
+ <xsl:template match="reflection/apis/api[apidata/@group='type' and family/ancestors/type/@api='T:System.MulticastDelegate']/apidata/@subgroup">
+ <xsl:attribute name="subgroup">
+ <xsl:value-of select="'delegate'"/>
+ </xsl:attribute>
+ </xsl:template>
+
+ <!-- Strip ancestors from delegates -->
+ <xsl:template match="reflection/apis/api[apidata/@group='type' and family/ancestors/type/@api='T:System.MulticastDelegate']/family">
+ </xsl:template>
+
+ <!-- Strip elements from delegates -->
+ <xsl:template match="reflection/apis/api[apidata/@group='type' and family/ancestors/type/@api='T:System.MulticastDelegate']/elements">
+ </xsl:template>
+
+ <!-- Insert parameters into delegates -->
+ <xsl:template match="reflection/apis/api[apidata/@group='type' and family/ancestors/type/@api='T:System.MulticastDelegate']/apidata">
+ <xsl:copy>
+ <xsl:apply-templates select="node() | @*" />
+ </xsl:copy>
+ <xsl:variable name="id" select="../@id" />
+ <xsl:copy-of select="/reflection/apis/api[starts-with(@id, concat('M:', substring-after($id, 'T:'), '.Invoke('))]/parameters">
+ </xsl:copy-of>
+ </xsl:template>
+
+ <!-- Annotate members whose types have the GlobalMethodsAttribute -->
+ <xsl:template match="reflection/apis/api[apidata/@group='member']/apidata/@name">
+ <xsl:copy>
+ <xsl:apply-templates select="node() | @*" />
+ </xsl:copy>
+ <xsl:variable name="type" select="../../containers/type/@api" />
+ <xsl:if test="/reflection/apis/api[@id=$type]/attributes/attribute/type/@api='T:System.GlobalMethodsAttribute'">
+ <xsl:attribute name="global">
+ <xsl:value-of select="'true'"/>
+ </xsl:attribute>
+ </xsl:if>
+ </xsl:template>
+
+ <!-- Annotate constructors whose types have the RecordAttribute -->
+ <xsl:template match="reflection/apis/api[apidata/@group='member']/apidata[@subgroup='constructor']/@subgroup">
+ <xsl:copy>
+ <xsl:apply-templates select="node() | @*" />
+ </xsl:copy>
+ <xsl:variable name="type" select="../../containers/type/@api" />
+ <xsl:if test="/reflection/apis/api[@id=$type]/attributes/attribute/type/@api='T:System.RecordAttribute'">
+ <xsl:attribute name="record">
+ <xsl:value-of select="'true'"/>
+ </xsl:attribute>
+ </xsl:if>
+ </xsl:template>
+
+</xsl:stylesheet> \ No newline at end of file
diff --git a/tools/Sandcastle/ProductionTransforms/MergeDuplicates.xsl b/tools/Sandcastle/ProductionTransforms/MergeDuplicates.xsl
new file mode 100644
index 0000000..3ac0b01
--- /dev/null
+++ b/tools/Sandcastle/ProductionTransforms/MergeDuplicates.xsl
@@ -0,0 +1,166 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.1">
+
+ <xsl:output indent="yes" encoding="UTF-8" />
+
+ <!-- Merges reflection nodes for apis that are declared in multiple assemblies.
+ For example, some of the same apis in the Microsoft.Windows.Themes namespace are declared in:
+ PresentationFramework.Aero.dll
+ PresentationFramework.Luna.dll
+ PresentationFramework.Classic.dll
+ PresentationFramework.Royale.dll
+
+ This transform:
+ - gets rid of duplicate element nodes in a namespace's api node
+ - type api nodes: collapses duplicates into a single api node; saves library info for each duplicate
+ - member api nodes: collapses duplicates into a single api node; saves library info for each duplicate
+ - enum api nodes: saves container info for each enum element, in case the element lists differ
+ -->
+ <xsl:key name="index" match="/*/apis/api" use="@id" />
+
+ <xsl:template match="/">
+ <reflection>
+ <xsl:copy-of select="/*/@*"/>
+ <xsl:copy-of select="/*/assemblies" />
+ <xsl:apply-templates select="/*/apis" />
+ </reflection>
+ </xsl:template>
+
+ <xsl:template match="apis">
+ <apis>
+ <xsl:apply-templates select="api" />
+ </apis>
+ </xsl:template>
+
+ <xsl:template match="api">
+ <xsl:copy-of select="." />
+ </xsl:template>
+
+ <xsl:template match="api[apidata/@group='namespace']">
+ <api>
+ <xsl:copy-of select="@*" />
+ <xsl:for-each select="*">
+ <xsl:choose>
+ <xsl:when test="local-name()='elements'">
+ <elements>
+ <xsl:for-each select="element[not(@api=preceding-sibling::element/@api)]">
+ <xsl:copy-of select="." />
+ </xsl:for-each>
+ </elements>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:copy-of select="." />
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:for-each>
+ </api>
+ </xsl:template>
+
+ <xsl:template match="api[apidata/@group='type']">
+ <xsl:variable name="ancestorId" select="family/ancestors/type[last()]/@api" />
+ <xsl:variable name="subgroup" select="apidata/@subgroup" />
+ <xsl:variable name="duplicates" select="key('index',@id)[apidata[@subgroup=$subgroup]]" />
+ <!--
+ (apidata[@subgroup!='class'] or family/ancestors/type[last()][@api=$ancestorId])]
+ -->
+ <xsl:choose>
+ <!-- if dupes, merge them -->
+ <xsl:when test="count($duplicates)&gt;1">
+ <xsl:variable name="typeId" select="@id" />
+ <xsl:if test="not(preceding-sibling::api[@id=$typeId][apidata[@subgroup=$subgroup]])">
+ <xsl:call-template name="mergeDuplicateTypes">
+ <xsl:with-param name="duplicates" select="$duplicates"/>
+ </xsl:call-template>
+ </xsl:if>
+ </xsl:when>
+ <!-- if no dupes, just copy it -->
+ <xsl:otherwise>
+ <xsl:copy-of select="." />
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template name="mergeDuplicateTypes">
+ <xsl:param name="duplicates"/>
+ <xsl:variable name="typeId" select="@id"/>
+ <xsl:variable name="subgroup" select="apidata/@subgroup" />
+ <xsl:variable name="duplicatesCount" select="count($duplicates)"/>
+ <api>
+ <xsl:copy-of select="@*" />
+ <xsl:for-each select="*">
+ <xsl:choose>
+ <xsl:when test="local-name()='containers'">
+ <containers>
+ <xsl:copy-of select="$duplicates/containers/library" />
+ <xsl:copy-of select="namespace|type" />
+ </containers>
+ </xsl:when>
+ <xsl:when test="local-name()='elements'">
+ <elements>
+ <xsl:for-each select="$duplicates/elements/element">
+ <xsl:variable name="elementId" select="@api"/>
+ <xsl:if test="not(preceding::api[@id=$typeId][apidata[@subgroup=$subgroup]]/elements/element[@api=$elementId])">
+ <!-- need to add library info to elements that are not in all duplicates -->
+ <element>
+ <xsl:copy-of select="@*"/>
+ <xsl:copy-of select="*"/>
+ <xsl:if test="count($duplicates/elements/element[@api=$elementId]) != $duplicatesCount">
+ <libraries>
+ <xsl:copy-of select="$duplicates/elements/element[@api=$elementId]/../../containers/library"/>
+ </libraries>
+ </xsl:if>
+ </element>
+ </xsl:if>
+ </xsl:for-each>
+ </elements>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:copy-of select="." />
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:for-each>
+ </api>
+ </xsl:template>
+
+ <xsl:template match="api[apidata/@group='member']">
+ <xsl:variable name="subgroup" select="apidata/@subgroup" />
+ <xsl:variable name="duplicates" select="key('index',@id)[apidata[@subgroup=$subgroup]]" />
+ <xsl:choose>
+ <!-- if dupes, merge them -->
+ <xsl:when test="count($duplicates)&gt;1">
+ <xsl:variable name="memberId" select="@id" />
+ <xsl:if test="not(preceding-sibling::api[@id=$memberId][apidata[@subgroup=$subgroup]])">
+ <xsl:call-template name="mergeDuplicateMembers">
+ <xsl:with-param name="duplicates" select="$duplicates"/>
+ </xsl:call-template>
+ </xsl:if>
+ </xsl:when>
+ <!-- if no dupes, just copy it -->
+ <xsl:otherwise>
+ <xsl:copy-of select="." />
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template name="mergeDuplicateMembers">
+ <xsl:param name="duplicates"/>
+ <api>
+ <xsl:copy-of select="@*" />
+ <xsl:for-each select="*">
+ <xsl:choose>
+ <xsl:when test="local-name()='containers'">
+ <containers>
+ <!-- include the library node for all the duplicates -->
+ <xsl:copy-of select="$duplicates/containers/library" />
+ <xsl:copy-of select="namespace|type" />
+ </containers>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:copy-of select="." />
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:for-each>
+ </api>
+ </xsl:template>
+
+</xsl:stylesheet> \ No newline at end of file
diff --git a/tools/Sandcastle/ProductionTransforms/MergeHxF.xsl b/tools/Sandcastle/ProductionTransforms/MergeHxF.xsl
new file mode 100644
index 0000000..7452eb3
--- /dev/null
+++ b/tools/Sandcastle/ProductionTransforms/MergeHxF.xsl
@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+<xsl:stylesheet
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:ds="http://ddue.schemas.microsoft.com/authoring/2003/5"
+ version="1.1">
+
+ <xsl:output doctype-system="MS-Help://Hx/Resources/HelpFileList.dtd" indent="yes" encoding="UTF-8" />
+
+ <xsl:param name="hxfToMerge" />
+
+ <xsl:template match="/">
+ <xsl:for-each select="*">
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:copy-of select="File"/>
+ <xsl:copy-of select="document($hxfToMerge)//File"/>
+ </xsl:copy>
+ </xsl:for-each>
+ </xsl:template>
+
+ <!--
+ <xsl:for-each select="document($hxfToMerge)//File">
+ <xsl:copy-of select="."/>
+ </xsl:for-each>
+ <xsl:template match="File">
+ </xsl:template>
+ -->
+</xsl:stylesheet> \ No newline at end of file
diff --git a/tools/Sandcastle/ProductionTransforms/ReflectionToCDocML.xsl b/tools/Sandcastle/ProductionTransforms/ReflectionToCDocML.xsl
new file mode 100644
index 0000000..57112f8
--- /dev/null
+++ b/tools/Sandcastle/ProductionTransforms/ReflectionToCDocML.xsl
@@ -0,0 +1,845 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.1">
+
+ <xsl:output indent="yes" />
+
+ <xsl:key name="index" match="/reflection/apis/api" use="@id" />
+
+ <xsl:template match="/">
+ <cDocMLDocument>
+ <content>
+ <assemblies>
+ <xsl:apply-templates select="/reflection/assemblies/assembly" />
+ </assemblies>
+ <namespaces>
+ <xsl:apply-templates select="/reflection/apis/api[apidata/@group='namespace']" />
+ </namespaces>
+ </content>
+ <idMap>
+ <xsl:for-each select="/reflection/apis/api[apidata/@group='namespace']">
+ <entity namespaceName="{apidata/@name}" typeName="" memberName="" commentId="{@id}" textId="" />
+ </xsl:for-each>
+ <xsl:for-each select="/reflection/apis/api[apidata/@group='type']">
+ <entity namespaceName="{key('index',containers/namespace/@api)/apidata/@name}" typeName="{apidata/@name}" memberName="" commentId="{@id}" textId="" />
+ </xsl:for-each>
+ <xsl:for-each select="/reflection/apis/api[apidata/@group='member']">
+ <entity namespaceName="{key('index',containers/namespace/@api)/apidata/@name}" typeName="{key('index',containers/type/@api)/apidata/@name}" memberName="{apidata/@name}" commentId="{@id}" textId="" />
+ </xsl:for-each>
+ </idMap>
+ <rMap>
+ <type namespace="System" name="Object" commentId="T:Sytem.Object">
+ <xsl:attribute name="external">
+ <xsl:choose>
+ <xsl:when test="/reflection/apis/api[@id='T:System.Object']">false</xsl:when>
+ <xsl:otherwise>true</xsl:otherwise>
+ </xsl:choose>
+ </xsl:attribute>
+ <type namespace="System" name="ValueType" commentId="T:System.ValueType">
+ <xsl:attribute name="external">
+ <xsl:choose>
+ <xsl:when test="/reflection/apis/api[@id='T:System.ValueType']">false</xsl:when>
+ <xsl:otherwise>true</xsl:otherwise>
+ </xsl:choose>
+ </xsl:attribute>
+ <xsl:for-each select="/reflection/apis/api[apidata/@subgroup='structure']">
+ <type namespace="{key('index',containers/namespace/@api)/apidata/@name}" name="{apidata/@name}" commentId="{@id}" external="false" />
+ </xsl:for-each>
+ </type>
+ <xsl:for-each select="/reflection/apis/api[apidata/@subgroup='class']">
+ <xsl:if test="not(@id='T:System.Object' or @id='T:System.ValueType')">
+ <type namespace="{key('index',containers/namespace/@api)/apidata/@name}" name="{apidata/@name}" commentId="{@id}" external="false" />
+ </xsl:if>
+ </xsl:for-each>
+ </type>
+ </rMap>
+
+ </cDocMLDocument>
+ </xsl:template>
+
+ <!-- utility templates -->
+
+ <xsl:template name="writeIdentity">
+ <xsl:param name="namespaceName" />
+ <xsl:param name="typeName" />
+ <xsl:param name="memberName" />
+ <xsl:param name="commentId" select="@id|@api" />
+ <xsl:param name="textId" />
+ <identity namespaceName="{$namespaceName}" typeName="{$typeName}" memberName="{$memberName}" commentId="{$commentId}" textId="{$textId}" />
+ </xsl:template>
+
+ <xsl:template name="writeTypeIdentity">
+ <xsl:call-template name="writeIdentity">
+ <xsl:with-param name="namespaceName" select="key('index',containers/namespace/@api)/apidata/@name" />
+ <xsl:with-param name="typeName" select="apidata/@name" />
+ </xsl:call-template>
+ </xsl:template>
+
+ <xsl:template name="writeMemberIdentity">
+ <xsl:call-template name="writeIdentity">
+ <xsl:with-param name="namespaceName" select="key('index',containers/namespace/@api)/apidata/@name" />
+ <xsl:with-param name="typeName" select="key('index',containers/type/@api)/apidata/@name" />
+ <xsl:with-param name="memberName" select="apidata/@name" />
+ </xsl:call-template>
+ </xsl:template>
+
+
+ <xsl:template name="writeSource">
+ <xsl:param name="assembly" select="containers/library/@assembly" />
+ <xsl:param name="module" select="containers/library/@module" />
+ <source assembly="{$assembly}" module="{$module}" />
+ </xsl:template>
+
+ <xsl:template name="writeTypeAttributes">
+ <xsl:param name="visibility" select="string('Public')" />
+ <xsl:param name="classLayout" select="string('AutoLayout')" />
+ <xsl:param name="abstract">
+ <xsl:choose>
+ <xsl:when test="typedata/@abstract">
+ <xsl:value-of select="typedata/@abstract" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>false</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:param>
+ <xsl:param name="sealed">
+ <xsl:choose>
+ <xsl:when test="typedata/@sealed">
+ <xsl:value-of select="typedata/@sealed" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>false</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:param>
+ <xsl:param name="specialName" select="string('false')" />
+ <attributes visibility="{$visibility}" classLayout="{$classLayout}" abstract="{$abstract}" sealed="{$sealed}" specialName="{$specialName}" import="false" stringFormat="Ansi" beforeFieldInitialization="false" runtimeSpecialName="false" />
+ </xsl:template>
+
+ <xsl:template name="writeMemberAccess">
+ <xsl:param name="visibility" select="string('Public')" />
+ <xsl:param name="static">
+ <xsl:choose>
+ <xsl:when test="memberdata/@static">
+ <xsl:value-of select="memberdata/@static" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>false</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:param>
+ <xsl:param name="declaringType" select="containers/type/@api" />
+ <xsl:param name="specialName" select="string('false')" />
+ <xsl:param name="runtimeSpecialName" select="string('false')"/>
+ <xsl:param name="hasDefaultValue" select="string('false')" />
+ <xsl:param name="hasMarshallingInformation" select="string('false')" />
+ <xsl:param name="hasRelativeVirtualAddress" select="string('false')" />
+ <xsl:param name="isInitializedOnly" select="fielddata/@initonly" />
+ <xsl:param name="isLiteral" select="fielddata/@literal" />
+ <xsl:param name="isNotSerialized" select="string('false')" />
+ <access visibility="{$visibility}" static="{$static}" declaringType="{$declaringType}" specialName="{$specialName}" runtimeSpecialName="{$runtimeSpecialName}" hasDefaultValue="{$hasDefaultValue}" hasMarshallingInformation="{$hasMarshallingInformation}" hasRelativeVirtualAddress="{$hasRelativeVirtualAddress}" isInitializedOnly="{$isInitializedOnly}" isLiteral="{$isLiteral}" isNotSerialized="{$isNotSerialized}" isPInvokeImplementation="false" />
+ </xsl:template>
+
+ <xsl:template name="writeMethodAccess">
+ <xsl:param name="visibility" select="string('Public')" />
+ <xsl:param name="static">
+ <xsl:choose>
+ <xsl:when test="memberdata/@static">
+ <xsl:value-of select="memberdata/@static" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>false</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:param>
+ <xsl:param name="declaringType" select="containers/type/@api" />
+ <xsl:param name="specialName">
+ <xsl:choose>
+ <xsl:when test="memberdata/@special">
+ <xsl:value-of select="memberdata/@special" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>false</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:param>
+ <xsl:param name="runtimeSpecialName" select="string('false')"/>
+ <xsl:param name="abstract">
+ <xsl:choose>
+ <xsl:when test="proceduredata/@abstract">
+ <xsl:value-of select="proceduredata/@abstract" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>false</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:param>
+ <xsl:param name="virtual">
+ <xsl:choose>
+ <xsl:when test="proceduredata/@virtual">
+ <xsl:value-of select="proceduredata/@virtual" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>false</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:param>
+ <xsl:param name="final">
+ <xsl:choose>
+ <xsl:when test="proceduredata/@final">
+ <xsl:value-of select="proceduredata/@final" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>false</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:param>
+ <xsl:param name="vtable" select="string('reuseSlot')" />
+ <xsl:param name="callingConvention" select="string('HasThis')" />
+ <xsl:param name="pInvokeImplementation" select="string('false')" />
+ <xsl:param name="hideBySignature" select="string('true')" />
+ <xsl:param name="hasSecurity" select="string('false')" />
+ <xsl:param name="requiresSecurityObject" select="string('false')" />
+ <xsl:param name="isUnmanagedExport" select="string('false')" />
+ <access visibility="{$visibility}" static="{$static}" declaringType="{$declaringType}" specialName="{$specialName}" runtimeSpecialName="{$runtimeSpecialName}" abstract="{$abstract}" virtual="{$virtual}" final="{$final}" vtable="{$vtable}" callingConvention="{$callingConvention}" pInvokeImplementation="{$pInvokeImplementation}" hideBySignature="{$hideBySignature}" hasSecurity="{$hasSecurity}" requiresSecurityObject="{$requiresSecurityObject}" isUnmanagedExport="{$isUnmanagedExport}" />
+ </xsl:template>
+
+ <xsl:template name="writePropertyAccess">
+ <xsl:param name="visibility" select="string('Public')" />
+ <xsl:param name="static">
+ <xsl:choose>
+ <xsl:when test="memberdata/@static">
+ <xsl:value-of select="memberdata/@static" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>false</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:param>
+ <xsl:param name="declaringType" select="containers/type/@api" />
+ <xsl:param name="specialName">
+ <xsl:choose>
+ <xsl:when test="memberdata/@special">
+ <xsl:value-of select="memberdata/@special" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>false</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:param>
+ <xsl:param name="runtimeSpecialName" select="string('false')"/>
+ <xsl:param name="abstract">
+ <xsl:choose>
+ <xsl:when test="proceduredata/@abstract">
+ <xsl:value-of select="proceduredata/@abstract" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>false</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:param>
+ <xsl:param name="virtual">
+ <xsl:choose>
+ <xsl:when test="proceduredata/@virtual">
+ <xsl:value-of select="proceduredata/@virtual" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>false</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:param>
+ <xsl:param name="final">
+ <xsl:choose>
+ <xsl:when test="proceduredata/@final">
+ <xsl:value-of select="proceduredata/@final" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>false</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:param>
+ <xsl:param name="readable" select="propertydata/@get" />
+ <xsl:param name="writeable" select="string('false')" />
+ <xsl:param name="hasDefaultValue" select="string('false')" />
+ <access visibility="{$visibility}" static="{$static}" declaringType="{$declaringType}" specialName="{$specialName}" runtimeSpecialName="{$runtimeSpecialName}" abstract="{$abstract}" virtual="{$virtual}" final="{$final}" readable="{$readable}" writeable="{$writeable}" hasDefaultValue="{$hasDefaultValue}" />
+ </xsl:template>
+
+ <xsl:template name="writeEventAccess">
+ <xsl:param name="visibility" select="string('Public')" />
+ <xsl:param name="static">
+ <xsl:choose>
+ <xsl:when test="memberdata/@static">
+ <xsl:value-of select="memberdata/@static" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>false</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:param>
+ <xsl:param name="declaringType" select="containers/type/@api" />
+ <xsl:param name="specialName">
+ <xsl:choose>
+ <xsl:when test="memberdata/@special">
+ <xsl:value-of select="memberdata/@special" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>false</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:param>
+ <xsl:param name="runtimeSpecialName" select="string('false')"/>
+ <xsl:param name="abstract">
+ <xsl:choose>
+ <xsl:when test="proceduredata/@abstract">
+ <xsl:value-of select="proceduredata/@abstract" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>false</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:param>
+ <xsl:param name="virtual">
+ <xsl:choose>
+ <xsl:when test="proceduredata/@virtual">
+ <xsl:value-of select="proceduredata/@virtual" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>false</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:param>
+ <xsl:param name="final">
+ <xsl:choose>
+ <xsl:when test="proceduredata/@final">
+ <xsl:value-of select="proceduredata/@final" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>false</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:param>
+ <access visibility="{$visibility}" static="{$static}" declaringType="{$declaringType}" specialName="{$specialName}" runtimeSpecialName="{$runtimeSpecialName}" abstract="{$abstract}" virtual="{$virtual}" final="{$final}" />
+ </xsl:template>
+
+ <xsl:template name="writeConstructorAccess">
+ <xsl:param name="visibility" select="string('Public')" />
+ <xsl:param name="static">
+ <xsl:choose>
+ <xsl:when test="memberdata/@static">
+ <xsl:value-of select="memberdata/@static" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>false</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:param>
+ <xsl:param name="declaringType" select="containers/type/@api" />
+ <xsl:param name="specialName">
+ <xsl:choose>
+ <xsl:when test="memberdata/@special">
+ <xsl:value-of select="memberdata/@special" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>false</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:param>
+ <xsl:param name="runtimeSpecialName" select="string('false')"/>
+ <access visibility="{$visibility}" static="{$static}" declaringType="{$declaringType}" specialName="{$specialName}" runtimeSpecialName="{$runtimeSpecialName}" />
+ </xsl:template>
+
+ <xsl:template name="writeMemberInheritance">
+ <xsl:choose>
+ <xsl:when test="overrides">
+ <inheritance doesOverride="true" isInherited="false" doesHide="false">
+ <baseMember name="{key('index',overrides/member/@api)/apidata/@name}" commentId="{overrides/member/@api}">
+ <type name="{key('index',overrides/member/type/@api)/apidata/@name}" namespace="{key('index',key('index',overrides/member/type/@api)/containers/namespace/@api)/apidata/@name}" commentId="{overrides/member/type/@api}" />
+ </baseMember>
+ </inheritance>
+ </xsl:when>
+ <xsl:otherwise>
+ <inheritance doesOverride="false" isInherited="false" doesHide="false">
+ <baseMember name="{apidata/@name}" commentId="{@id}">
+ <type name="{key('index',containers/type/@api)/apidata/@name}" namespace="{key('index',containers/namespace/@api)/apidata/@name}" commentId="{containers/type/@api}" />
+ </baseMember>
+ </inheritance>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template name="writeImplementedInterfaces">
+ <implementedInterfaces>
+ <xsl:for-each select="implements/type">
+ <interface name="{key('index',@api)/apidata/@name}" namespace="{key('index',key('index',@api)/containers/namespace/@api)/apidata/@name}" commentId="{@api}" >
+ <xsl:if test="specialization">
+ <parameters>
+ <xsl:for-each select="specialization/*">
+ <parameter pointerIndirections="0" byRef="false" pinned="false" sentinel="false">
+ <xsl:apply-templates select="(descendant-or-self::type | descendant-or-self::template)[1]" />
+ </parameter>
+ </xsl:for-each>
+ </parameters>
+ </xsl:if>
+ </interface>
+ </xsl:for-each>
+ </implementedInterfaces>
+ </xsl:template>
+
+ <xsl:template name="writeMembers">
+ <xsl:param name="type" select="@id" />
+ <members>
+<!--
+ <fields />
+ <constructors />
+ <methods />
+ <properties />
+ <events />
+-->
+
+ <fields>
+ <xsl:apply-templates select="(key('index',elements/element/@api) | elements/element)[apidata/@subgroup='field' and containers/type/@api=$type]" />
+ </fields>
+ <constructors>
+ <xsl:apply-templates select="key('index',elements/element/@api)[apidata/@subgroup='constructor']" />
+ </constructors>
+ <methods>
+ <xsl:apply-templates select="(key('index',elements/element/@api) | elements/element)[apidata/@subgroup='method' and containers/type/@api=$type]" />
+ </methods>
+ <properties>
+ <xsl:apply-templates select="(key('index',elements/element/@api) | elements/element)[apidata/@subgroup='property' and containers/type/@api=$type]" />
+ </properties>
+ <events>
+ <xsl:apply-templates select="(key('index',elements/element/@api) | elements/element)[apidata/@subgroup='event' and containers/type/@api=$type]" />
+ </events>
+
+ </members>
+ </xsl:template>
+
+ <xsl:template name="writeCustomAttributes">
+ <customAttributes />
+ </xsl:template>
+
+ <xsl:template name="writeParameters">
+ <parameters>
+ <xsl:for-each select="parameters/parameter">
+ <parameter name="{@name}" in="false" out="false" optional="false" retval="false" params="false">
+ <parameterTypeReference pointerIndirections="0" byRef="false" pinned="false" sentinel="false">
+ <xsl:apply-templates select="(.//type | .//template)[1]" />
+ </parameterTypeReference>
+ </parameter>
+ </xsl:for-each>
+ </parameters>
+ </xsl:template>
+
+ <xsl:template name="writeReturnValue">
+ <returnValue pointerIndirections="0" byRef="false" pinned="false" sentinel="false">
+ <xsl:choose>
+ <xsl:when test="returns">
+ <xsl:apply-templates select="(returns//type | returns//template)[1]" />
+ </xsl:when>
+ <xsl:otherwise>
+ <typeReference name="Void" namespace="System" commentId="T:System.Void" />
+ <customModifiers />
+ <arrayDefinitions />
+ </xsl:otherwise>
+ </xsl:choose>
+ </returnValue>
+ </xsl:template>
+
+ <xsl:template name="writeValue">
+ <value pointerIndirections="0" byRef="false" pinned="false" sentinel="false">
+ <xsl:choose>
+ <xsl:when test="returns">
+ <xsl:apply-templates select="(returns//type | returns//template)[1]" />
+ </xsl:when>
+ <xsl:otherwise>
+ <typeReference name="Void" namespace="System" commentId="T:System.Void" />
+ <customModifiers />
+ <arrayDefinitions />
+ </xsl:otherwise>
+ </xsl:choose>
+ </value>
+ </xsl:template>
+
+ <xsl:template match="type">
+ <typeReference name="" namespace="" commentId="{@api}" />
+ <customModifiers />
+ <arrayDefinitions />
+ </xsl:template>
+
+ <xsl:template match="template">
+ <typeReference name="{@name}" index="{@index}" target="Type" />
+ <customModifiers />
+ <arrayDefinitions />
+ </xsl:template>
+
+ <xsl:template match="templates">
+ <genericTypeParameters>
+ <xsl:for-each select="template">
+ <genericTypeParameter name="{@name}">
+ <constraints />
+ </genericTypeParameter>
+ </xsl:for-each>
+ </genericTypeParameters>
+ </xsl:template>
+
+ <!-- api entities -->
+
+ <xsl:template match="assembly">
+ <assembly>
+ <attributes name="{@name}" hashAlgorithm="SHA" culture="" sideBySideCompatible="true" retargetable="false" enableJitCompileTracking="false" enableJitCompileOptimizer="false" />
+ <version majorVersion="2" minorVersion="0" buildNumber="0" revisionNumber="0" />
+ <operatingSystems />
+ <processors />
+ <xsl:call-template name="writeCustomAttributes" />
+ <modules />
+ <assemblyReferences />
+ <files />
+ <manifestResources />
+ </assembly>
+ </xsl:template>
+
+ <xsl:template match="api[apidata/@group='namespace']">
+ <namespace>
+ <frameworks />
+ <xsl:call-template name="writeIdentity">
+ <xsl:with-param name="namespaceName" select="apidata/@name" />
+ </xsl:call-template>
+ <xsl:call-template name="writeSource" />
+ <comments />
+ <xsl:call-template name="writeCustomAttributes" />
+ <xsl:apply-templates select="key('index',elements/element/@api)[apidata/@subgroup='enumeration']" />
+ <xsl:apply-templates select="key('index',elements/element/@api)[apidata/@subgroup='structure']" />
+ <xsl:apply-templates select="key('index',elements/element/@api)[apidata/@subgroup='delegate']" />
+ <xsl:apply-templates select="key('index',elements/element/@api)[apidata/@subgroup='interface']" />
+ <xsl:apply-templates select="key('index',elements/element/@api)[apidata/@subgroup='class']" />
+ </namespace>
+ </xsl:template>
+
+ <xsl:template match="api[apidata/@group='type' and apidata/@subgroup='class']">
+ <class>
+ <frameworks />
+ <xsl:call-template name="writeTypeIdentity" />
+ <xsl:call-template name="writeSource" />
+ <xsl:call-template name="writeTypeAttributes" />
+ <inheritance>
+ <baseType name="Object" namespace="System" commentId="T:System.Object" />
+ <xsl:call-template name="writeImplementedInterfaces" />
+ </inheritance>
+ <xsl:apply-templates select="templates" />
+ <comments />
+ <xsl:call-template name="writeCustomAttributes" />
+ <xsl:call-template name="writeMembers">
+ <xsl:with-param name="type" select="@id" />
+ </xsl:call-template>
+ <PermissionSetAttributes />
+ </class>
+ </xsl:template>
+
+ <xsl:template match="api[apidata/@group='type' and apidata/@subgroup='structure']">
+ <structure>
+ <frameworks />
+ <xsl:call-template name="writeTypeIdentity" />
+ <xsl:call-template name="writeSource" />
+ <xsl:call-template name="typeIdentity" />
+ <xsl:call-template name="writeTypeAttributes">
+ <xsl:with-param name="classLayout">SequentialLayout</xsl:with-param>
+ </xsl:call-template>
+ <inheritance>
+ <baseType name="ValueType" namespace="System" commentId="T:System.ValueType" />
+ <xsl:call-template name="writeImplementedInterfaces" />
+ </inheritance>
+ <xsl:apply-templates select="templates" />
+ <comments />
+ <xsl:call-template name="writeCustomAttributes" />
+ <xsl:call-template name="writeMembers" />
+ </structure>
+ </xsl:template>
+
+
+ <xsl:template match="api[apidata/@group='type' and apidata/@subgroup='enumeration']">
+ <enumeration>
+ <frameworks />
+ <xsl:call-template name="writeTypeIdentity" />
+ <xsl:call-template name="writeSource" />
+ <xsl:call-template name="writeTypeAttributes" />
+ <inheritance>
+ <baseType name="Enum" namespace="System" commentId="T:System.Enum" />
+ <implementedInterfaces />
+ </inheritance>
+ <comments />
+ <xsl:call-template name="writeCustomAttributes" />
+ <xsl:call-template name="writeMembers" />
+ </enumeration>
+ </xsl:template>
+
+ <xsl:template match="api[apidata/@group='type' and apidata/@subgroup='delegate']">
+ <delegate>
+ <frameworks />
+ <xsl:call-template name="writeTypeIdentity" />
+ <xsl:call-template name="writeSource" />
+ <xsl:call-template name="writeTypeAttributes" />
+ <inheritance>
+ <baseType name="MulticastDelegate" namespace="System" commentId="T:System.MulticastDelegate" />
+ <implementedInterfaces />
+ </inheritance>
+ <comments />
+ <xsl:call-template name="writeCustomAttributes" />
+ <xsl:call-template name="writeMembers" />
+ <xsl:call-template name="writeParameters" />
+ <xsl:call-template name="writeReturnValue" />
+ </delegate>
+ </xsl:template>
+
+ <xsl:template match="api[apidata/@group='type' and apidata/@subgroup='interface']">
+ <interface>
+ <frameworks />
+ <xsl:call-template name="writeTypeIdentity" />
+ <xsl:call-template name="writeSource" />
+ <xsl:call-template name="writeTypeAttributes" />
+ <inheritance>
+ <baseType name="" namespace="" commentId="" />
+ <implementedInterfaces />
+ </inheritance>
+ <xsl:apply-templates select="templates" />
+ <comments />
+ <xsl:call-template name="writeCustomAttributes" />
+ <xsl:call-template name="writeMembers" />
+ </interface>
+ </xsl:template>
+
+
+ <!-- member entries -->
+
+ <xsl:template match="*[apidata/@group='member' and apidata/@subgroup='field']">
+ <field>
+ <frameworks />
+ <xsl:call-template name="writeMemberIdentity" />
+ <xsl:call-template name="writeSource" />
+ <comments />
+ <xsl:call-template name="writeCustomAttributes" />
+ <xsl:variable name="type" select="key('index',containers/type/@api)" />
+ <inheritance doesOverride="false" isInherited="false" doesHide="false">
+ <baseMember name="{apidata/@name}" commentId="{@id}">
+ <type name="{key('index',containers/type/@api)/apidata/@name}" namespace="{key('index',containers/namespace/@api)/apidata/@name}" commentId="{containers/type/@api}" />
+ </baseMember>
+ </inheritance>
+
+ <xsl:call-template name="writeMemberAccess" />
+ <value pointerIndirections="0" byRef="false" pinned="false" sentinel="false">
+ <typeReference name="{key('index',containers/type/@api)/apidata/@name}" namespace="{key('index',containers/namespace/@api)/apidata/@name}" commentId="{containers/type/@api}" />
+ <customModifiers />
+ <arrayDefinitions />
+ </value>
+ </field>
+ </xsl:template>
+
+ <xsl:template match="*[apidata/@group='member' and apidata/@subgroup='method']">
+ <method>
+ <xsl:attribute name="isOverload">
+ <xsl:choose>
+ <xsl:when test="memberdata/@overload='true'">
+ <xsl:text>true</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>false</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:attribute>
+ <xsl:attribute name="hasVarArgs">
+ <xsl:text>false</xsl:text>
+ </xsl:attribute>
+ <xsl:attribute name="isExplicitInterfaceImpl">
+ <xsl:text>false</xsl:text>
+ </xsl:attribute>
+ <frameworks />
+ <xsl:call-template name="writeMemberIdentity" />
+ <xsl:call-template name="writeSource" />
+ <xsl:call-template name="writeMethodAccess" />
+ <xsl:call-template name="writeMemberInheritance" />
+ <xsl:call-template name="writeCustomAttributes" />
+ <PermissionSetAttributes />
+ <xsl:call-template name="writeParameters" />
+ <xsl:call-template name="writeReturnValue" />
+ <explicitImplRefs />
+ <comments />
+ </method>
+ </xsl:template>
+
+ <xsl:template match="*[apidata/@group='member' and apidata/@subgroup='property']">
+ <property>
+ <xsl:attribute name="isOverload">
+ <xsl:choose>
+ <xsl:when test="memberdata/@overload='true'">
+ <xsl:text>true</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>false</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:attribute>
+ <frameworks />
+ <xsl:call-template name="writeMemberIdentity" />
+ <xsl:call-template name="writeSource" />
+ <comments />
+ <xsl:call-template name="writeCustomAttributes" />
+ <xsl:call-template name="writeMemberInheritance" />
+ <xsl:if test="propertydata/@get='true'">
+ <propertyGet>
+ <method isOverload="false" hasVarArgs="false" isExplicitInterfaceImpl="false">
+ <frameworks />
+ <xsl:call-template name="writeMemberIdentity">
+ <!-- <xsl:with-param name="memberName" select="concat('get_',apidata/@name)" /> -->
+ </xsl:call-template>
+ <xsl:call-template name="writeSource" />
+ <xsl:call-template name="writeMethodAccess" />
+ <xsl:call-template name="writeMemberInheritance" />
+ <xsl:call-template name="writeCustomAttributes" />
+ <PermissionSetAttributes />
+ <xsl:call-template name="writeParameters" />
+ <xsl:call-template name="writeReturnValue" />
+ <explicitImplRefs />
+ <comments />
+ </method>
+ </propertyGet>
+ </xsl:if>
+ <xsl:if test="propertydata/@set='true'">
+
+ </xsl:if>
+ <xsl:call-template name="writePropertyAccess" />
+ <xsl:call-template name="writeParameters" />
+ <xsl:call-template name="writeValue" />
+ </property>
+ </xsl:template>
+
+ <xsl:template match="*[apidata/@group='member' and apidata/@subgroup='event']">
+ <event>
+ <frameworks />
+ <xsl:call-template name="writeMemberIdentity" />
+ <xsl:call-template name="writeSource" />
+ <comments />
+ <xsl:call-template name="writeCustomAttributes" />
+ <xsl:call-template name="writeMemberInheritance" />
+ <eventAdd>
+ <method isOverload="false" hasVarArgs="false" isExplicitInterfaceImpl="false">
+ <frameworks />
+ <xsl:call-template name="writeMemberIdentity" />
+ <xsl:call-template name="writeSource" />
+ <xsl:call-template name="writeMethodAccess" />
+ <xsl:call-template name="writeMemberInheritance" />
+ <xsl:call-template name="writeCustomAttributes" />
+ <PermissionSetAttributes />
+ <xsl:call-template name="writeParameters" />
+ <xsl:call-template name="writeReturnValue" />
+ <explicitImplRefs />
+ <comments />
+ </method>
+ </eventAdd>
+ <eventRemove>
+ <method isOverload="false" hasVarArgs="false" isExplicitInterfaceImpl="false">
+ <frameworks />
+ <xsl:call-template name="writeMemberIdentity" />
+ <xsl:call-template name="writeSource" />
+ <xsl:call-template name="writeMethodAccess" />
+ <xsl:call-template name="writeMemberInheritance" />
+ <xsl:call-template name="writeCustomAttributes" />
+ <PermissionSetAttributes />
+ <xsl:call-template name="writeParameters" />
+ <xsl:call-template name="writeReturnValue" />
+ <explicitImplRefs />
+ <comments />
+ </method>
+ </eventRemove>
+ <xsl:call-template name="writeEventAccess" />
+ <eventHandler name="" namespace="" commentId="{eventhandler/type/@api}" />
+ </event>
+ </xsl:template>
+
+
+ <xsl:template match="*[apidata/@group='member' and apidata/@subgroup='constructor']">
+ <constructor>
+ <xsl:attribute name="isOverload">
+ <xsl:choose>
+ <xsl:when test="false()"><xsl:text>true</xsl:text></xsl:when>
+ <xsl:otherwise><xsl:text>false</xsl:text></xsl:otherwise>
+ </xsl:choose>
+ </xsl:attribute>
+ <frameworks />
+ <xsl:call-template name="writeMemberIdentity" />
+ <xsl:call-template name="writeSource" />
+ <xsl:call-template name="writeConstructorAccess" />
+ <xsl:call-template name="writeMemberInheritance" />
+ <xsl:call-template name="writeParameters" />
+ <xsl:call-template name="writeCustomAttributes" />
+ <PermissionSetAttributes />
+ <comments />
+ </constructor>
+ </xsl:template>
+
+ <xsl:template match="attribute">
+ <CustomAttribute>
+ <TypeRef name="{key('index',type/@api)/apidata/@name}" namespace="{key('index',key('index',type/@api)/containers/containingNamespace/@api)/apidata/@name}" commendId="{type/@api}" />
+ <CustomAttributeNamedValues />
+ <CustomattributeConstructor />
+ </CustomAttribute>
+ </xsl:template>
+
+ <xsl:template name="typeIdentity">
+ <identity namespaceName="{key('index',containers/namespace/@api)/apidata/@name}" typeName="{apidata/@name}" memberName="" commentId="{@id}" textId="" />
+ </xsl:template>
+
+ <xsl:template name="memberIdentity">
+ <identity namespaceName="{key('index',containers/namespace/@api)/apidata/@name}" typeName="{key('index',containers/type/@api)/apidata/@name}" memberName="{apidata/@name}" commentId="{@id}" textId="" />
+ </xsl:template>
+
+ <xsl:template name="source">
+ <source assembly="{containers/library/@assembly}" module="{containers/library/@module}.dll" />
+ </xsl:template>
+
+ <xsl:template match="templates">
+ <genericTypeParameters>
+ <xsl:for-each select="template">
+ <genericTypeParameter name="{@name}">
+ <constraints />
+ </genericTypeParameter>
+ </xsl:for-each>
+ </genericTypeParameters>
+ </xsl:template>
+
+ <xsl:template name="typeReference">
+ <xsl:attribute name="pointerIndirections">
+ <xsl:value-of select="count(pointerTo)" />
+ </xsl:attribute>
+ <xsl:attribute name="byRef">
+ <xsl:value-of select="type/@ref" />
+ </xsl:attribute>
+ <xsl:attribute name="pinned">
+ <xsl:text>false</xsl:text>
+ </xsl:attribute>
+ <typeReference name="{key('index',.//type[1]/@api)/apidata/@name}" namespace="{key('index',key('index',.//type[1]/@api)/containers/namespace/@api)/apidata/@name}" commendId="{.//type[1]/@api}" />
+ <customModifiers />
+ <arrayDefinitions>
+ <xsl:if test="arrayOf">
+ <xsl:attribute name="rank">
+ <xsl:value-of select="arrayOf/@rank" />
+ </xsl:attribute>
+ <dimensions />
+ </xsl:if>
+ </arrayDefinitions>
+ </xsl:template>
+
+ <xsl:template name="visibility">
+ <xsl:param name="visibility" />
+ <xsl:attribute name="visibility">
+ <xsl:choose>
+ <xsl:when test="$visibility='public'">
+ <xsl:text>Public</xsl:text>
+ </xsl:when>
+ <xsl:when test="$visibility='family'">
+ <xsl:text>Family</xsl:text>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:attribute>
+ </xsl:template>
+
+</xsl:stylesheet> \ No newline at end of file
diff --git a/tools/Sandcastle/ProductionTransforms/ReflectionToChmIndex.xsl b/tools/Sandcastle/ProductionTransforms/ReflectionToChmIndex.xsl
new file mode 100644
index 0000000..6e7aa70
--- /dev/null
+++ b/tools/Sandcastle/ProductionTransforms/ReflectionToChmIndex.xsl
@@ -0,0 +1,77 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.1">
+
+ <xsl:output method="text" encoding="iso-8859-1" />
+
+ <xsl:key name="index" match="/reflection/apis/api" use="@id" />
+
+ <xsl:template match="/">
+ <xsl:text>&lt;!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML/EN"&gt;&#x0a;</xsl:text>
+ <xsl:text>&lt;HTML&gt;&#x0a;</xsl:text>
+ <xsl:text> &lt;BODY&gt;&#x0a;</xsl:text>
+ <xsl:text> &lt;UL&gt;&#x0a;</xsl:text>
+
+ <xsl:apply-templates select="/reflection/apis/api"/>
+
+ <xsl:text> &lt;/UL&gt;&#x0a;</xsl:text>
+ <xsl:text> &lt;/BODY&gt;&#x0a;</xsl:text>
+ <xsl:text>&lt;/HTML&gt;&#x0a;</xsl:text>
+ </xsl:template>
+
+ <xsl:template match="api[apidata/@group='namespace']">
+ <xsl:call-template name="createIndexEntry">
+ <xsl:with-param name="text" select="concat(apidata/@name,' namespace')" />
+ <xsl:with-param name="file" select="file/@name" />
+ </xsl:call-template>
+ </xsl:template>
+
+ <xsl:template match="api[apidata/@group='type']">
+ <xsl:variable name="namespace" select="key('index',containers/namespace/@api)/apidata/@name" />
+ <xsl:call-template name="createIndexEntry">
+ <xsl:with-param name="text" select="concat(apidata/@name,' ',apidata/@subgroup)" />
+ <xsl:with-param name="file" select="file/@name" />
+ </xsl:call-template>
+ <xsl:call-template name="createIndexEntry">
+ <xsl:with-param name="text" select="concat($namespace,'.',apidata/@name,' ',apidata/@subgroup)" />
+ <xsl:with-param name="file" select="file/@name" />
+ </xsl:call-template>
+ </xsl:template>
+
+ <xsl:template match="api[apidata/@group='member' and topicdata/@notopic !='']" >
+ <xsl:variable name="type" select="key('index',containers/type/@api)" />
+ <xsl:if test="not(apidata/@subgroup='constructor')">
+ <xsl:call-template name="createIndexEntry">
+ <xsl:with-param name="text">
+ <xsl:value-of select="concat(apidata/@name,' ',apidata/@subgroup)" />
+ </xsl:with-param>
+ <xsl:with-param name="file" select="file/@name" />
+ </xsl:call-template>
+ </xsl:if>
+ <xsl:call-template name="createIndexEntry">
+ <xsl:with-param name="text">
+ <xsl:choose>
+ <xsl:when test="apidata/@subgroup='constructor'">
+ <xsl:value-of select="concat($type/apidata/@name,' ',$type/apidata/@subgroup,', constructor')" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="concat($type/apidata/@name,'.',apidata/@name,' ',apidata/@subgroup)" />
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:with-param>
+ <xsl:with-param name="file" select="file/@name" />
+ </xsl:call-template>
+ </xsl:template>
+
+ <xsl:template match="api" />
+
+ <xsl:template name="createIndexEntry">
+ <xsl:param name="text" />
+ <xsl:param name="file" />
+ <xsl:text> &lt;LI&gt;&lt;OBJECT type="text/sitemap"&gt;&#x0a;</xsl:text>
+ <xsl:text> &lt;param name="Name" value="</xsl:text><xsl:value-of select="$text" /><xsl:text>"&gt;&#x0a;</xsl:text>
+ <xsl:text> &lt;param name="Local" value="html/</xsl:text><xsl:value-of select="$file" /><xsl:text>.htm"&gt;&#x0a;</xsl:text>
+ <xsl:text> &lt;/OBJECT&gt;&lt;LI&gt;&#x0a;</xsl:text>
+
+ </xsl:template>
+
+</xsl:stylesheet>
diff --git a/tools/Sandcastle/ProductionTransforms/ReflectionToChmProject.xsl b/tools/Sandcastle/ProductionTransforms/ReflectionToChmProject.xsl
new file mode 100644
index 0000000..cde5a36
--- /dev/null
+++ b/tools/Sandcastle/ProductionTransforms/ReflectionToChmProject.xsl
@@ -0,0 +1,47 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.1">
+
+ <xsl:param name="project" select="string('test')" />
+
+ <xsl:output method="text" encoding="iso-8859-1" />
+
+ <xsl:key name="index" match="/reflection/apis/api" use="@id" />
+
+ <xsl:variable name="topic">
+ <xsl:choose>
+ <xsl:when test="/reflection/apis/api[apidata/@group='root']">
+ <xsl:value-of select="/reflection/apis/api[apidata/@group='root'][1]/file/@name"/>
+ </xsl:when>
+ <xsl:when test="/reflection/apis/api[apidata/@group='namespace']">
+ <xsl:value-of select="/reflection/apis/api[apidata/@group='namespace'][1]/file/@name"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="/reflection/apis/api[apidata/@group='type'][1]/file/@name"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <xsl:template match="/">
+ <xsl:text>[OPTIONS]&#x0a;</xsl:text>
+ <xsl:text>Compatibility=1.1 or later&#x0a;</xsl:text>
+ <xsl:text>Compiled file=</xsl:text><xsl:value-of select="$project" /><xsl:text>.chm&#x0a;</xsl:text>
+ <xsl:text>Contents file=</xsl:text><xsl:value-of select="$project" /><xsl:text>.hhc&#x0a;</xsl:text>
+ <xsl:text>Index file=</xsl:text><xsl:value-of select="$project" /><xsl:text>.hhk&#x0a;</xsl:text>
+ <xsl:text>Default Topic=html/</xsl:text><xsl:value-of select="$topic" /><xsl:text>.htm&#x0a;</xsl:text>
+ <!-- <xsl:text>Display compile progress=No&#x0a;</xsl:text> -->
+ <xsl:text>Full-text search=Yes&#x0a;</xsl:text>
+ <xsl:text>Language=0x409 English (United States)&#x0a;</xsl:text>
+ <xsl:text>Title=</xsl:text><xsl:value-of select="$project" /><xsl:text>&#x0a;</xsl:text>
+
+ <xsl:text>[FILES]&#x0a;</xsl:text>
+ <xsl:text>icons\*.gif&#x0a;</xsl:text>
+ <xsl:text>art\*.gif&#x0a;</xsl:text>
+ <xsl:text>media\*.gif&#x0a;</xsl:text>
+ <xsl:text>scripts\*.js&#x0a;</xsl:text>
+ <xsl:text>styles\*.css&#x0a;</xsl:text>
+ <xsl:text>html\*.htm&#x0a;</xsl:text>
+
+ <xsl:text>[INFOTYPES]&#x0a;</xsl:text>
+ </xsl:template>
+
+</xsl:stylesheet>
diff --git a/tools/Sandcastle/ProductionTransforms/ReflectionToManifest.xsl b/tools/Sandcastle/ProductionTransforms/ReflectionToManifest.xsl
new file mode 100644
index 0000000..b12d480
--- /dev/null
+++ b/tools/Sandcastle/ProductionTransforms/ReflectionToManifest.xsl
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.1">
+
+ <xsl:output indent="yes" encoding="UTF-8" />
+
+ <xsl:key name="index" match="/reflection/apis/api" use="@id" />
+
+ <xsl:template match="/">
+ <topics>
+ <xsl:apply-templates select="/reflection/apis/api" />
+ </topics>
+ </xsl:template>
+
+ <!-- namespace and member topics -->
+ <xsl:template match="api">
+ <xsl:if test="not(topicdata/@notopic)">
+ <topic id="{@id}" />
+ </xsl:if>
+ </xsl:template>
+
+</xsl:stylesheet>
diff --git a/tools/Sandcastle/ProductionTransforms/TocToChmContents.xsl b/tools/Sandcastle/ProductionTransforms/TocToChmContents.xsl
new file mode 100644
index 0000000..82e034a
--- /dev/null
+++ b/tools/Sandcastle/ProductionTransforms/TocToChmContents.xsl
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- Doc Studio Contents to HTML Help Compiler Contents Transform
+
+ Invoke with: xsltransform TocToChmContents.xsl toc.xml [/arg:html=html-dir] /out:output.hhc
+
+ - comments - specifies the directory where the HTML files are stored.
+
+ NOTE: The output looks like HTML, but it isn't. Whitespace is significant.
+-->
+
+<xsl:stylesheet version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:msxsl="urn:schemas-microsoft-com:xslt"
+ xmlns:ddue="http://ddue.schemas.microsoft.com/authoring/2003/5">
+
+ <msxsl:script language="C#" implements-prefix="ddue">
+ <msxsl:using namespace="System.Xml" />
+ <msxsl:using namespace="System.Xml.XPath" />
+ <![CDATA[
+ public static string getTitle(string fileName) {
+ XPathDocument doc = new XPathDocument(fileName);
+ XPathNavigator node = doc.CreateNavigator().SelectSingleNode("/html/head/title");
+ if (node != null)
+ return node.Value;
+ else
+ return String.Empty;
+ }
+ ]]>
+ </msxsl:script>
+
+
+ <xsl:param name="html" select="string('Output/html')"/>
+
+ <xsl:output method="text" encoding="utf-8"/>
+
+ <xsl:template match="/">
+ <xsl:text>&lt;!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML/EN"&gt;&#x0a;</xsl:text>
+ <xsl:text>&lt;HTML&gt;&#x0a;</xsl:text>
+ <xsl:text> &lt;BODY&gt;&#x0a;</xsl:text>
+ <xsl:apply-templates select="topics"/>
+ <xsl:text> &lt;/BODY&gt;&#x0a;</xsl:text>
+ <xsl:text>&lt;/HTML&gt;&#x0a;</xsl:text>
+ </xsl:template>
+
+ <xsl:template match="topics">
+ <xsl:call-template name="parentNode"/>
+ </xsl:template>
+
+ <xsl:template name="parentNode">
+ <xsl:if test="topic">
+ <xsl:call-template name="indent"/>
+ <xsl:text>&lt;UL&gt;&#x0a;</xsl:text>
+ <xsl:apply-templates select="topic"/>
+ <xsl:call-template name="indent"/>
+ <xsl:text>&lt;/UL&gt;&#x0a;</xsl:text>
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template match="topic">
+ <xsl:call-template name="indent"/>
+ <xsl:text><![CDATA[<LI><OBJECT type="text/sitemap">]]>&#x0a;</xsl:text>
+ <xsl:call-template name="indent"/>
+ <xsl:text> &lt;param name="Name" value="</xsl:text>
+ <xsl:value-of select="ddue:getTitle(concat($html,'/', @file, '.htm'))"/>
+ <xsl:text>"&gt;&#x0a;</xsl:text>
+ <xsl:call-template name="indent"/>
+ <xsl:text> &lt;param name="Local" value="html\</xsl:text>
+ <xsl:value-of select="@file"/>
+ <xsl:text>.htm"&gt;&#x0a;</xsl:text>
+ <xsl:call-template name="indent"/>
+ <xsl:text><![CDATA[</OBJECT></LI>]]>&#x0a;</xsl:text>
+
+ <xsl:call-template name="parentNode"/>
+ </xsl:template>
+
+ <xsl:template name="indent"><xsl:for-each select="ancestor::*"><xsl:text>&#x20;&#x20;</xsl:text></xsl:for-each></xsl:template>
+
+</xsl:stylesheet>
diff --git a/tools/Sandcastle/ProductionTransforms/TocToHxsContents.xsl b/tools/Sandcastle/ProductionTransforms/TocToHxsContents.xsl
new file mode 100644
index 0000000..44a4484
--- /dev/null
+++ b/tools/Sandcastle/ProductionTransforms/TocToHxsContents.xsl
@@ -0,0 +1,54 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.1">
+
+ <xsl:output indent="yes" encoding="UTF-8" doctype-system="MS-Help://Hx/Resources/HelpTOC.dtd" />
+
+ <xsl:param name="segregated" />
+ <xsl:param name="includeIds" />
+
+ <xsl:template match="/">
+ <HelpTOC DTDVersion="1.0">
+ <xsl:apply-templates select="/topics" />
+ </HelpTOC>
+ </xsl:template>
+
+ <xsl:template match="topic">
+ <HelpTOCNode>
+ <xsl:if test="boolean($includeIds)">
+ <xsl:attribute name="Id">
+ <xsl:value-of select="@id"/>
+ </xsl:attribute>
+ </xsl:if>
+ <xsl:choose>
+ <xsl:when test="@file">
+ <xsl:attribute name="Url">
+ <xsl:choose>
+ <xsl:when test="boolean($segregated)">
+ <xsl:value-of select="concat('ms-help:/../',@project,'/html/',@file,'.htm')" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="concat('html\',@file,'.htm')" />
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:attribute>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:attribute name="Title">
+ <xsl:value-of select="@id" />
+ </xsl:attribute>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:apply-templates />
+ </HelpTOCNode>
+ </xsl:template>
+
+ <xsl:template match="stoc">
+ <HelpTOCNode NodeType="TOC" Url="{@project}" />
+ </xsl:template>
+
+ <xsl:template match="stopic">
+ <HelpTOCNode Url="ms-help:/../{@project}/html/{@file}.htm" Id="{@id}">
+ <xsl:apply-templates />
+ </HelpTOCNode>
+ </xsl:template>
+</xsl:stylesheet>
diff --git a/tools/Sandcastle/ProductionTransforms/Vs2005TocToDsToc.xsl b/tools/Sandcastle/ProductionTransforms/Vs2005TocToDsToc.xsl
new file mode 100644
index 0000000..2868a29
--- /dev/null
+++ b/tools/Sandcastle/ProductionTransforms/Vs2005TocToDsToc.xsl
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- This transform turns a mref TOC produced by CreateVSToc.xsl into a format suitable for TocToSitemap.xsl
+ We're also using this step to resolve topic titles and urls.
+
+ Invoke with:
+ xsltransform /xsl:FixMrefToc.xsl /arg:topicInfo=topic-info-dir /out:mreftoc.xml
+-->
+
+<xsl:stylesheet version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:ddue="http://ddue.schemas.microsoft.com/authoring/2003/5">
+
+ <xsl:param name="topicInfo" select="'Temp\TopicInfo'"/>
+
+ <xsl:output indent="yes" encoding="utf-8"/>
+
+ <xsl:namespace-alias stylesheet-prefix="ddue" result-prefix="#default"/>
+
+ <xsl:template match="/topics">
+ <tableOfContents>
+ <xsl:apply-templates/>
+ </tableOfContents>
+ </xsl:template>
+
+ <xsl:template match="topic">
+ <topic>
+ <xsl:attribute name="id">
+ <xsl:value-of select="@file"/>
+ </xsl:attribute>
+ <xsl:attribute name="url">
+ <xsl:value-of select="document(concat($topicInfo, '/', @file, '.xml'))//pageUrl[1]"/>
+ </xsl:attribute>
+ <xsl:attribute name="title">
+ <xsl:value-of select="document(concat($topicInfo, '/', @file, '.xml'))//title[1]"/>
+ </xsl:attribute>
+ <xsl:apply-templates/>
+ </topic>
+ </xsl:template>
+
+</xsl:stylesheet>