summaryrefslogtreecommitdiffstats
path: root/src/boost/tools/docca/include
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 18:45:59 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 18:45:59 +0000
commit19fcec84d8d7d21e796c7624e521b60d28ee21ed (patch)
tree42d26aa27d1e3f7c0b8bd3fd14e7d7082f5008dc /src/boost/tools/docca/include
parentInitial commit. (diff)
downloadceph-upstream.tar.xz
ceph-upstream.zip
Adding upstream version 16.2.11+ds.upstream/16.2.11+dsupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/boost/tools/docca/include')
-rw-r--r--src/boost/tools/docca/include/docca/assemble-quickbook.xsl20
-rw-r--r--src/boost/tools/docca/include/docca/base-extract-xml-pages.xsl427
-rw-r--r--src/boost/tools/docca/include/docca/base-stage1.xsl590
-rw-r--r--src/boost/tools/docca/include/docca/common.xsl107
-rw-r--r--src/boost/tools/docca/include/docca/config.xsl47
-rw-r--r--src/boost/tools/docca/include/docca/debug-friendly-quickbook.xsl23
-rw-r--r--src/boost/tools/docca/include/docca/emphasized-types.xsl43
-rw-r--r--src/boost/tools/docca/include/docca/extract-xml-pages.xsl12
-rw-r--r--src/boost/tools/docca/include/docca/stage1.xsl11
-rw-r--r--src/boost/tools/docca/include/docca/stage2.xsl228
10 files changed, 1508 insertions, 0 deletions
diff --git a/src/boost/tools/docca/include/docca/assemble-quickbook.xsl b/src/boost/tools/docca/include/docca/assemble-quickbook.xsl
new file mode 100644
index 000000000..fe39870a0
--- /dev/null
+++ b/src/boost/tools/docca/include/docca/assemble-quickbook.xsl
@@ -0,0 +1,20 @@
+<!-- Concatenate all the text files from a directory into one big file -->
+<xsl:stylesheet version="3.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ exclude-result-prefixes="xs">
+
+ <xsl:output method="text"/>
+
+ <!-- TODO: remove this coupling; should be configured in the build file somehow
+ (add support for Saxon parameter-passing in the build?) -->
+ <xsl:param name="input-dir" select="'stage2/results'"/>
+
+ <xsl:template match="page">
+ <xsl:copy-of select="unparsed-text(concat($input-dir, '/', @href))"/>
+ <xsl:apply-templates select="page"/>
+ <!-- Two line breaks before to ensure it doesn't get absorbed into a preceding list -->
+ <xsl:text>&#xA;&#xA;[endsect]&#xA;</xsl:text>
+ </xsl:template>
+
+</xsl:stylesheet>
diff --git a/src/boost/tools/docca/include/docca/base-extract-xml-pages.xsl b/src/boost/tools/docca/include/docca/base-extract-xml-pages.xsl
new file mode 100644
index 000000000..685380c4d
--- /dev/null
+++ b/src/boost/tools/docca/include/docca/base-extract-xml-pages.xsl
@@ -0,0 +1,427 @@
+<xsl:stylesheet version="3.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xmlns:d="http://github.com/vinniefalco/docca"
+ exclude-result-prefixes="xs d"
+ expand-text="yes">
+
+ <!-- TODO: make sure this doesn't screw up any formatting -->
+ <!-- NEW TODO: verify we don't need/want this -->
+ <!--
+ <xsl:output indent="yes"/>
+ -->
+
+ <xsl:include href="common.xsl"/>
+
+ <xsl:key name="visible-memberdefs-by-id"
+ match="memberdef[$include-private-members or not(@prot eq 'private')]"
+ use="@id"/>
+
+ <xsl:key name="elements-by-refid" match="compound | member" use="@refid"/>
+
+ <xsl:variable name="index-xml" select="/"/>
+
+ <xsl:template match="/">
+ <index>
+ <xsl:apply-templates select="/doxygenindex/compound"/>
+ </index>
+ <!-- Testing the ID-related functions
+ <xsl:value-of select="replace(d:extract-ns('put'), '::$', '')"/>
+ <xsl:text>&#xA;</xsl:text>
+ <xsl:value-of select="replace(d:extract-ns('foobar::parser::put'), '::$', '')"/>
+ <xsl:text>&#xA;</xsl:text>
+ <xsl:value-of select="d:extract-ns('foobar::parser::put&lt;foo::bar, bat::bang>')"/>
+ <xsl:text>&#xA;</xsl:text>
+ <xsl:value-of select="d:strip-ns('boost::beast::http::parser::basic_parser&lt; foo::isRequest, bar::parser &gt;')"/>
+ <xsl:text>&#xA;</xsl:text>
+ <xsl:value-of select="d:strip-doc-ns('boost::beast::http::parser::basic_parser&lt; foo::isRequest, bar::parser &gt;')"/>
+ <xsl:text>&#xA;</xsl:text>
+ <xsl:text>&#xA;</xsl:text>
+ <xsl:value-of select="d:make-id('boost::beast::http::parser::basic_parser&lt; foo::isRequest, bar::parser &gt;')"/>
+ -->
+ </xsl:template>
+
+ <!-- Default implementation; can be customized/overridden -->
+ <xsl:function name="d:should-ignore-compound">
+ <xsl:param name="compound" as="element(compound)"/>
+ <xsl:sequence select="false()"/>
+ </xsl:function>
+
+ <xsl:template match="compound[d:should-ignore-compound(.)]"/>
+ <xsl:template match="compound">
+ <!-- Load each input file only once -->
+ <xsl:variable name="source-doc" select="d:get-source-doc(.)"/>
+ <!-- Ignore private classes unless private members are enabled -->
+ <xsl:if test="$include-private-members or not($source-doc/doxygen/compounddef/@prot eq 'private')">
+ <!-- Look up memberdefs (and constrain by visibility) only once -->
+ <xsl:variable name="memberdefs" select="key('visible-memberdefs-by-id', member/@refid, $source-doc)"/>
+ <!-- Create a filtered copy of members within their minimal context, listing only the visible ones -->
+ <xsl:variable name="visible-members" as="element(member)*">
+ <xsl:variable name="compound" as="element()">
+ <compound kind="{@kind}" refid="{@refid}">
+ <name>{name}</name>
+ <xsl:copy-of select="member[@refid = $memberdefs/@id]"/>
+ </compound>
+ </xsl:variable>
+ <xsl:sequence select="$compound/member"/>
+ </xsl:variable>
+ <xsl:apply-templates mode="create-page" select=".">
+ <xsl:with-param name="source-doc" select="$source-doc" tunnel="yes"/>
+ <xsl:with-param name="memberdefs" select="$memberdefs" tunnel="yes"/>
+ <xsl:with-param name="visible-members" select="$visible-members" tunnel="yes"/>
+ </xsl:apply-templates>
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:function name="d:get-source-doc" as="document-node()">
+ <xsl:param name="compound" as="element(compound)"/>
+ <xsl:sequence select="document($compound/@refid||'.xml', $index-xml)"/>
+ </xsl:function>
+
+ <!-- Split up the content into class, struct, and member pages -->
+ <xsl:template mode="create-page" match="*"/>
+ <xsl:template mode="create-page" match="compound[@kind = 'namespace']">
+ <xsl:apply-templates mode="child-pages" select="."/>
+ </xsl:template>
+ <xsl:template mode="create-page" match="compound[@kind = ('class','struct')]
+ | compound/member">
+ <xsl:variable name="page-id" as="xs:string">
+ <xsl:apply-templates mode="page-id" select="."/>
+ </xsl:variable>
+ <page id="{$page-id}" href="{$page-id}.xml">
+ <xsl:result-document href="xml-pages/{$page-id}.xml">
+ <xsl:apply-templates mode="page-content" select=".">
+ <xsl:with-param name="page-id" select="$page-id" tunnel="yes"/>
+ </xsl:apply-templates>
+ </xsl:result-document>
+ <xsl:apply-templates mode="child-pages" select="."/>
+ </page>
+ </xsl:template>
+
+ <!-- Create the member page for each child (or, if overloaded, the overload-list page) -->
+ <xsl:template mode="child-pages" match="compound">
+ <xsl:param name="visible-members" tunnel="yes"/>
+ <!-- Create a page for each unique member name -->
+ <xsl:for-each select="$visible-members[not(name = preceding-sibling::member/name)]">
+ <xsl:apply-templates mode="create-page" select=".">
+ <xsl:with-param name="is-overload-list-page" select="d:is-overloaded(.)" tunnel="yes"/>
+ </xsl:apply-templates>
+ </xsl:for-each>
+ </xsl:template>
+
+ <!-- A member page doesn't have children, unless it is an overload-list page -->
+ <xsl:template mode="child-pages" match="compound/member">
+ <xsl:param name="is-overload-list-page" tunnel="yes"/>
+ <xsl:if test="$is-overload-list-page">
+ <xsl:apply-templates mode="create-page" select="d:overloaded-members(.)">
+ <xsl:with-param name="is-overload-list-page" select="false()" tunnel="yes"/>
+ </xsl:apply-templates>
+ </xsl:if>
+ </xsl:template>
+
+
+ <xsl:template mode="page-id" match="compound">{d:make-id(name)}</xsl:template>
+ <xsl:template mode="page-id" match="member">
+ <xsl:param name="is-overload-list-page" tunnel="yes"/>
+ <xsl:value-of>
+ <xsl:apply-templates mode="base-member-page-id" select="."/>
+ <!-- Append the overload-specific suffix, if applicable -->
+ <xsl:if test="d:is-overloaded(.) and not($is-overload-list-page)">
+ <xsl:value-of select="d:make-id('.overload'||d:overload-position(.))"/>
+ </xsl:if>
+ </xsl:value-of>
+ </xsl:template>
+
+ <xsl:function name="d:is-overloaded" as="xs:boolean">
+ <xsl:param name="member" as="element(member)"/>
+ <xsl:sequence select="exists(d:overloaded-members($member)[2])"/>
+ </xsl:function>
+
+ <xsl:function name="d:overload-position" as="xs:integer">
+ <xsl:param name="member" as="element(member)"/>
+ <xsl:sequence select="1 + count($member/preceding-sibling::member[name eq $member/name])"/>
+ </xsl:function>
+
+ <xsl:function name="d:overloaded-members" as="element(member)+">
+ <xsl:param name="member" as="element(member)"/>
+ <xsl:sequence select="$member/../member[name eq $member/name]"/>
+ </xsl:function>
+
+
+ <xsl:template mode="base-member-page-id" priority="1"
+ match="compound[@kind eq 'namespace']
+ /member">{d:make-id(../name||'::'||name)}</xsl:template>
+ <xsl:template mode="base-member-page-id" match="compound/member">{d:make-id(../name||'.' ||name)}</xsl:template>
+
+
+ <!-- The content for a class or struct is the original source document, pared down some -->
+ <xsl:template mode="page-content" match="compound">
+ <xsl:param name="source-doc" tunnel="yes"/>
+ <xsl:apply-templates mode="compound-page" select="$source-doc"/>
+ </xsl:template>
+
+ <!-- By default, copy everything -->
+ <xsl:template mode="compound-page" match="@* | node()" name="copy-in-compound-page">
+ <xsl:copy>
+ <xsl:apply-templates mode="#current" select="@*"/>
+ <xsl:apply-templates mode="compound-page-insert" select="."/>
+ <xsl:apply-templates mode="#current"/>
+ </xsl:copy>
+ </xsl:template>
+
+ <!-- By default, don't insert anything -->
+ <xsl:template mode="compound-page-insert" match="*"/>
+
+ <xsl:template mode="compound-page" match="listofallmembers"/>
+
+ <xsl:template mode="compound-page" match="memberdef/@*"/>
+
+ <!-- But directly inside <memberdef>, don't copy anything... -->
+ <xsl:template mode="compound-page" match="memberdef/node()"/>
+
+ <!-- ...except for <name>, <briefdescription>, and <type> -->
+ <xsl:template mode="compound-page" match="memberdef/name
+ | memberdef/briefdescription
+ | memberdef/type" priority="1">
+ <xsl:call-template name="copy-in-compound-page"/>
+ </xsl:template>
+
+ <!-- Insert a reference to each child member's page ID -->
+ <xsl:template mode="compound-page-insert" match="memberdef">
+ <xsl:attribute name="d:page-refid" select="d:make-id(/doxygen/compounddef/compoundname||'.'||name)"/>
+ </xsl:template>
+
+ <!-- Alternative implementation in case we need to start controlling whitespace more
+ <xsl:template mode="compound-page" match="memberdef">
+ <memberdef>
+ <xsl:text>&#xA;</xsl:text>
+ <xsl:copy-of select="name"/>
+ <xsl:text>&#xA;</xsl:text>
+ <xsl:copy-of select="briefdescription"/>
+ </memberdef>
+ </xsl:template>
+ -->
+
+ <!-- The content for a member page is a subset of the source document -->
+ <xsl:template mode="page-content" match="compound/member">
+ <xsl:param name="is-overload-list-page" tunnel="yes"/>
+ <xsl:choose>
+ <xsl:when test="$is-overload-list-page">
+ <!-- For the overload list page, include the content for every like-named member -->
+ <xsl:apply-templates mode="list-page" select=".">
+ <xsl:with-param name="applicable-members" select="d:overloaded-members(.)" tunnel="yes"/>
+ </xsl:apply-templates>
+ </xsl:when>
+ <xsl:otherwise>
+ <!-- Otherwise, this page is just for one implementation (whether overloaded or not) -->
+ <xsl:apply-templates mode="member-page" select="."/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template mode="list-page member-page" match="member" priority="2">
+ <xsl:param name="applicable-members" as="element(member)+" select="." tunnel="yes"/>
+ <xsl:param name="source-doc" tunnel="yes"/>
+ <xsl:param name="memberdefs" tunnel="yes"/>
+ <xsl:apply-templates mode="#current" select="$source-doc">
+ <xsl:with-param name="target-memberdefs"
+ select="$memberdefs[@id = $applicable-members/@refid]"
+ tunnel="yes"/>
+ <xsl:with-param name="member" select="." tunnel="yes"/>
+ </xsl:apply-templates>
+ </xsl:template>
+
+ <!-- Always copy the name of the parent compound -->
+ <xsl:template mode="list-page member-page" match="compoundname" priority="2">
+ <xsl:copy-of select="."/>
+ </xsl:template>
+
+ <!-- Otherwise, only copy an element if it's the target member or one of its ancestors -->
+ <xsl:template mode="list-page member-page" match="*" priority="1">
+ <xsl:param name="target-memberdefs" tunnel="yes"/>
+ <xsl:if test=". intersect $target-memberdefs/ancestor-or-self::*">
+ <xsl:next-match/>
+ </xsl:if>
+ </xsl:template>
+
+ <!-- By default, copy everything -->
+ <xsl:template mode="list-page" match="@* | node()">
+ <xsl:copy>
+ <xsl:apply-templates mode="#current" select="@*"/>
+ <xsl:apply-templates mode="list-page-insert" select="."/>
+ <xsl:apply-templates mode="#current"/>
+ </xsl:copy>
+ </xsl:template>
+
+ <!-- By default, don't insert anything -->
+ <xsl:template mode="list-page-insert" match="*"/>
+
+
+ <!-- By default, copy everything -->
+ <xsl:template mode="member-page
+ copy-member-content" match="@* | node()">
+ <xsl:copy>
+ <xsl:apply-templates mode="#current" select="@*"/>
+ <xsl:apply-templates mode="member-page-insert" select="."/>
+ <xsl:apply-templates mode="#current"/>
+ <xsl:apply-templates mode="member-page-append" select="."/>
+ </xsl:copy>
+ </xsl:template>
+
+ <!-- By default, don't insert or append anything -->
+ <xsl:template mode="member-page-insert
+ member-page-append" match="*"/>
+
+ <!-- Strip out extraneous whitespace -->
+ <xsl:template mode="list-page member-page" match="compounddef/text() | sectiondef/text()"/>
+
+ <!-- Switch to an unfiltered copy once we're done filtering out the undesired elements -->
+ <xsl:template mode="list-page member-page" match="memberdef/node()" priority="2">
+ <xsl:apply-templates mode="copy-member-content" select="."/>
+ </xsl:template>
+
+ <!-- Add the page ID to the top of all page types -->
+ <xsl:template mode="compound-page-insert
+ member-page-insert
+ list-page-insert" match="/doxygen" priority="2">
+ <xsl:param name="page-id" tunnel="yes"/>
+ <xsl:attribute name="d:page-id" select="$page-id"/>
+ <xsl:next-match/>
+ </xsl:template>
+
+ <!-- Also, if applicable, insert the overload position and/or base compound reference of this member -->
+ <xsl:template mode="member-page-insert" match="/doxygen" priority="1">
+ <xsl:param name="member" tunnel="yes"/>
+ <xsl:if test="d:is-overloaded($member)">
+ <xsl:attribute name="d:overload-position" select="d:overload-position($member)"/>
+ <xsl:attribute name="d:overload-size" select="count(d:overloaded-members($member))"/>
+ </xsl:if>
+ <xsl:if test="$member[not(starts-with(@refid, ../@refid))]">
+ <xsl:variable name="base-compound" select="$index-xml/*/compound[starts-with($member/@refid, @refid)]
+ [not(d:should-ignore-compound(.))]"/>
+ <xsl:apply-templates mode="base-compound-atts" select="$base-compound"/>
+ </xsl:if>
+ <xsl:next-match/>
+ </xsl:template>
+
+ <xsl:template mode="base-compound-atts" match="compound">
+ <xsl:attribute name="d:base-compound-name" select="d:strip-doc-ns(name)"/>
+ <xsl:attribute name="d:base-compound-refid">
+ <xsl:apply-templates mode="page-id" select="."/>
+ </xsl:attribute>
+ </xsl:template>
+
+ <!-- Make data available for the typedef tables, if applicable -->
+ <xsl:template mode="member-page-append" match="memberdef[@kind eq 'typedef']
+ [type/ref]
+ [not(contains(type, '*'))]">
+ <xsl:for-each select="type/ref">
+ <d:referenced-typedef-class>
+ <xsl:variable name="compound" select="d:get-target-element(.)[self::compound]"/>
+ <xsl:apply-templates mode="compound-page" select="$compound ! d:get-source-doc(.)/*/compounddef"/>
+ </d:referenced-typedef-class>
+ </xsl:for-each>
+ </xsl:template>
+
+ <!-- Finally, add the page type -->
+ <xsl:template mode="compound-page-insert" match="/doxygen">
+ <xsl:attribute name="d:page-type" select="'compound'"/>
+ </xsl:template>
+ <xsl:template mode="member-page-insert" match="/doxygen">
+ <xsl:attribute name="d:page-type" select="'member'"/>
+ </xsl:template>
+ <xsl:template mode="list-page-insert" match="/doxygen">
+ <xsl:attribute name="d:page-type" select="'overload-list'"/>
+ </xsl:template>
+
+ <!-- For overload-list pages, include the page id for each member -->
+ <xsl:template mode="list-page-insert" match="memberdef">
+ <xsl:param name="applicable-members" tunnel="yes"/>
+ <xsl:variable name="this-id" select="@id"/>
+ <xsl:variable name="original-member" select="$applicable-members[@refid eq $this-id]"/>
+ <xsl:attribute name="d:page-refid">
+ <xsl:apply-templates mode="page-id" select="$original-member">
+ <xsl:with-param name="is-overload-list-page" select="false()" tunnel="yes"/>
+ </xsl:apply-templates>
+ </xsl:attribute>
+ </xsl:template>
+
+ <!-- For public innerclasses, insert the referenced class inline -->
+ <xsl:template mode="compound-page-insert" match="innerclass[@prot eq 'public']">
+ <xsl:attribute name="d:page-refid" select="d:make-id(.)"/>
+ <d:referenced-inner-class>
+ <xsl:variable name="compound" select="d:get-target-element(.)" as="element(compound)"/>
+ <xsl:apply-templates mode="compound-page" select="d:get-source-doc($compound)/*/compounddef"/>
+ </d:referenced-inner-class>
+ </xsl:template>
+
+ <!-- TODO: refactor this rule -->
+ <!-- Resolve the referenced page IDs for later link generation -->
+ <xsl:template mode="compound-page-insert member-page-insert" match="ref" name="insert-referenced-page-id">
+ <xsl:attribute name="d:refid">
+ <xsl:apply-templates mode="page-id" select="d:get-target-element(.)"/>
+ </xsl:attribute>
+ </xsl:template>
+
+ <xsl:function name="d:get-target-element" as="element()?"> <!-- to allow for partial builds -->
+ <!--
+ <xsl:function name="d:get-target-element" as="element()">
+ -->
+ <xsl:param name="ref" as="element()"/> <!-- <ref> or <innerclass> or... -->
+ <xsl:variable name="referenced-elements" select="key('elements-by-refid', $ref/@refid, $index-xml)"/>
+ <xsl:variable name="result" as="element()?">
+ <xsl:choose>
+ <!-- Handle the case where the referenced element appears two or more times in index.xml -->
+ <!-- If there's no ambiguity, we're done! -->
+ <xsl:when test="count($referenced-elements) eq 1">
+ <xsl:apply-templates mode="find-target-element" select="$referenced-elements"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <!-- Otherwise, see if a namespace in the link text successfully disambiguates -->
+ <xsl:variable name="qualified-reference" as="element()*">
+ <xsl:variable name="parent-in-link-text"
+ select="if (contains($ref,'::'))
+ then d:extract-ns-without-suffix($ref)
+ else ''"/>
+ <xsl:sequence select="$referenced-elements[ends-with(parent::compound/name, '::'||$parent-in-link-text)]"/>
+ </xsl:variable>
+ <xsl:choose>
+ <xsl:when test="count($qualified-reference) eq 1">
+ <xsl:apply-templates mode="find-target-element" select="$qualified-reference"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <!-- Otherwise, favor the member that's in the same class or namespace as the current page -->
+ <xsl:variable name="sibling-reference" as="element()*">
+ <xsl:variable name="compound-for-current-page" select="root($ref)/doxygen/compounddef/compoundname/string()"/>
+ <xsl:sequence select="$referenced-elements[parent::compound/name eq $compound-for-current-page]"/>
+ </xsl:variable>
+ <xsl:choose>
+ <xsl:when test="count($sibling-reference) eq 1">
+ <xsl:apply-templates mode="find-target-element" select="$sibling-reference"/>
+ </xsl:when>
+ <!-- If all else fails, give up and just use the first one -->
+ <xsl:otherwise>
+ <xsl:apply-templates mode="find-target-element" select="$referenced-elements[1]"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:if test="not($result)">
+ <xsl:message>Unable to find referenced ID: <xsl:value-of select="$ref/@refid"/></xsl:message>
+ </xsl:if>
+ <xsl:sequence select="$result"/>
+ </xsl:function>
+
+ <xsl:template mode="find-target-element" match="compound | member">
+ <xsl:sequence select="."/>
+ </xsl:template>
+
+ <!-- In the index XML, enumvalue "members" immediately follow the corresponding enum member -->
+ <xsl:template mode="find-target-element" match="member[@kind eq 'enumvalue']">
+ <xsl:sequence select="preceding-sibling::member[@kind eq 'enum'][1]"/>
+ </xsl:template>
+
+</xsl:stylesheet>
diff --git a/src/boost/tools/docca/include/docca/base-stage1.xsl b/src/boost/tools/docca/include/docca/base-stage1.xsl
new file mode 100644
index 000000000..6e5d47977
--- /dev/null
+++ b/src/boost/tools/docca/include/docca/base-stage1.xsl
@@ -0,0 +1,590 @@
+<!DOCTYPE xsl:stylesheet [
+<!-- TODO: complete this list -->
+<!ENTITY BLOCK_LEVEL_ELEMENT "programlisting
+ | itemizedlist
+ | orderedlist
+ | parameterlist
+ | simplesect
+ | para
+ | table
+ | linebreak">
+]>
+<xsl:stylesheet version="3.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xmlns:d="http://github.com/vinniefalco/docca"
+ exclude-result-prefixes="xs d"
+ expand-text="yes">
+
+ <xsl:include href="common.xsl"/>
+
+ <xsl:output indent="yes"/>
+
+ <xsl:template match="/doxygen" priority="1">
+ <page id="{@d:page-id}" type="{@d:page-type}">
+ <xsl:apply-templates mode="index-term-atts" select="."/>
+ <title>
+ <xsl:apply-templates mode="page-title" select="."/>
+ </title>
+ <xsl:apply-templates select="@d:base-compound-refid"/>
+ <xsl:next-match/>
+ </page>
+ </xsl:template>
+
+ <xsl:template match="@d:base-compound-refid">
+ <div>(Inherited from <ref d:refid="{.}">{../@d:base-compound-name}</ref>)</div>
+ </xsl:template>
+
+ <!-- Put an index term on every page except class (compound) and overloaded-member pages -->
+ <xsl:template mode="index-term-atts" match="doxygen[@d:page-type eq 'compound' or @d:overload-position]"/>
+ <xsl:template mode="index-term-atts" match="doxygen">
+ <xsl:attribute name="primary-index-term">
+ <xsl:apply-templates mode="primary-index-term" select="."/>
+ </xsl:attribute>
+ <xsl:apply-templates mode="secondary-index-term-att" select="."/>
+ </xsl:template>
+
+ <!-- By default, use the member name as the primary term... -->
+ <xsl:template mode="primary-index-term" match="doxygen">
+ <xsl:apply-templates mode="member-name" select="."/>
+ </xsl:template>
+ <!-- ...and the compound name as the secondary term. -->
+ <xsl:template mode="secondary-index-term-att" match="doxygen">
+ <xsl:attribute name="secondary-index-term">
+ <xsl:apply-templates mode="compound-name" select="."/>
+ </xsl:attribute>
+ </xsl:template>
+
+ <!-- But with namespace members, use the fully-qualified name as the primary term... -->
+ <xsl:template mode="primary-index-term" match="doxygen[compounddef/@kind eq 'namespace']">
+ <xsl:apply-templates mode="compound-and-member-name" select="."/>
+ </xsl:template>
+ <!-- ...and no secondary term. -->
+ <xsl:template mode="secondary-index-term-att" match="doxygen[compounddef/@kind eq 'namespace']"/>
+
+ <xsl:template mode="compound-name" match="doxygen"
+ >{d:strip-doc-ns(compounddef/compoundname)}</xsl:template>
+
+ <xsl:template mode="member-name" match="doxygen"
+ >{(compounddef/sectiondef/memberdef/name)[1]}</xsl:template>
+
+ <xsl:template mode="compound-and-member-name" match="doxygen">
+ <xsl:variable name="compound-name" as="xs:string">
+ <xsl:apply-templates mode="compound-name" select="."/>
+ </xsl:variable>
+ <xsl:if test="$compound-name">{$compound-name}::</xsl:if>
+ <xsl:apply-templates mode="member-name" select="."/>
+ </xsl:template>
+
+ <xsl:template mode="page-title" match="doxygen[@d:page-type eq 'compound']">
+ <xsl:apply-templates mode="compound-name" select="."/>
+ </xsl:template>
+ <xsl:template mode="page-title" match="doxygen">
+ <xsl:apply-templates mode="compound-and-member-name" select="."/>
+ <xsl:apply-templates mode="overload-qualifier" select="."/>
+ </xsl:template>
+
+ <xsl:template mode="overload-qualifier" match="doxygen"/>
+ <xsl:template mode="overload-qualifier" match="doxygen[@d:overload-position]">
+ <xsl:text> (</xsl:text>
+ <xsl:value-of select="@d:overload-position"/>
+ <xsl:text> of </xsl:text>
+ <xsl:value-of select="@d:overload-size"/>
+ <xsl:text> overloads)</xsl:text>
+ </xsl:template>
+
+
+ <xsl:template match="/doxygen[@d:page-type eq 'compound']">
+ <xsl:apply-templates select="compounddef"/>
+ </xsl:template>
+
+ <xsl:template match="/doxygen[@d:page-type eq 'member']">
+ <xsl:apply-templates select="compounddef/sectiondef/memberdef"/> <!-- should just be one -->
+ </xsl:template>
+
+ <xsl:template match="/doxygen[@d:page-type eq 'overload-list']">
+ <xsl:apply-templates select="(compounddef/sectiondef/memberdef)[1]"/>
+ </xsl:template>
+
+ <xsl:template match="compounddef | memberdef" priority="2">
+ <xsl:next-match/>
+ <xsl:apply-templates mode="includes" select=".">
+ <xsl:with-param name="is-footer" select="true()"/>
+ </xsl:apply-templates>
+ </xsl:template>
+
+ <!-- For convenience, pre-calculate some member sequences and tunnel them through -->
+ <xsl:template match="compounddef" priority="1">
+ <xsl:next-match>
+ <xsl:with-param name="public-types"
+ select="sectiondef[@kind eq 'public-type']/memberdef
+ | innerclass[@prot eq 'public'][not(d:should-ignore-inner-class(.))]"
+ tunnel="yes"/>
+ <xsl:with-param name="friends"
+ select="sectiondef[@kind eq 'friend']/memberdef[not(type eq 'friend class')]
+ [not(d:should-ignore-friend(.))]"
+ tunnel="yes"/>
+ </xsl:next-match>
+ </xsl:template>
+
+ <xsl:template match="compounddef">
+ <xsl:param name="public-types" tunnel="yes"/>
+ <xsl:param name="friends" tunnel="yes"/>
+
+ <xsl:apply-templates select="briefdescription"/>
+
+ <xsl:apply-templates mode="section"
+ select=".,
+
+ ( $public-types/self::memberdef/..
+ | $public-types/self::innerclass
+ )[1],
+
+ sectiondef[@kind = ( 'public-func', 'public-static-func')],
+ sectiondef[@kind = ('protected-func','protected-static-func')],
+ sectiondef[@kind = ( 'private-func', 'private-static-func')][$include-private-members],
+
+ sectiondef[@kind = ( 'public-attrib', 'public-static-attrib')],
+ sectiondef[@kind = ('protected-attrib','protected-static-attrib')],
+ sectiondef[@kind = ( 'private-attrib', 'private-static-attrib')][$include-private-members],
+
+ $friends/..,
+
+ sectiondef[@kind eq 'related'],
+
+ detaileddescription
+ "/>
+ </xsl:template>
+
+ <xsl:template match="memberdef">
+ <xsl:apply-templates select="briefdescription"/>
+ <xsl:apply-templates mode="section" select="., detaileddescription"/>
+ </xsl:template>
+
+ <xsl:template match="memberdef[@kind eq 'enum']">
+ <xsl:apply-templates select="briefdescription"/>
+ <xsl:apply-templates mode="section" select="., parent::sectiondef, detaileddescription"/>
+ </xsl:template>
+
+ <xsl:template match="memberdef[/doxygen/@d:page-type eq 'overload-list']">
+ <xsl:apply-templates mode="overload-list" select="../../sectiondef/memberdef"/>
+ </xsl:template>
+
+ <xsl:template mode="overload-list" match="memberdef">
+ <xsl:apply-templates select="briefdescription[not(. = ../preceding-sibling::*/briefdescription)]"/>
+ <overloaded-member>
+ <xsl:apply-templates mode="normalize-params" select="templateparamlist"/>
+ <xsl:apply-templates mode="modifier" select="(@explicit, @friend, @static)[. eq 'yes'],
+ @virt[. eq 'virtual']"/>
+ <xsl:apply-templates select="type"/>
+ <ref d:refid="{@d:page-refid}">{name}</ref>
+ <params>
+ <xsl:apply-templates select="param"/>
+ </params>
+ <xsl:apply-templates mode="modifier" select="@const[. eq 'yes']"/>
+ </overloaded-member>
+ </xsl:template>
+
+ <xsl:template mode="modifier" match="@*">
+ <modifier>{local-name(.)}</modifier>
+ </xsl:template>
+ <xsl:template mode="modifier" match="@virt">
+ <modifier>virtual</modifier>
+ </xsl:template>
+
+
+ <xsl:template match="type">
+ <type>
+ <xsl:value-of select="d:cleanup-type(normalize-space(.))"/>
+ </type>
+ </xsl:template>
+
+ <!-- d:cleanup-param() may not be needed, and the above may suffice. (TODO: confirm this and remove d:cleanup-param() if so)
+ <xsl:template match="param/type">
+ <type>
+ <xsl:value-of select="d:cleanup-param(.)"/>
+ </type>
+ </xsl:template>
+ -->
+
+ <!-- TODO: Should this be a custom rule or built-in? -->
+ <xsl:template mode="section" match="simplesect[matches(title,'Concepts:?')]"/>
+
+ <xsl:template mode="section" match="*">
+ <section>
+ <heading>
+ <xsl:apply-templates mode="section-heading" select="."/>
+ </heading>
+ <xsl:apply-templates mode="section-body" select="."/>
+ </section>
+ </xsl:template>
+
+ <xsl:template match="simplesect | parameterlist">
+ <xsl:apply-templates mode="section" select="."/>
+ </xsl:template>
+
+ <xsl:template mode="section-heading" match="memberdef |
+ compounddef ">Synopsis</xsl:template>
+ <xsl:template mode="section-heading" match="detaileddescription">Description</xsl:template>
+
+ <xsl:template mode="section-heading" match="simplesect[@kind eq 'note' ]">Remarks</xsl:template>
+ <xsl:template mode="section-heading" match="simplesect[@kind eq 'see' ]">See Also</xsl:template>
+ <xsl:template mode="section-heading" match="simplesect[@kind eq 'return']">Return Value</xsl:template>
+ <xsl:template mode="section-heading" match="simplesect" >{title}</xsl:template>
+
+ <xsl:template mode="section-heading" match="parameterlist[@kind eq 'exception' ]">Exceptions</xsl:template>
+ <xsl:template mode="section-heading" match="parameterlist[@kind eq 'templateparam']">Template Parameters</xsl:template>
+ <xsl:template mode="section-heading" match="parameterlist ">Parameters</xsl:template>
+
+ <xsl:template mode="section-heading" match="innerclass
+ | sectiondef[@kind eq 'public-type']">Types</xsl:template>
+ <xsl:template mode="section-heading" match="sectiondef[@kind eq 'friend' ]">Friends</xsl:template>
+ <xsl:template mode="section-heading" match="sectiondef[@kind eq 'related' ]">Related Functions</xsl:template>
+
+ <xsl:template mode="section-heading" match="sectiondef[@kind eq 'enum']">Values</xsl:template>
+
+ <xsl:template mode="section-heading" match="sectiondef">
+ <xsl:apply-templates mode="access-level" select="@kind"/>
+ <xsl:apply-templates mode="member-kind" select="@kind"/>
+ </xsl:template>
+
+ <xsl:template mode="access-level" match="@kind[starts-with(.,'public' )]"/>
+ <xsl:template mode="access-level" match="@kind[starts-with(.,'protected')]">Protected </xsl:template>
+ <xsl:template mode="access-level" match="@kind[starts-with(.,'private' )]">Private </xsl:template>
+
+ <xsl:template mode="member-kind" match="@kind[ends-with(.,'func' )]">Member Functions</xsl:template>
+ <xsl:template mode="member-kind" match="@kind[ends-with(.,'attrib')]">Data Members</xsl:template>
+
+ <xsl:template mode="section-body" match="sectiondef | innerclass | parameterlist">
+ <table>
+ <tr>
+ <th>
+ <xsl:apply-templates mode="column-1-name" select="."/>
+ </th>
+ <th>
+ <xsl:apply-templates mode="column-2-name" select="."/>
+ </th>
+ </tr>
+ <xsl:apply-templates mode="table-body" select="."/>
+ </table>
+ </xsl:template>
+
+ <xsl:template mode="column-1-name" match="*">Name</xsl:template>
+ <xsl:template mode="column-2-name" match="*">Description</xsl:template>
+
+ <xsl:template mode="column-1-name"
+ match="parameterlist[@kind = ('exception','templateparam')]">Type</xsl:template>
+
+ <xsl:template mode="column-2-name" match="parameterlist[@kind eq 'exception']">Thrown On</xsl:template>
+
+
+ <xsl:template mode="table-body" match="parameterlist">
+ <xsl:apply-templates mode="parameter-row" select="parameteritem"/>
+ </xsl:template>
+
+ <xsl:template mode="parameter-row" match="parameteritem">
+ <tr>
+ <td>
+ <code>
+ <!-- ASSUMPTION: <parameternamelist> only ever has one <parametername> child -->
+ <xsl:apply-templates select="parameternamelist/parametername/node()"/>
+ </code>
+ </td>
+ <td>
+ <xsl:apply-templates select="parameterdescription/node()"/>
+ </td>
+ </tr>
+ </xsl:template>
+
+ <xsl:template mode="table-body" match="sectiondef[@kind eq 'enum']">
+ <xsl:apply-templates mode="enum-row" select="memberdef/enumvalue"/> <!-- Use input order for enum values -->
+ </xsl:template>
+
+ <xsl:template mode="enum-row" match="enumvalue">
+ <tr>
+ <td>
+ <code>{name}</code>
+ </td>
+ <td>
+ <xsl:apply-templates select="briefdescription, detaileddescription"/>
+ </td>
+ </tr>
+ </xsl:template>
+
+ <xsl:template mode="table-body" match="sectiondef | innerclass">
+ <xsl:variable name="member-nodes" as="element()*">
+ <xsl:apply-templates mode="member-nodes" select="."/>
+ </xsl:variable>
+ <xsl:apply-templates mode="member-row" select="$member-nodes">
+ <xsl:sort select="d:member-name(.)"/>
+ </xsl:apply-templates>
+ </xsl:template>
+
+ <xsl:template mode="member-nodes" match="innerclass | sectiondef[@kind eq 'public-type']">
+ <xsl:param name="public-types" tunnel="yes"/>
+ <xsl:sequence select="$public-types"/>
+ </xsl:template>
+
+ <xsl:template mode="member-nodes" match="sectiondef[@kind eq 'friend']">
+ <xsl:param name="friends" tunnel="yes"/>
+ <xsl:sequence select="$friends"/>
+ </xsl:template>
+
+ <xsl:template mode="member-nodes" match="sectiondef">
+ <xsl:sequence select="memberdef"/>
+ </xsl:template>
+
+
+ <xsl:function name="d:member-name">
+ <xsl:param name="element"/>
+ <xsl:apply-templates mode="member-name" select="$element"/>
+ </xsl:function>
+
+ <xsl:template mode="member-name" match="memberdef">
+ <xsl:sequence select="name"/>
+ </xsl:template>
+ <xsl:template mode="member-name" match="innerclass">
+ <xsl:sequence select="d:referenced-inner-class/compounddef/compoundname ! d:strip-ns(.)"/>
+ </xsl:template>
+
+
+ <!-- Only output a table row for the first instance of each name (ignore overloads) -->
+ <xsl:template mode="member-row" match="memberdef[name = preceding-sibling::memberdef/name]"/>
+ <xsl:template mode="member-row" match="*">
+ <tr>
+ <td>
+ <bold>
+ <ref d:refid="{@d:page-refid}">{d:member-name(.)}</ref>
+ </bold>
+ </td>
+ <td>
+ <xsl:apply-templates mode="member-description" select="."/>
+ </td>
+ </tr>
+ </xsl:template>
+
+ <xsl:template mode="member-description" match="innerclass">
+ <xsl:apply-templates select="d:referenced-inner-class/compounddef/briefdescription"/>
+ </xsl:template>
+ <xsl:template mode="member-description" match="memberdef">
+ <xsl:variable name="descriptions" select="../memberdef[name eq current()/name]/briefdescription"/>
+ <!-- Pull in any overload descriptions but only if they vary -->
+ <xsl:for-each select="distinct-values($descriptions)">
+ <xsl:apply-templates select="$descriptions[. eq current()][1]"/>
+ </xsl:for-each>
+ </xsl:template>
+
+
+ <xsl:template mode="section-body" match="detaileddescription | simplesect">
+ <xsl:apply-templates/>
+ </xsl:template>
+
+ <xsl:template mode="section-body" match="compounddef | memberdef" priority="1">
+ <xsl:apply-templates mode="includes" select="."/>
+ <xsl:next-match/>
+ </xsl:template>
+
+ <xsl:template mode="section-body" match="compounddef">
+ <compound>
+ <xsl:apply-templates mode="normalize-params" select="templateparamlist"/>
+ <kind>{@kind}</kind>
+ <name>{d:strip-ns(compoundname)}</name>
+ <xsl:for-each select="basecompoundref[not(d:should-ignore-base(.))]">
+ <base>
+ <prot>{@prot}</prot>
+ <name>{d:strip-doc-ns(.)}</name>
+ </base>
+ </xsl:for-each>
+ </compound>
+ </xsl:template>
+
+ <xsl:template mode="section-body" match="memberdef[@kind eq 'typedef']">
+ <typedef>
+ <xsl:apply-templates mode="normalize-params" select="templateparamlist"/>
+ <xsl:apply-templates select="name, type"/>
+ </typedef>
+ <!-- Nested compounddefs were derived from refs in the typedef's type -->
+ <xsl:apply-templates select="d:referenced-typedef-class/compounddef"/>
+ </xsl:template>
+
+ <!-- Suppress the display of several aspects of referenced typedef classes -->
+
+ <!-- Don't show the briefdescription -->
+ <xsl:template match="d:referenced-typedef-class/compounddef/briefdescription"/>
+
+ <!-- Don't show the Synopsis -->
+ <xsl:template mode="section" match="d:referenced-typedef-class/compounddef"/>
+
+ <!-- Exclude the "Description" heading (only show the body) -->
+ <xsl:template mode="section" match="d:referenced-typedef-class/compounddef/detaileddescription">
+ <xsl:apply-templates mode="section-body" select="."/>
+ </xsl:template>
+
+ <!-- Don't show the includes header or footer -->
+ <xsl:template mode="includes" match="d:referenced-typedef-class/compounddef"/>
+
+
+ <xsl:template mode="section-body" match="memberdef[@kind eq 'enum']">
+ <enum>
+ <xsl:apply-templates select="name"/>
+ </enum>
+ </xsl:template>
+
+ <xsl:template mode="section-body" match="memberdef[@kind eq 'variable']">
+ <variable>
+ <xsl:apply-templates mode="modifier" select="@static[. eq 'yes']"/>
+ <xsl:apply-templates select="type, name"/>
+ <xsl:apply-templates select="initializer[count(../initializer) eq 1]"/>
+ </variable>
+ </xsl:template>
+
+ <xsl:template mode="section-body" match="memberdef[@kind = ('function','friend')]">
+ <function>
+ <xsl:apply-templates mode="normalize-params" select="templateparamlist"/>
+ <xsl:apply-templates mode="modifier" select="@static[. eq 'yes'],
+ @virt [. eq 'virtual']"/>
+ <xsl:apply-templates select="type, name"/>
+ <params>
+ <xsl:apply-templates select="param"/>
+ </params>
+ <xsl:apply-templates mode="modifier" select="@const[. eq 'yes']"/>
+ </function>
+ </xsl:template>
+
+ <!-- TODO: make sure this is robust and handles all the possible cases well -->
+ <xsl:template mode="normalize-params" match="templateparamlist/param/type[not(../declname)]
+ [starts-with(.,'class ')]"
+ priority="1">
+ <type>class</type>
+ <declname>{substring-after(.,'class ')}</declname>
+ </xsl:template>
+
+ <xsl:template mode="normalize-params" match="templateparamlist/param/type[not(../declname)]">
+ <ERROR message="param neither has a declname nor a 'class ' prefix in the type"/>
+ </xsl:template>
+
+ <xsl:template mode="normalize-params" match="templateparamlist/param/defname"/>
+
+
+ <!-- We only need to keep the @file attribute -->
+ <xsl:template match="location/@*[. except ../@file]"/>
+
+ <xsl:template match="briefdescription | detaileddescription">
+ <div>
+ <xsl:apply-templates/>
+ </div>
+ </xsl:template>
+
+ <xsl:template match="simplesect/title"/>
+
+ <!-- TODO: verify we don't need this; it was causing duplicate headings in simplesect sections
+ <xsl:template match="title">
+ <heading>
+ <xsl:apply-templates/>
+ </heading>
+ </xsl:template>
+ -->
+
+ <!-- By default, don't output an includes header or footer -->
+ <xsl:template mode="includes" match="*"/>
+
+ <!-- TODO: Review; this is meant to effect what the previous code did, but I'm not sure it captures the original intentions -->
+ <xsl:template mode="includes" match="compounddef
+ | memberdef[@kind eq 'friend' or ../../@kind eq 'namespace']
+ [not(/doxygen/@d:page-type eq 'overload-list')]">
+ <xsl:param name="is-footer"/>
+ <para>
+ <xsl:choose>
+ <xsl:when test="$is-footer">
+ <footer>
+ <xsl:apply-templates select="location"/>
+ </footer>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates select="location"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </para>
+ </xsl:template>
+
+ <!-- Strip the project namespace prefix from link display names
+ (matching the text node so this will still work with the strip-leading-space mode/process below) -->
+ <!-- TODO: figure out if we need anything like this (maybe not).
+ <xsl:template match="ref/text()[starts-with(.,$doc-ns)]">
+ <xsl:value-of select="d:strip-doc-ns(.)"/>
+ </xsl:template>
+ -->
+
+
+ <!-- When a <para> directly contains a mix of inline nodes and block-level elements, normalize its content -->
+ <xsl:template match="para[&BLOCK_LEVEL_ELEMENT;]">
+ <para>
+ <xsl:for-each-group select="* | text()" group-adjacent="d:is-inline(.)">
+ <xsl:apply-templates mode="capture-ranges" select="."/>
+ </xsl:for-each-group>
+ </para>
+ </xsl:template>
+
+ <xsl:function name="d:is-inline">
+ <xsl:param name="node"/>
+ <xsl:sequence select="not($node/../(&BLOCK_LEVEL_ELEMENT;)[. is $node])"/>
+ </xsl:function>
+
+ <!-- Process the block-level elements as usual -->
+ <xsl:template mode="capture-ranges" match="node()">
+ <xsl:apply-templates select="current-group()"/>
+ </xsl:template>
+
+ <!-- Wrap contiguous ranges of inline children in a nested <para> -->
+ <xsl:template mode="capture-ranges" match="node()[d:is-inline(.)]">
+ <xsl:choose>
+ <!-- But only if it has text or if the group has more than one node -->
+ <xsl:when test="normalize-space(.) or current-group()[2]">
+ <para>
+ <xsl:apply-templates mode="strip-leading-space" select="."/>
+ </para>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:next-match/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+
+ <!-- Strip leading whitespace from the nested paragraphs to prevent eventual interpretation as a code block -->
+ <xsl:template mode="strip-leading-space" match="*">
+ <xsl:copy>
+ <xsl:apply-templates mode="#current" select="@* | node()[1]"/>
+ </xsl:copy>
+ <xsl:apply-templates mode="#current" select="following-sibling::node()[1]
+ [ancestor-or-self::node() intersect current-group()]"/>
+ </xsl:template>
+
+ <xsl:template mode="strip-leading-space" match="@*">
+ <xsl:copy/>
+ </xsl:template>
+
+ <xsl:template mode="strip-leading-space" match="text()">
+ <xsl:param name="done-stripping" tunnel="yes" select="false()"/>
+ <xsl:choose>
+ <xsl:when test="$done-stripping">
+ <xsl:apply-templates select="."/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:sequence select="replace(.,'^\s+','')"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:apply-templates mode="#current" select="following-sibling::node()[1]
+ [ancestor-or-self::node() intersect current-group()]">
+ <xsl:with-param name="done-stripping" select="$done-stripping or normalize-space(.)" tunnel="yes"/>
+ </xsl:apply-templates>
+ </xsl:template>
+
+
+ <xsl:template mode="#default normalize-params" match="@* | node()">
+ <xsl:copy copy-namespaces="no">
+ <xsl:apply-templates mode="#current" select="@* | node()"/>
+ </xsl:copy>
+ </xsl:template>
+
+</xsl:stylesheet>
diff --git a/src/boost/tools/docca/include/docca/common.xsl b/src/boost/tools/docca/include/docca/common.xsl
new file mode 100644
index 000000000..b9b02c5a6
--- /dev/null
+++ b/src/boost/tools/docca/include/docca/common.xsl
@@ -0,0 +1,107 @@
+<xsl:stylesheet version="3.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xmlns:d="http://github.com/vinniefalco/docca"
+ exclude-result-prefixes="xs d">
+
+ <xsl:variable name="nl" select="'&#xA;'"/>
+
+ <xsl:variable name="leading-ns-regex" select="'^([^:&lt;]+::)+'"/>
+
+ <xsl:function name="d:extract-ns-without-suffix">
+ <xsl:param name="name"/>
+ <xsl:sequence select="replace(d:extract-ns($name), '::$', '')"/>
+ </xsl:function>
+
+ <xsl:function name="d:extract-ns">
+ <xsl:param name="name"/>
+ <xsl:sequence select="replace($name, '('||$leading-ns-regex||').*', '$1')"/>
+ </xsl:function>
+
+ <!-- Strip all C++ namespace prefixes that come at the beginning -->
+ <xsl:function name="d:strip-ns">
+ <xsl:param name="name"/>
+ <xsl:sequence select="replace($name, $leading-ns-regex, '')"/>
+ </xsl:function>
+
+ <!-- Strip the common C++ namespace prefix for the docs as a whole -->
+ <!-- ASSUMPTION: $doc-ns is defined in the customizing stylesheet -->
+ <xsl:function name="d:strip-doc-ns">
+ <xsl:param name="name"/>
+ <xsl:sequence select="if ($name eq $doc-ns)
+ then ''
+ else replace($name, '^'||$doc-ns||'::', '')"/>
+ </xsl:function>
+
+ <xsl:function name="d:make-id">
+ <xsl:param name="name"/>
+ <xsl:sequence select="d:perform-replacements($name, $id-replacements)"/>
+ </xsl:function>
+
+ <xsl:function name="d:perform-replacements">
+ <xsl:param name="name"/>
+ <xsl:param name="replacements"/>
+ <xsl:variable name="next" select="head($replacements)"/>
+ <xsl:variable name="rest" select="tail($replacements)"/>
+ <xsl:sequence select="if (exists($next))
+ then d:perform-replacements(replace($name, $next/@pattern, $next/@with), $rest)
+ else $name"/>
+ </xsl:function>
+
+ <xsl:variable name="id-replacements" select="$additional-id-replacements, $base-id-replacements"/>
+
+ <!-- Can be overridden by a customizing stylesheet -->
+ <xsl:variable name="additional-id-replacements" as="element(replace)*" select="()"/>
+
+ <xsl:variable name="base-id-replacements" as="element(replace)+">
+ <replace pattern="::" with="__"/>
+ <replace pattern="=" with="_eq_"/>
+ <replace pattern="!" with="_not_"/>
+ <replace pattern="->" with="_arrow_"/>
+ <replace pattern="&lt;" with="_lt_"/>
+ <replace pattern=">" with="_gt_"/>
+ <replace pattern="^~" with="_dtor_"/> <!-- destructor -->
+ <replace pattern="~" with="_"/>
+ <replace pattern="\[" with="_lb_"/>
+ <replace pattern="\]" with="_rb_"/>
+ <replace pattern="\(" with="_lp_"/>
+ <replace pattern="\)" with="_rp_"/>
+ <replace pattern="\+" with="_plus_"/>
+ <replace pattern="-" with="_minus_"/>
+ <replace pattern="\*" with="_star_"/>
+ <replace pattern="/" with="_slash_"/>
+ <replace pattern=" " with="_"/>
+ </xsl:variable>
+
+ <xsl:function name="d:cleanup-param">
+ <xsl:param name="name"/>
+ <xsl:sequence select="d:perform-replacements($name, $param-replacements)"/>
+ </xsl:function>
+
+ <xsl:function name="d:cleanup-type">
+ <xsl:param name="name"/>
+ <xsl:sequence select="d:perform-replacements($name, $type-replacements)"/>
+ </xsl:function>
+
+ <xsl:variable name="param-replacements" select="$additional-param-replacements, $base-param-replacements"/>
+
+ <!-- Can be overridden by a customizing stylesheet -->
+ <xsl:variable name="additional-param-replacements" as="element(replace)*" select="()"/>
+
+ <xsl:variable name="base-param-replacements" as="element(replace)*">
+ <!-- Reformats '*', '&', and '...' in parameters, e.g. "void const*" -->
+ <replace pattern=" \*$" with="*"/>
+ <replace pattern=" (&amp;&amp;?)(\.{{3}})?$" with="$1$2"/>
+ </xsl:variable>
+
+ <!-- NOTE: $type-replacements includes $param-replacements -->
+ <xsl:variable name="type-replacements" select="$additional-type-replacements, $base-type-replacements, $param-replacements"/>
+
+ <!-- Can be overridden by a customizing stylesheet -->
+ <xsl:variable name="additional-type-replacements" as="element(replace)*" select="()"/>
+
+ <xsl:variable name="base-type-replacements" as="element(replace)*">
+ <replace pattern="^virtual$" with=""/>
+ </xsl:variable>
+
+</xsl:stylesheet>
diff --git a/src/boost/tools/docca/include/docca/config.xsl b/src/boost/tools/docca/include/docca/config.xsl
new file mode 100644
index 000000000..bb2ce8aab
--- /dev/null
+++ b/src/boost/tools/docca/include/docca/config.xsl
@@ -0,0 +1,47 @@
+<xsl:stylesheet version="3.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xmlns:d="http://github.com/vinniefalco/docca"
+ exclude-result-prefixes="xs d"
+ expand-text="yes">
+
+<!-- CONFIG_TEMPLATE -->
+
+ <xsl:variable name="additional-id-replacements" as="element(replace)*">
+ <replace pattern="boost::asio::error" with=""/>
+ </xsl:variable>
+
+ <xsl:variable name="additional-type-replacements" as="element(replace)*">
+ <replace pattern="BOOST_ASIO_DECL ?(.*)" with="$1"/>
+ </xsl:variable>
+
+ <xsl:variable name="include-private-members" select="false()"/>
+
+ <!-- TODO: refactor the stage-two-specific rules into a separate module that can't intefere with stage one -->
+ <xsl:template mode="includes-template" match="location"
+ >Defined in header [include_file {substring-after(@file, 'include/')}]
+ </xsl:template>
+
+<!-- INCLUDES_FOOT_TEMPLATE -->
+
+ <xsl:function name="d:should-ignore-compound">
+ <xsl:param name="element" as="element(compound)"/>
+ <xsl:sequence select="contains($element/name, '::detail')"/> <!-- TODO: Confirm this should be custom and not built-in behavior -->
+ </xsl:function>
+
+ <xsl:function name="d:should-ignore-base">
+ <xsl:param name="element" as="element(basecompoundref)"/>
+ <xsl:sequence select="contains($element, '::detail')"/> <!-- TODO: Confirm this should be custom and not built-in behavior -->
+ </xsl:function>
+
+ <xsl:function name="d:should-ignore-inner-class">
+ <xsl:param name="element" as="element(innerclass)"/>
+ <xsl:sequence select="contains($element, '_handler')"/>
+ </xsl:function>
+
+ <xsl:function name="d:should-ignore-friend">
+ <xsl:param name="element" as="element(memberdef)"/>
+ <xsl:sequence select="contains($element, '_helper')"/>
+ </xsl:function>
+
+</xsl:stylesheet>
diff --git a/src/boost/tools/docca/include/docca/debug-friendly-quickbook.xsl b/src/boost/tools/docca/include/docca/debug-friendly-quickbook.xsl
new file mode 100644
index 000000000..4d2cb7393
--- /dev/null
+++ b/src/boost/tools/docca/include/docca/debug-friendly-quickbook.xsl
@@ -0,0 +1,23 @@
+<!--
+ All this stylesheet does is output a .txt file for each (erroneously-but-unavoidably-named)
+ .xml file that actually contains a fragment of Quickbook content. This isn't needed for the
+ regular build, but it's useful for viewing in the browser when debugging.
+-->
+<xsl:stylesheet version="3.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ exclude-result-prefixes="xs">
+
+ <xsl:output method="text"/>
+
+ <xsl:param name="input-dir"/>
+
+ <xsl:template match="page">
+ <xsl:variable name="input-uri" select="$input-dir||'/'||@href"/>
+ <xsl:result-document href="{replace($input-uri, '\.xml$', '.txt')}">
+ <xsl:copy-of select="unparsed-text($input-uri)"/>
+ </xsl:result-document>
+ <xsl:apply-templates select="page"/>
+ </xsl:template>
+
+</xsl:stylesheet>
diff --git a/src/boost/tools/docca/include/docca/emphasized-types.xsl b/src/boost/tools/docca/include/docca/emphasized-types.xsl
new file mode 100644
index 000000000..e3ea174ad
--- /dev/null
+++ b/src/boost/tools/docca/include/docca/emphasized-types.xsl
@@ -0,0 +1,43 @@
+<xsl:stylesheet version="3.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ exclude-result-prefixes="xs">
+
+ <xsl:variable name="emphasized-template-parameter-types" select="
+ 'Allocator',
+ 'AsyncStream',
+ 'AsyncReadStream',
+ 'AsyncWriteStream',
+ 'Body',
+ 'BufferSequence',
+ 'BufferSequence', (: TODO: Was this intended to be 'BufferSequence_' ?? :)
+ 'CompletionCondition',
+ 'CompletionHandler',
+ 'CompletionToken',
+ 'ConnectCondition',
+ 'ConnectHandler',
+ 'ConstBufferSequence',
+ 'DynamicBuffer',
+ 'EndpointSequence',
+ 'ExecutionContext',
+ 'Executor',
+ 'Executor_',
+ 'Executor1',
+ 'Executor2',
+ 'Fields',
+ 'Handler',
+ 'Handler_',
+ 'IteratorConnectHandler',
+ 'MutableBufferSequence',
+ 'Protocol',
+ 'RangeConnectHandler',
+ 'RatePolicy',
+ 'ReadHandler',
+ 'Stream',
+ 'SyncStream',
+ 'SyncReadStream',
+ 'SyncWriteStream',
+ 'WriteHandler'
+ "/>
+
+</xsl:stylesheet>
diff --git a/src/boost/tools/docca/include/docca/extract-xml-pages.xsl b/src/boost/tools/docca/include/docca/extract-xml-pages.xsl
new file mode 100644
index 000000000..cb6d1497c
--- /dev/null
+++ b/src/boost/tools/docca/include/docca/extract-xml-pages.xsl
@@ -0,0 +1,12 @@
+<xsl:stylesheet version="3.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xmlns:d="http://github.com/vinniefalco/docca"
+ exclude-result-prefixes="xs d">
+
+ <xsl:import href="base-extract-xml-pages.xsl"/>
+
+ <!-- TODO: consider refactoring to stage-specific configurations -->
+ <xsl:include href="config.xsl"/>
+
+</xsl:stylesheet>
diff --git a/src/boost/tools/docca/include/docca/stage1.xsl b/src/boost/tools/docca/include/docca/stage1.xsl
new file mode 100644
index 000000000..ac44de5af
--- /dev/null
+++ b/src/boost/tools/docca/include/docca/stage1.xsl
@@ -0,0 +1,11 @@
+<xsl:stylesheet version="3.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ exclude-result-prefixes="xs"
+ expand-text="yes">
+
+ <xsl:import href="base-stage1.xsl"/>
+
+ <xsl:include href="config.xsl"/>
+
+</xsl:stylesheet>
diff --git a/src/boost/tools/docca/include/docca/stage2.xsl b/src/boost/tools/docca/include/docca/stage2.xsl
new file mode 100644
index 000000000..211beb438
--- /dev/null
+++ b/src/boost/tools/docca/include/docca/stage2.xsl
@@ -0,0 +1,228 @@
+<!DOCTYPE xsl:stylesheet [
+<!ENTITY SYNTAX_BLOCK "*[ self::compound
+ | self::function
+ | self::typedef
+ | self::enum
+ | self::variable
+ | self::overloaded-member
+ ]">
+]>
+<xsl:stylesheet version="3.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xmlns:d="http://github.com/vinniefalco/docca"
+ expand-text="yes">
+
+ <xsl:output method="text"/>
+
+ <xsl:import href="common.xsl"/>
+
+ <xsl:include href="config.xsl"/>
+ <xsl:include href="emphasized-types.xsl"/>
+
+ <xsl:param name="DEBUG" select="false()"/>
+
+ <xsl:variable name="list-indent-width" select="4"/>
+
+ <xsl:template mode="before" match="/page">
+ <xsl:text>{$nl}</xsl:text>
+ <xsl:text>[section:{tokenize(@id,'\.')[last()]} {d:qb-escape(title)}]</xsl:text>
+ <xsl:apply-templates mode="indexterm" select="."/>
+ </xsl:template>
+
+ <xsl:template mode="indexterm" match="page"/>
+ <xsl:template mode="indexterm" match="page[@primary-index-term]"
+ >{$nl}[indexterm1 {d:qb-escape(@primary-index-term)}]{$nl}</xsl:template>
+ <xsl:template mode="indexterm" match="page[@secondary-index-term]" priority="1"
+ >{$nl}[indexterm2 {d:qb-escape(@primary-index-term)}..{
+ d:qb-escape(@secondary-index-term)}]{$nl}</xsl:template>
+
+ <!-- Title is already included in section header -->
+ <xsl:template match="/page/title"/>
+
+ <xsl:template match="heading">{$nl}[heading {.}]</xsl:template>
+
+ <xsl:template match="location">
+ <xsl:apply-templates mode="includes-template" select="."/>
+ </xsl:template>
+
+ <xsl:template match="footer/location">
+ <xsl:apply-templates mode="includes-template-footer" select="."/>
+ </xsl:template>
+
+ <xsl:template mode="before" match="&SYNTAX_BLOCK;">{$nl}```{$nl}</xsl:template>
+ <xsl:template mode="after" match="&SYNTAX_BLOCK;">{$nl}```{$nl}</xsl:template>
+
+ <!-- Merge adjacent overloaded-members into one syntax block, separated by one blank line -->
+ <xsl:template mode="after" match="overloaded-member[following-sibling::*[1]/self::overloaded-member]" priority="1"/>
+ <xsl:template mode="before" match="overloaded-member[preceding-sibling::*[1]/self::overloaded-member]" priority="1"
+ >{$nl}{$nl}</xsl:template>
+
+ <xsl:template mode="after" match="overloaded-member/type[normalize-space(.)]
+ | function/type[normalize-space(.)]">{$nl}</xsl:template>
+
+ <xsl:template mode="append" match="function">;</xsl:template>
+
+ <xsl:template mode="append" match="overloaded-member">
+ <xsl:text>;{$nl}</xsl:text>
+ <xsl:variable name="more-link" as="element()">
+ <emphasis>'''&amp;raquo;''' <ref d:refid="{ref/@d:refid}">more...</ref></emphasis>
+ </xsl:variable>
+ <xsl:text> ``</xsl:text>
+ <xsl:apply-templates select="$more-link"/>
+ <xsl:text>``</xsl:text>
+ </xsl:template>
+
+ <xsl:template priority="1"
+ match="&SYNTAX_BLOCK;//ref">``[link {$doc-ref}.{@d:refid} {d:qb-escape(.)}]``</xsl:template>
+ <xsl:template match="td[1]//ref" >[link {$doc-ref}.{@d:refid} {d:qb-escape(.)}]</xsl:template>
+ <xsl:template match="ref" >[link {$doc-ref}.{@d:refid} `{d:qb-escape(.)}`]</xsl:template>
+
+ <xsl:template mode="before" match="computeroutput[not(ref)] | code">`</xsl:template>
+ <xsl:template mode="after" match="computeroutput[not(ref)] | code">`</xsl:template>
+
+ <xsl:template mode="before" match="enum/name">enum </xsl:template>
+
+ <xsl:template mode="before" match="typedef/name">using </xsl:template>
+ <xsl:template mode="after" match="typedef/name"> = </xsl:template>
+ <xsl:template mode="after" match="typedef/type">;</xsl:template>
+
+ <xsl:template match="type[. eq '__implementation_defined__' ]">``['implementation-defined]``</xsl:template>
+ <xsl:template match="type[. eq '__see_below__' ]">``['see-below]``</xsl:template>
+ <xsl:template match="type[. = ('__deduced__','void_or_deduced')]">``__deduced__``</xsl:template>
+
+ <xsl:template mode="before" match="variable/name | variable/initializer">{' '}</xsl:template>
+ <xsl:template mode="append" match="variable">;</xsl:template>
+
+ <xsl:template mode="after" match="compound/kind">{' '}</xsl:template>
+
+ <xsl:template mode="before" match="base[1]"> :{$nl} </xsl:template>
+ <xsl:template mode="before" match="base" >{$nl} </xsl:template>
+ <xsl:template mode="after" match="base[position() ne last()]">,</xsl:template>
+
+ <xsl:template mode="after" match="base/prot">{' '}</xsl:template>
+
+ <xsl:template mode="before" match="templateparamlist">template&lt;</xsl:template>
+ <xsl:template mode="after" match="templateparamlist">>{$nl}</xsl:template>
+
+ <xsl:template mode="before" match="param">{$nl} </xsl:template>
+ <xsl:template mode="after" match="param[position() ne last()]">,</xsl:template>
+
+ <xsl:template mode="after" match="param[declname]/type">{' '}</xsl:template>
+
+
+ <xsl:template mode="before" match="params">(</xsl:template>
+ <xsl:template mode="after" match="params">)</xsl:template>
+
+ <xsl:template match="templateparamlist/param/declname[. = $emphasized-template-parameter-types]"
+ >__{translate(.,'_','')}__</xsl:template>
+
+ <xsl:template mode="before" match="defval"> = </xsl:template>
+
+ <xsl:template mode="before" match="modifier[. eq 'const']">{' '}</xsl:template>
+ <xsl:template mode="after" match="modifier[. eq 'const']"/>
+
+ <xsl:template mode="after" match="modifier">{$nl}</xsl:template>
+
+
+ <xsl:template mode="#all" match="ERROR">[role red error.{@message}]</xsl:template>
+
+ <xsl:template mode="before" match="table">{$nl}[table </xsl:template>
+ <xsl:template mode="after" match="table">{$nl}]</xsl:template>
+
+ <!-- ASSUMPTION: table rows have either <th> or <td>, not both -->
+ <xsl:template mode="before" match="tr[th] | th">[</xsl:template>
+ <xsl:template mode="after" match="tr[th] | th">]</xsl:template>
+
+ <xsl:template mode="before" match="tr">{$nl} [</xsl:template>
+ <xsl:template mode="after" match="tr">{$nl} ]</xsl:template>
+
+ <xsl:template mode="before" match="td">{$nl} [</xsl:template>
+ <xsl:template mode="after" match="td">{$nl} ]</xsl:template>
+
+ <xsl:template mode="before" match="bold">[*</xsl:template>
+ <xsl:template mode="after" match="bold">]</xsl:template>
+
+ <xsl:template mode="before" match="emphasis">['</xsl:template>
+ <xsl:template mode="after" match="emphasis">]</xsl:template>
+
+ <xsl:template mode="before" match="ulink">[@{@url} </xsl:template>
+ <xsl:template mode="after" match="ulink">]</xsl:template>
+
+ <xsl:template mode="after" match="itemizedlist | orderedlist">{$nl}</xsl:template>
+
+ <xsl:template match="listitem">
+ <xsl:text>{$nl}</xsl:text>
+ <xsl:apply-templates mode="list-item-indent" select="."/>
+ <xsl:apply-templates mode="list-item-label" select=".."/>
+ <xsl:text> </xsl:text>
+ <!-- ASSUMPTION: <para> always appears as a child of list items -->
+ <xsl:apply-templates select="para/node()"/>
+ </xsl:template>
+
+ <!-- TODO: verify this works as expected (find an example of a nested list) -->
+ <xsl:template mode="list-item-indent"
+ match="listitem">{ancestor::listitem ! (1 to $list-indent-width) ! ' '}</xsl:template>
+
+ <xsl:template mode="list-item-label" match="itemizedlist">*</xsl:template>
+ <xsl:template mode="list-item-label" match="orderedlist" >#</xsl:template>
+
+ <xsl:template mode="append" match="/page/div[1]">
+ <xsl:if test="$DEBUG">
+ <xsl:text>['</xsl:text>
+ <xsl:text>[role red \[Page type: [*{/*/@type}]\]] </xsl:text>
+ <xsl:text>[role green \[[@../../doc/html/{translate($doc-ref,'.','/')}/{
+ translate(/page/@id,'.','/')}.html [role green doc_build_html]]\]] </xsl:text>
+ <xsl:text>[@../build/xml-pages/{/page/@id}.xml [role blue [*\[doxygen_page_xml\]]]]</xsl:text>
+ <xsl:text>[@../build/stage1_visualized/visualized/{/page/@id}.html [role magenta ---stage1_visualized-->]]</xsl:text>
+ <xsl:text>[@../build/stage1_visualized/results/{ /page/@id}.xml [role blue [*\[docca_page_xml\]]]]</xsl:text>
+ <xsl:text>[@../build/stage2_visualized/visualized/{/page/@id}.html [role magenta ---stage2_visualized-->]]</xsl:text>
+ <xsl:text>[@../build/stage2_visualized/results/{ /page/@id}.txt [role blue [*\[quickbook_result\]]]]</xsl:text>
+ <xsl:text>]</xsl:text>
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template mode="before" match="para | div">{$nl}</xsl:template>
+
+ <xsl:template match="sp">{' '}</xsl:template>
+
+ <xsl:template match="linebreak">{$nl}{$nl}</xsl:template>
+
+ <xsl:template mode="before" match="programlisting">{$nl}```{$nl}</xsl:template>
+ <xsl:template mode="after" match="programlisting" >```{$nl}</xsl:template>
+
+ <xsl:template mode="after" match="codeline">{$nl}</xsl:template>
+
+ <!-- Ignore whitespace-only text nodes -->
+ <xsl:template match="text()[not(normalize-space())]"/>
+
+ <!-- Boilerplate default rules for elements -->
+ <!-- Convention of this stylesheet is to favor use of just "before" and "after"
+ and to utilize "append" (and maybe "insert") only when a distinction is needed -->
+ <xsl:template match="*" priority="10">
+ <xsl:apply-templates mode="before" select="."/>
+ <!-- enable if needed/desired
+ <xsl:apply-templates mode="insert" select="."/> -->
+ <xsl:next-match/>
+ <xsl:apply-templates mode="append" select="."/>
+ <xsl:apply-templates mode="after" select="."/>
+ </xsl:template>
+
+ <!-- Default before/after/insert/append rules are to do nothing -->
+ <xsl:template mode="before" match="*"/>
+ <!-- enable if needed/desired
+ <xsl:template mode="insert" match="*"/> -->
+ <xsl:template mode="append" match="*"/>
+ <xsl:template mode="after" match="*"/>
+
+
+ <xsl:function name="d:qb-escape">
+ <xsl:param name="string"/>
+ <xsl:sequence select="replace(
+ replace($string, '\[', '\\['),
+ '\]',
+ '\\]'
+ )"/>
+ </xsl:function>
+
+</xsl:stylesheet>