links.xsl 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794
  1. <?xml version='1.0'?>
  2. <!--
  3. Copyright © 2004-2006 by Idiom Technologies, Inc. All rights reserved.
  4. IDIOM is a registered trademark of Idiom Technologies, Inc. and WORLDSERVER
  5. and WORLDSTART are trademarks of Idiom Technologies, Inc. All other
  6. trademarks are the property of their respective owners.
  7. IDIOM TECHNOLOGIES, INC. IS DELIVERING THE SOFTWARE "AS IS," WITH
  8. ABSOLUTELY NO WARRANTIES WHATSOEVER, WHETHER EXPRESS OR IMPLIED, AND IDIOM
  9. TECHNOLOGIES, INC. DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
  10. BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  11. PURPOSE AND WARRANTY OF NON-INFRINGEMENT. IDIOM TECHNOLOGIES, INC. SHALL NOT
  12. BE LIABLE FOR INDIRECT, INCIDENTAL, SPECIAL, COVER, PUNITIVE, EXEMPLARY,
  13. RELIANCE, OR CONSEQUENTIAL DAMAGES (INCLUDING BUT NOT LIMITED TO LOSS OF
  14. ANTICIPATED PROFIT), ARISING FROM ANY CAUSE UNDER OR RELATED TO OR ARISING
  15. OUT OF THE USE OF OR INABILITY TO USE THE SOFTWARE, EVEN IF IDIOM
  16. TECHNOLOGIES, INC. HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
  17. Idiom Technologies, Inc. and its licensors shall not be liable for any
  18. damages suffered by any person as a result of using and/or modifying the
  19. Software or its derivatives. In no event shall Idiom Technologies, Inc.'s
  20. liability for any damages hereunder exceed the amounts received by Idiom
  21. Technologies, Inc. as a result of this transaction.
  22. These terms and conditions supersede the terms and conditions in any
  23. licensing agreement to the extent that such terms and conditions conflict
  24. with those set forth herein.
  25. This file is part of the DITA Open Toolkit project.
  26. See the accompanying license.txt file for applicable licenses.
  27. -->
  28. <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  29. xmlns:fo="http://www.w3.org/1999/XSL/Format"
  30. xmlns:opentopic-mapmerge="http://www.idiominc.com/opentopic/mapmerge"
  31. xmlns:opentopic-func="http://www.idiominc.com/opentopic/exsl/function"
  32. xmlns:related-links="http://dita-ot.sourceforge.net/ns/200709/related-links"
  33. xmlns:dita-ot="http://dita-ot.sourceforge.net/ns/201007/dita-ot"
  34. xmlns:xs="http://www.w3.org/2001/XMLSchema"
  35. exclude-result-prefixes="dita-ot opentopic-mapmerge opentopic-func related-links xs"
  36. version="2.0">
  37. <xsl:import href="plugin:org.dita.base:xsl/common/output-message.xsl"/>
  38. <xsl:param name="figurelink.style" select="'NUMTITLE'"/>
  39. <xsl:param name="tablelink.style" select="'NUMTITLE'"/>
  40. <!-- Deprecated since 2.3 -->
  41. <xsl:variable name="msgprefix">DOTX</xsl:variable>
  42. <xsl:key name="key_anchor" match="*[@id][not(contains(@class,' map/topicref '))]" use="@id"/>
  43. <!--[not(contains(@class,' map/topicref '))]-->
  44. <xsl:template name="insertLinkShortDesc">
  45. <xsl:param name="destination"/>
  46. <xsl:param name="element"/>
  47. <xsl:param name="linkScope"/>
  48. <xsl:choose>
  49. <!-- User specified description (from map or topic): use that. -->
  50. <xsl:when test="*[contains(@class,' topic/desc ')] and
  51. processing-instruction()[name()='ditaot'][.='usershortdesc']">
  52. <fo:block xsl:use-attribute-sets="link__shortdesc">
  53. <xsl:apply-templates select="*[contains(@class, ' topic/desc ')]"/>
  54. </fo:block>
  55. </xsl:when>
  56. <!-- External: do not attempt to retrieve. -->
  57. <xsl:when test="$linkScope='external'">
  58. </xsl:when>
  59. <!-- When the target has a short description and no local override, use the target -->
  60. <xsl:when test="$element/*[contains(@class, ' topic/shortdesc ')]">
  61. <fo:block xsl:use-attribute-sets="link__shortdesc">
  62. <xsl:apply-templates select="$element/*[contains(@class, ' topic/shortdesc ')]"/>
  63. </fo:block>
  64. </xsl:when>
  65. </xsl:choose>
  66. </xsl:template>
  67. <xsl:template name="insertLinkDesc">
  68. <xsl:call-template name="getVariable">
  69. <xsl:with-param name="id" select="'Link description'"/>
  70. <xsl:with-param name="params">
  71. <desc>
  72. <fo:inline>
  73. <xsl:apply-templates select="*[contains(@class,' topic/desc ')]" mode="insert-description"/>
  74. </fo:inline>
  75. </desc>
  76. </xsl:with-param>
  77. </xsl:call-template>
  78. </xsl:template>
  79. <xsl:template match="*[contains(@class,' topic/xref ') or contains(@class, ' topic/link ')]/*[contains(@class,' topic/desc ')]" priority="1"/>
  80. <xsl:template match="*[contains(@class,' topic/desc ')]" mode="insert-description">
  81. <xsl:apply-templates/>
  82. </xsl:template>
  83. <!-- The insertReferenceTitle template is called from <xref> and <link> and is
  84. used to build link contents (using full FO syntax, not just the text). -->
  85. <!-- Process any cross reference or link with author-specified text.
  86. The specified text is used as the link text. -->
  87. <xsl:template match="*[processing-instruction()[name()='ditaot'][.='usertext']]" mode="insertReferenceTitle">
  88. <xsl:apply-templates select="*[not(contains(@class,' topic/desc '))]|text()"/>
  89. </xsl:template>
  90. <!-- Process any cross reference or link with no content, or with content
  91. generated by the DITA-OT preprocess. The title will be retrieved from
  92. the target element, and combined with generated text such as Figure N. -->
  93. <xsl:template match="*" mode="insertReferenceTitle">
  94. <xsl:param name="href"/>
  95. <xsl:param name="titlePrefix"/>
  96. <xsl:param name="destination"/>
  97. <xsl:param name="element"/>
  98. <xsl:variable name="referenceContent">
  99. <xsl:choose>
  100. <xsl:when test="not($element) or ($destination = '')">
  101. <xsl:text>#none#</xsl:text>
  102. </xsl:when>
  103. <xsl:when test="contains($element/@class,' topic/li ') and
  104. contains($element/parent::*/@class,' topic/ol ')">
  105. <!-- SF Bug 1839827: This causes preprocessor text to be used for links to OL/LI -->
  106. <xsl:text>#none#</xsl:text>
  107. </xsl:when>
  108. <xsl:otherwise>
  109. <xsl:apply-templates select="$element" mode="retrieveReferenceTitle"/>
  110. </xsl:otherwise>
  111. </xsl:choose>
  112. </xsl:variable>
  113. <xsl:if test="not($titlePrefix = '')">
  114. <xsl:call-template name="getVariable">
  115. <xsl:with-param name="id" select="$titlePrefix"/>
  116. </xsl:call-template>
  117. </xsl:if>
  118. <xsl:choose>
  119. <xsl:when test="not($element) or ($destination = '') or $referenceContent='#none#'">
  120. <xsl:choose>
  121. <xsl:when test="*[not(contains(@class,' topic/desc '))] | text()">
  122. <xsl:apply-templates select="*[not(contains(@class,' topic/desc '))] | text()"/>
  123. </xsl:when>
  124. <xsl:otherwise>
  125. <xsl:value-of select="$href"/>
  126. </xsl:otherwise>
  127. </xsl:choose>
  128. </xsl:when>
  129. <xsl:otherwise>
  130. <xsl:copy-of select="$referenceContent"/>
  131. </xsl:otherwise>
  132. </xsl:choose>
  133. </xsl:template>
  134. <xsl:template match="*[contains(@class, ' topic/fig ')][*[contains(@class, ' topic/title ')]]" mode="retrieveReferenceTitle">
  135. <xsl:choose>
  136. <xsl:when test="$figurelink.style='NUMBER'">
  137. <xsl:call-template name="getVariable">
  138. <xsl:with-param name="id" select="'Figure Number'"/>
  139. <xsl:with-param name="params">
  140. <number>
  141. <xsl:apply-templates select="*[contains(@class, ' topic/title ')]" mode="fig.title-number"/>
  142. </number>
  143. </xsl:with-param>
  144. </xsl:call-template>
  145. </xsl:when>
  146. <xsl:when test="$figurelink.style='TITLE'">
  147. <xsl:apply-templates select="*[contains(@class, ' topic/title ')]" mode="insert-text"/>
  148. </xsl:when>
  149. <xsl:otherwise>
  150. <xsl:call-template name="getVariable">
  151. <xsl:with-param name="id" select="'Figure.title'"/>
  152. <xsl:with-param name="params">
  153. <number>
  154. <xsl:apply-templates select="*[contains(@class, ' topic/title ')]" mode="fig.title-number"/>
  155. </number>
  156. <title>
  157. <xsl:apply-templates select="*[contains(@class, ' topic/title ')]" mode="insert-text"/>
  158. </title>
  159. </xsl:with-param>
  160. </xsl:call-template>
  161. </xsl:otherwise>
  162. </xsl:choose>
  163. </xsl:template>
  164. <xsl:template match="*[contains(@class, ' topic/section ')][*[contains(@class, ' topic/title ')]]" mode="retrieveReferenceTitle">
  165. <xsl:variable name="title">
  166. <xsl:apply-templates select="*[contains(@class, ' topic/title ')]" mode="insert-text"/>
  167. </xsl:variable>
  168. <xsl:value-of select="normalize-space($title)"/>
  169. </xsl:template>
  170. <xsl:template match="*[contains(@class, ' topic/table ')][*[contains(@class, ' topic/title ')]]" mode="retrieveReferenceTitle">
  171. <xsl:choose>
  172. <xsl:when test="$tablelink.style='NUMBER'">
  173. <xsl:call-template name="getVariable">
  174. <xsl:with-param name="id" select="'Table Number'"/>
  175. <xsl:with-param name="params">
  176. <number>
  177. <xsl:apply-templates select="*[contains(@class, ' topic/title ')]" mode="table.title-number"/>
  178. </number>
  179. </xsl:with-param>
  180. </xsl:call-template>
  181. </xsl:when>
  182. <xsl:when test="$tablelink.style='TITLE'">
  183. <xsl:apply-templates select="*[contains(@class, ' topic/title ')]" mode="insert-text"/>
  184. </xsl:when>
  185. <xsl:otherwise>
  186. <xsl:call-template name="getVariable">
  187. <xsl:with-param name="id" select="'Table.title'"/>
  188. <xsl:with-param name="params">
  189. <number>
  190. <xsl:apply-templates select="*[contains(@class, ' topic/title ')]" mode="table.title-number"/>
  191. </number>
  192. <title>
  193. <xsl:apply-templates select="*[contains(@class, ' topic/title ')]" mode="insert-text"/>
  194. </title>
  195. </xsl:with-param>
  196. </xsl:call-template>
  197. </xsl:otherwise>
  198. </xsl:choose>
  199. </xsl:template>
  200. <xsl:template match="*[contains(@class, ' topic/li ')]" mode="retrieveReferenceTitle">
  201. <xsl:call-template name="getVariable">
  202. <xsl:with-param name="id" select="'List item'"/>
  203. </xsl:call-template>
  204. </xsl:template>
  205. <xsl:template match="*[contains(@class, ' topic/fn ')]" mode="retrieveReferenceTitle">
  206. <xsl:call-template name="getVariable">
  207. <xsl:with-param name="id" select="'Foot note'"/>
  208. </xsl:call-template>
  209. </xsl:template>
  210. <!-- Default rule: if element has a title, use that, otherwise return '#none#' -->
  211. <xsl:template match="*" mode="retrieveReferenceTitle" >
  212. <xsl:choose>
  213. <xsl:when test="*[contains(@class,' topic/title ')]">
  214. <xsl:value-of select="string(*[contains(@class, ' topic/title ')])"/>
  215. </xsl:when>
  216. <xsl:otherwise>
  217. <xsl:text>#none#</xsl:text>
  218. </xsl:otherwise>
  219. </xsl:choose>
  220. </xsl:template>
  221. <xsl:template match="*[contains(@class,' topic/xref ')]" name="topic.xref">
  222. <fo:inline>
  223. <xsl:call-template name="commonattributes"/>
  224. </fo:inline>
  225. <xsl:variable name="destination" select="opentopic-func:getDestinationId(@href)"/>
  226. <xsl:variable name="element" select="key('key_anchor',$destination, $root)[1]"/>
  227. <xsl:variable name="referenceTitle" as="node()*">
  228. <xsl:apply-templates select="." mode="insertReferenceTitle">
  229. <xsl:with-param name="href" select="@href"/>
  230. <xsl:with-param name="titlePrefix" select="''"/>
  231. <xsl:with-param name="destination" select="$destination"/>
  232. <xsl:with-param name="element" select="$element"/>
  233. </xsl:apply-templates>
  234. </xsl:variable>
  235. <fo:basic-link xsl:use-attribute-sets="xref">
  236. <xsl:call-template name="buildBasicLinkDestination">
  237. <xsl:with-param name="scope" select="@scope"/>
  238. <xsl:with-param name="format" select="@format"/>
  239. <xsl:with-param name="href" select="@href"/>
  240. </xsl:call-template>
  241. <xsl:choose>
  242. <xsl:when test="not(@scope = 'external' or not(empty(@format) or @format = 'dita')) and exists($referenceTitle)">
  243. <xsl:copy-of select="$referenceTitle"/>
  244. </xsl:when>
  245. <xsl:when test="not(@scope = 'external' or not(empty(@format) or @format = 'dita'))">
  246. <xsl:call-template name="insertPageNumberCitation">
  247. <xsl:with-param name="isTitleEmpty" select="true()"/>
  248. <xsl:with-param name="destination" select="$destination"/>
  249. <xsl:with-param name="element" select="$element"/>
  250. </xsl:call-template>
  251. </xsl:when>
  252. <xsl:otherwise>
  253. <xsl:choose>
  254. <xsl:when test="*[not(contains(@class,' topic/desc '))] | text()">
  255. <xsl:apply-templates select="*[not(contains(@class,' topic/desc '))] | text()" />
  256. </xsl:when>
  257. <xsl:otherwise>
  258. <xsl:value-of select="@href"/>
  259. </xsl:otherwise>
  260. </xsl:choose>
  261. </xsl:otherwise>
  262. </xsl:choose>
  263. </fo:basic-link>
  264. <!--
  265. Disable because of the CQ#8102 bug
  266. <xsl:if test="*[contains(@class,' topic/desc ')]">
  267. <xsl:call-template name="insertLinkDesc"/>
  268. </xsl:if>
  269. -->
  270. <xsl:if test="not(@scope = 'external' or not(empty(@format) or @format = 'dita')) and exists($referenceTitle) and not($element[contains(@class, ' topic/fn ')])">
  271. <!-- SourceForge bug 1880097: should not include page number when xref includes author specified text -->
  272. <xsl:if test="not(processing-instruction()[name()='ditaot'][.='usertext'])">
  273. <xsl:call-template name="insertPageNumberCitation">
  274. <xsl:with-param name="destination" select="$destination"/>
  275. <xsl:with-param name="element" select="$element"/>
  276. </xsl:call-template>
  277. </xsl:if>
  278. </xsl:if>
  279. </xsl:template>
  280. <!-- xref to footnote makes a callout. -->
  281. <xsl:template match="*[contains(@class,' topic/xref ')][@type='fn']" priority="2">
  282. <xsl:variable name="href-fragment" select="substring-after(@href, '#')"/>
  283. <xsl:variable name="elemId" select="substring-after($href-fragment, '/')"/>
  284. <xsl:variable name="topicId" select="substring-before($href-fragment, '/')"/>
  285. <xsl:variable name="footnote-target" select="key('fnById', $elemId)[ancestor::*[contains(@class, ' topic/topic ')][1]/@id = $topicId]"/>
  286. <xsl:apply-templates select="$footnote-target" mode="footnote-callout"/>
  287. </xsl:template>
  288. <xsl:template match="*[contains(@class,' topic/xref ')][empty(@href)]" priority="2">
  289. <fo:inline>
  290. <xsl:call-template name="commonattributes"/>
  291. <xsl:apply-templates select="*[not(contains(@class,' topic/desc '))] | text()" />
  292. </fo:inline>
  293. </xsl:template>
  294. <xsl:template match="*[contains(@class, ' topic/fn ')]" mode="footnote-callout">
  295. <fo:inline xsl:use-attribute-sets="fn__callout">
  296. <fo:basic-link internal-destination="{dita-ot:getFootnoteInternalID(.)}">
  297. <xsl:apply-templates select="." mode="callout"/>
  298. </fo:basic-link>
  299. </fo:inline>
  300. </xsl:template>
  301. <xsl:template match="*[contains(@class,' topic/related-links ')]">
  302. <xsl:if test="exists($includeRelatedLinkRoles)">
  303. <!--
  304. <xsl:variable name="topicType">
  305. <xsl:for-each select="parent::*">
  306. <xsl:call-template name="determineTopicType"/>
  307. </xsl:for-each>
  308. </xsl:variable>
  309. <xsl:variable name="collectedLinks">
  310. <xsl:apply-templates>
  311. <xsl:with-param name="topicType" select="$topicType"/>
  312. </xsl:apply-templates>
  313. </xsl:variable>
  314. <xsl:variable name="linkTextContent" select="string($collectedLinks)"/>
  315. <xsl:if test="normalize-space($linkTextContent)!=''">
  316. <fo:block xsl:use-attribute-sets="related-links">
  317. <fo:block xsl:use-attribute-sets="related-links.title">
  318. <xsl:call-template name="getVariable">
  319. <xsl:with-param name="id" select="'Related Links'"/>
  320. </xsl:call-template>
  321. </fo:block>
  322. <fo:block xsl:use-attribute-sets="related-links__content">
  323. <xsl:copy-of select="$collectedLinks"/>
  324. </fo:block>
  325. </fo:block>
  326. </xsl:if>
  327. -->
  328. <fo:block xsl:use-attribute-sets="related-links">
  329. <fo:block xsl:use-attribute-sets="related-links__content">
  330. <xsl:if test="$includeRelatedLinkRoles = ('child', 'descendant')">
  331. <xsl:call-template name="ul-child-links"/>
  332. <xsl:call-template name="ol-child-links"/>
  333. </xsl:if>
  334. <!--xsl:if test="$includeRelatedLinkRoles = ('next', 'previous', 'parent')">
  335. <xsl:call-template name="next-prev-parent-links"/>
  336. </xsl:if-->
  337. <xsl:variable name="unordered-links" as="element()*">
  338. <xsl:apply-templates select="." mode="related-links:group-unordered-links">
  339. <xsl:with-param name="nodes"
  340. select="descendant::*[contains(@class, ' topic/link ')]
  341. [not(related-links:omit-from-unordered-links(.))]
  342. [generate-id(.) = generate-id(key('hideduplicates', related-links:hideduplicates(.))[1])]"/>
  343. </xsl:apply-templates>
  344. </xsl:variable>
  345. <xsl:apply-templates select="$unordered-links"/>
  346. <!--linklists - last but not least, create all the linklists and their links, with no sorting or re-ordering-->
  347. <xsl:apply-templates select="*[contains(@class, ' topic/linklist ')]"/>
  348. </fo:block>
  349. </fo:block>
  350. </xsl:if>
  351. </xsl:template>
  352. <xsl:template name="ul-child-links">
  353. <xsl:variable name="children"
  354. select="descendant::*[contains(@class, ' topic/link ')]
  355. [@role = ('child', 'descendant')]
  356. [not(parent::*/@collection-type = 'sequence')]
  357. [not(ancestor::*[contains(@class, ' topic/linklist ')])]"/>
  358. <xsl:if test="$children">
  359. <fo:list-block xsl:use-attribute-sets="related-links.ul">
  360. <xsl:for-each select="$children[generate-id(.) = generate-id(key('link', related-links:link(.))[1])]">
  361. <fo:list-item xsl:use-attribute-sets="related-links.ul.li">
  362. <fo:list-item-label xsl:use-attribute-sets="related-links.ul.li__label">
  363. <fo:block xsl:use-attribute-sets="related-links.ul.li__label__content">
  364. <fo:inline>
  365. <xsl:call-template name="commonattributes"/>
  366. </fo:inline>
  367. <xsl:call-template name="getVariable">
  368. <xsl:with-param name="id" select="'Unordered List bullet'"/>
  369. </xsl:call-template>
  370. </fo:block>
  371. </fo:list-item-label>
  372. <fo:list-item-body xsl:use-attribute-sets="related-links.ul.li__body">
  373. <fo:block xsl:use-attribute-sets="related-links.ul.li__content">
  374. <xsl:apply-templates select="."/>
  375. </fo:block>
  376. </fo:list-item-body>
  377. </fo:list-item>
  378. </xsl:for-each>
  379. </fo:list-block>
  380. </xsl:if>
  381. </xsl:template>
  382. <xsl:template name="ol-child-links">
  383. <xsl:variable name="children"
  384. select="descendant::*[contains(@class, ' topic/link ')]
  385. [@role = ('child', 'descendant')]
  386. [parent::*/@collection-type = 'sequence']
  387. [not(ancestor::*[contains(@class, ' topic/linklist ')])]"/>
  388. <xsl:if test="$children">
  389. <fo:list-block xsl:use-attribute-sets="related-links.ol">
  390. <xsl:for-each select="($children[generate-id(.) = generate-id(key('link', related-links:link(.))[1])])">
  391. <fo:list-item xsl:use-attribute-sets="related-links.ol.li">
  392. <fo:list-item-label xsl:use-attribute-sets="related-links.ol.li__label">
  393. <fo:block xsl:use-attribute-sets="related-links.ol.li__label__content">
  394. <fo:inline>
  395. <xsl:call-template name="commonattributes"/>
  396. </fo:inline>
  397. <xsl:call-template name="getVariable">
  398. <xsl:with-param name="id" select="'Ordered List Number'"/>
  399. <xsl:with-param name="params">
  400. <number>
  401. <xsl:value-of select="position()"/>
  402. </number>
  403. </xsl:with-param>
  404. </xsl:call-template>
  405. </fo:block>
  406. </fo:list-item-label>
  407. <fo:list-item-body xsl:use-attribute-sets="related-links.ol.li__body">
  408. <fo:block xsl:use-attribute-sets="related-links.ol.li__content">
  409. <xsl:apply-templates select="."/>
  410. </fo:block>
  411. </fo:list-item-body>
  412. </fo:list-item>
  413. </xsl:for-each>
  414. </fo:list-block>
  415. </xsl:if>
  416. </xsl:template>
  417. <xsl:template name="getLinkScope" as="xs:string">
  418. <xsl:choose>
  419. <xsl:when test="ancestor-or-self::*[@scope][1]/@scope">
  420. <xsl:value-of select="ancestor-or-self::*[@scope][1]/@scope"/>
  421. </xsl:when>
  422. <xsl:otherwise>
  423. <xsl:value-of select="'local'"/>
  424. </xsl:otherwise>
  425. </xsl:choose>
  426. </xsl:template>
  427. <xsl:template match="*[contains(@class,' topic/link ')]">
  428. <xsl:param name="topicType" as="xs:string?">
  429. <xsl:for-each select="ancestor::*[contains(@class,' topic/topic ')][1]">
  430. <xsl:call-template name="determineTopicType"/>
  431. </xsl:for-each>
  432. </xsl:param>
  433. <xsl:choose>
  434. <xsl:when test="(@role and not($includeRelatedLinkRoles = @role)) or
  435. (not(@role) and not($includeRelatedLinkRoles = '#default'))"/>
  436. <xsl:when test="@role='child' and $chapterLayout='MINITOC' and
  437. $topicType = ('topicChapter', 'topicAppendix', 'topicPart')">
  438. <!-- When a minitoc already links to children, do not add them here -->
  439. </xsl:when>
  440. <xsl:otherwise>
  441. <xsl:apply-templates select="." mode="processLink"/>
  442. </xsl:otherwise>
  443. </xsl:choose>
  444. </xsl:template>
  445. <xsl:template match="*[contains(@class,' topic/link ')]" mode="processLink">
  446. <xsl:variable name="destination" select="opentopic-func:getDestinationId(@href)"/>
  447. <xsl:variable name="element" select="key('key_anchor',$destination, $root)[1]"/>
  448. <xsl:variable name="referenceTitle" as="node()*">
  449. <xsl:apply-templates select="." mode="insertReferenceTitle">
  450. <xsl:with-param name="href" select="@href"/>
  451. <xsl:with-param name="titlePrefix" select="''"/>
  452. <xsl:with-param name="destination" select="$destination"/>
  453. <xsl:with-param name="element" select="$element"/>
  454. </xsl:apply-templates>
  455. </xsl:variable>
  456. <xsl:variable name="linkScope" as="xs:string">
  457. <xsl:call-template name="getLinkScope"/>
  458. </xsl:variable>
  459. <fo:block xsl:use-attribute-sets="link">
  460. <fo:inline xsl:use-attribute-sets="link__content">
  461. <fo:basic-link>
  462. <xsl:call-template name="buildBasicLinkDestination">
  463. <xsl:with-param name="scope" select="$linkScope"/>
  464. <xsl:with-param name="href" select="@href"/>
  465. </xsl:call-template>
  466. <xsl:choose>
  467. <xsl:when test="not($linkScope = 'external') and exists($referenceTitle)">
  468. <xsl:copy-of select="$referenceTitle"/>
  469. </xsl:when>
  470. <xsl:when test="not($linkScope = 'external')">
  471. <xsl:call-template name="insertPageNumberCitation">
  472. <xsl:with-param name="isTitleEmpty" select="true()"/>
  473. <xsl:with-param name="destination" select="$destination"/>
  474. <xsl:with-param name="element" select="$element"/>
  475. </xsl:call-template>
  476. </xsl:when>
  477. <xsl:otherwise>
  478. <xsl:apply-templates select="*[contains(@class, ' topic/linktext ')]"/>
  479. </xsl:otherwise>
  480. </xsl:choose>
  481. </fo:basic-link>
  482. </fo:inline>
  483. <xsl:if test="not($linkScope = 'external') and exists($referenceTitle)">
  484. <xsl:call-template name="insertPageNumberCitation">
  485. <xsl:with-param name="destination" select="$destination"/>
  486. <xsl:with-param name="element" select="$element"/>
  487. </xsl:call-template>
  488. </xsl:if>
  489. <xsl:call-template name="insertLinkShortDesc">
  490. <xsl:with-param name="destination" select="$destination"/>
  491. <xsl:with-param name="element" select="$element"/>
  492. <xsl:with-param name="linkScope" select="$linkScope"/>
  493. </xsl:call-template>
  494. </fo:block>
  495. </xsl:template>
  496. <xsl:template name="buildBasicLinkDestination">
  497. <xsl:param name="scope" select="@scope"/>
  498. <xsl:param name="format" select="@format"/>
  499. <xsl:param name="href" select="@href"/>
  500. <xsl:choose>
  501. <xsl:when test="(contains($href, '://') and not(starts-with($href, 'file://')))
  502. or starts-with($href, '/') or $scope = 'external' or not(empty($format) or $format = 'dita')">
  503. <xsl:attribute name="external-destination">
  504. <xsl:text>url('</xsl:text>
  505. <xsl:value-of select="$href"/>
  506. <xsl:text>')</xsl:text>
  507. </xsl:attribute>
  508. </xsl:when>
  509. <xsl:when test="$scope = 'peer'">
  510. <xsl:attribute name="internal-destination">
  511. <xsl:value-of select="$href"/>
  512. </xsl:attribute>
  513. </xsl:when>
  514. <xsl:when test="contains($href, '#')">
  515. <xsl:attribute name="internal-destination">
  516. <xsl:value-of select="opentopic-func:getDestinationId($href)"/>
  517. </xsl:attribute>
  518. </xsl:when>
  519. <xsl:otherwise>
  520. <!-- Appears that topicmerge updates links so that this section will never be triggered;
  521. keeping $href as backup value in case something goes wrong. -->
  522. <xsl:attribute name="internal-destination">
  523. <xsl:value-of select="$href"/>
  524. </xsl:attribute>
  525. </xsl:otherwise>
  526. </xsl:choose>
  527. </xsl:template>
  528. <xsl:template name="insertPageNumberCitation">
  529. <xsl:param name="isTitleEmpty" as="xs:boolean" select="false()"/>
  530. <xsl:param name="destination" as="xs:string"/>
  531. <xsl:param name="element" as="element()?"/>
  532. <xsl:choose>
  533. <xsl:when test="not($element) or ($destination = '')"/>
  534. <xsl:when test="$isTitleEmpty">
  535. <fo:inline>
  536. <xsl:call-template name="getVariable">
  537. <xsl:with-param name="id" select="'Page'"/>
  538. <xsl:with-param name="params">
  539. <pagenum>
  540. <fo:inline>
  541. <fo:page-number-citation ref-id="{$destination}"/>
  542. </fo:inline>
  543. </pagenum>
  544. </xsl:with-param>
  545. </xsl:call-template>
  546. </fo:inline>
  547. </xsl:when>
  548. <xsl:otherwise>
  549. <fo:inline>
  550. <xsl:call-template name="getVariable">
  551. <xsl:with-param name="id" select="'On the page'"/>
  552. <xsl:with-param name="params">
  553. <pagenum>
  554. <fo:inline>
  555. <fo:page-number-citation ref-id="{$destination}"/>
  556. </fo:inline>
  557. </pagenum>
  558. </xsl:with-param>
  559. </xsl:call-template>
  560. </fo:inline>
  561. </xsl:otherwise>
  562. </xsl:choose>
  563. </xsl:template>
  564. <xsl:template match="*[contains(@class,' topic/linktext ')]">
  565. <fo:inline xsl:use-attribute-sets="linktext">
  566. <xsl:apply-templates/>
  567. </fo:inline>
  568. </xsl:template>
  569. <xsl:template match="*[contains(@class, ' topic/linklist ')]">
  570. <fo:block xsl:use-attribute-sets="linklist">
  571. <xsl:apply-templates/>
  572. </fo:block>
  573. </xsl:template>
  574. <xsl:template match="*[contains(@class,' topic/linkinfo ')]">
  575. <fo:block xsl:use-attribute-sets="linkinfo">
  576. <xsl:apply-templates/>
  577. </fo:block>
  578. </xsl:template>
  579. <xsl:template match="*[contains(@class,' topic/linkpool ')]">
  580. <xsl:param name="topicType"/>
  581. <fo:block xsl:use-attribute-sets="linkpool">
  582. <xsl:apply-templates>
  583. <xsl:with-param name="topicType" select="$topicType"/>
  584. </xsl:apply-templates>
  585. </fo:block>
  586. </xsl:template>
  587. <xsl:function name="opentopic-func:getDestinationId">
  588. <xsl:param name="href"/>
  589. <xsl:call-template name="getDestinationIdImpl">
  590. <xsl:with-param name="href" select="$href"/>
  591. </xsl:call-template>
  592. </xsl:function>
  593. <xsl:template name="getDestinationIdImpl">
  594. <xsl:param name="href"/>
  595. <xsl:variable name="topic-id" select="substring-after($href, '#')"/>
  596. <xsl:variable name="element-id" select="substring-after($topic-id, '/')"/>
  597. <xsl:choose>
  598. <xsl:when test="$element-id = ''">
  599. <xsl:value-of select="$topic-id"/>
  600. </xsl:when>
  601. <xsl:otherwise>
  602. <xsl:value-of select="$element-id"/>
  603. </xsl:otherwise>
  604. </xsl:choose>
  605. </xsl:template>
  606. <!-- Deprecated since 2.3 -->
  607. <xsl:template name="brokenLinks">
  608. </xsl:template>
  609. <!-- Links with @type="topic" belong in no-name group. -->
  610. <xsl:template match="*[contains(@class, ' topic/link ')]" mode="related-links:get-group-priority"
  611. name="related-links:group-priority.topic" priority="-10"
  612. as="xs:integer">
  613. <xsl:call-template name="related-links:group-priority."/>
  614. </xsl:template>
  615. <xsl:template match="*[contains(@class, ' topic/link ')]" mode="related-links:get-group"
  616. name="related-links:group.topic" priority="-10"
  617. as="xs:string">
  618. <xsl:call-template name="related-links:group."/>
  619. </xsl:template>
  620. <!-- Override no-name group wrapper template for HTML: output "Related Information" in a <linklist>. -->
  621. <xsl:template match="*[contains(@class, ' topic/link ')]" mode="related-links:result-group" name="related-links:group-result."
  622. as="element()?" priority="-10">
  623. <xsl:param name="links" as="node()*"/>
  624. <xsl:if test="exists($links)">
  625. <linklist class="- topic/linklist " outputclass="relinfo">
  626. <title class="- topic/title ">
  627. <xsl:call-template name="getVariable">
  628. <xsl:with-param name="id" select="'Related information'"/>
  629. </xsl:call-template>
  630. </title>
  631. <xsl:copy-of select="$links"/>
  632. </linklist>
  633. </xsl:if>
  634. </xsl:template>
  635. <!-- Concepts have their own group. -->
  636. <xsl:template match="*[contains(@class, ' topic/link ')][@type='concept']" mode="related-links:get-group"
  637. name="related-links:group.concept"
  638. as="xs:string">
  639. <xsl:text>concept</xsl:text>
  640. </xsl:template>
  641. <!-- Priority of concept group. -->
  642. <xsl:template match="*[contains(@class, ' topic/link ')][@type='concept']" mode="related-links:get-group-priority"
  643. name="related-links:group-priority.concept"
  644. as="xs:integer">
  645. <xsl:sequence select="3"/>
  646. </xsl:template>
  647. <!-- Wrapper for concept group: "Related concepts" in a <div>. -->
  648. <xsl:template match="*[contains(@class, ' topic/link ')][@type='concept']" mode="related-links:result-group"
  649. name="related-links:result.concept" as="element()?">
  650. <xsl:param name="links" as="node()*"/>
  651. <xsl:if test="normalize-space(string-join($links, ''))">
  652. <linklist class="- topic/linklist " outputclass="relinfo relconcepts">
  653. <title class="- topic/title ">
  654. <xsl:call-template name="getVariable">
  655. <xsl:with-param name="id" select="'Related concepts'"/>
  656. </xsl:call-template>
  657. </title>
  658. <xsl:copy-of select="$links"/>
  659. </linklist>
  660. </xsl:if>
  661. </xsl:template>
  662. <!-- References have their own group. -->
  663. <xsl:template match="*[contains(@class, ' topic/link ')][@type='reference']" mode="related-links:get-group"
  664. name="related-links:group.reference"
  665. as="xs:string">
  666. <xsl:text>reference</xsl:text>
  667. </xsl:template>
  668. <!-- Priority of reference group. -->
  669. <xsl:template match="*[contains(@class, ' topic/link ')][@type='reference']" mode="related-links:get-group-priority"
  670. name="related-links:group-priority.reference"
  671. as="xs:integer">
  672. <xsl:sequence select="1"/>
  673. </xsl:template>
  674. <!-- Reference wrapper for HTML: "Related reference" in <div>. -->
  675. <xsl:template match="*[contains(@class, ' topic/link ')][@type='reference']" mode="related-links:result-group"
  676. name="related-links:result.reference" as="element()?">
  677. <xsl:param name="links"/>
  678. <xsl:if test="normalize-space(string-join($links, ''))">
  679. <linklist class="- topic/linklist " outputclass="relinfo relref">
  680. <title class="- topic/title ">
  681. <xsl:call-template name="getVariable">
  682. <xsl:with-param name="id" select="'Related reference'"/>
  683. </xsl:call-template>
  684. </title>
  685. <xsl:copy-of select="$links"/>
  686. </linklist>
  687. </xsl:if>
  688. </xsl:template>
  689. <!-- Tasks have their own group. -->
  690. <xsl:template match="*[contains(@class, ' topic/link ')][@type='task']" mode="related-links:get-group"
  691. name="related-links:group.task"
  692. as="xs:string">
  693. <xsl:text>task</xsl:text>
  694. </xsl:template>
  695. <!-- Priority of task group. -->
  696. <xsl:template match="*[contains(@class, ' topic/link ')][@type='task']" mode="related-links:get-group-priority"
  697. name="related-links:group-priority.task"
  698. as="xs:integer">
  699. <xsl:sequence select="2"/>
  700. </xsl:template>
  701. <!-- Task wrapper for HTML: "Related tasks" in <div>. -->
  702. <xsl:template match="*[contains(@class, ' topic/link ')][@type='task']" mode="related-links:result-group"
  703. name="related-links:result.task" as="element()?">
  704. <xsl:param name="links" as="node()*"/>
  705. <xsl:if test="normalize-space(string-join($links, ''))">
  706. <linklist class="- topic/linklist " outputclass="relinfo reltasks">
  707. <title class="- topic/title ">
  708. <xsl:call-template name="getVariable">
  709. <xsl:with-param name="id" select="'Related tasks'"/>
  710. </xsl:call-template>
  711. </title>
  712. <xsl:copy-of select="$links"/>
  713. </linklist>
  714. </xsl:if>
  715. </xsl:template>
  716. </xsl:stylesheet>