body.xsl 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!--
  3. * This file is part of the LibreOffice project.
  4. *
  5. * This Source Code Form is subject to the terms of the Mozilla Public
  6. * License, v. 2.0. If a copy of the MPL was not distributed with this
  7. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  8. *
  9. * This file incorporates work covered by the following license notice:
  10. *
  11. * Licensed to the Apache Software Foundation (ASF) under one or more
  12. * contributor license agreements. See the NOTICE file distributed
  13. * with this work for additional information regarding copyright
  14. * ownership. The ASF licenses this file to you under the Apache
  15. * License, Version 2.0 (the "License"); you may not use this file
  16. * except in compliance with the License. You may obtain a copy of
  17. * the License at http://www.apache.org/licenses/LICENSE-2.0 .
  18. -->
  19. <!--
  20. For further documentation and updates visit http://xml.openoffice.org/odf2xhtml
  21. -->
  22. <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:java="http://xml.apache.org/xslt/java" xmlns:urlencoder="http://www.jclark.com/xt/java/java.net.URLEncoder" exclude-result-prefixes="chart config dc dom dr3d draw fo form math meta number office ooo oooc ooow script style svg table text xforms xlink xsd xsi java urlencoder">
  23. <xsl:include href="table_of_content.xsl"/>
  24. <!-- ****************** -->
  25. <!-- *** Whitespace *** -->
  26. <!-- ****************** -->
  27. <xsl:template match="text:s">
  28. <xsl:call-template name="write-breakable-whitespace">
  29. <xsl:with-param name="whitespaces" select="@text:c"/>
  30. </xsl:call-template>
  31. </xsl:template>
  32. <!--write the number of 'whitespaces' -->
  33. <xsl:template name="write-breakable-whitespace">
  34. <xsl:param name="whitespaces"/>
  35. <!--write two space chars as the normal white space character will be stripped
  36. and the other is able to break -->
  37. <xsl:text>&#160;</xsl:text>
  38. <xsl:if test="$whitespaces >= 2">
  39. <xsl:call-template name="write-breakable-whitespace-2">
  40. <xsl:with-param name="whitespaces" select="$whitespaces - 1"/>
  41. </xsl:call-template>
  42. </xsl:if>
  43. </xsl:template>
  44. <!--write the number of 'whitespaces' -->
  45. <xsl:template name="write-breakable-whitespace-2">
  46. <xsl:param name="whitespaces"/>
  47. <!--write two space chars as the normal white space character will be stripped
  48. and the other is able to break -->
  49. <xsl:text> </xsl:text>
  50. <xsl:if test="$whitespaces >= 2">
  51. <xsl:call-template name="write-breakable-whitespace">
  52. <xsl:with-param name="whitespaces" select="$whitespaces - 1"/>
  53. </xsl:call-template>
  54. </xsl:if>
  55. </xsl:template>
  56. <!-- currentSolution: 8 non-breakable-spaces instead of a TAB is an approximation.
  57. Sometimes less spaces than 8 might be needed and the output might be more difficult to read-->
  58. <xsl:template match="text:tab">
  59. <xsl:param name="globalData"/>
  60. <xsl:call-template name="write-breakable-whitespace">
  61. <xsl:with-param name="whitespaces" select="8"/>
  62. </xsl:call-template>
  63. </xsl:template>
  64. <!-- *************** -->
  65. <!-- *** Textbox *** -->
  66. <!-- *************** -->
  67. <!-- ID / NAME of text-box -->
  68. <xsl:template match="@draw:name">
  69. <xsl:attribute name="id">
  70. <xsl:choose>
  71. <xsl:when test="number(substring(.,1,1))">
  72. <!-- Heuristic: If the first character is a number a 'a_' will be set
  73. as prefix, as id have to be of type NMTOKEN -->
  74. <xsl:value-of select="concat('a_',translate(., '&#xA;&amp;&lt;&gt;.,;: %()[]/\+', '___________________________'))"/>
  75. </xsl:when>
  76. <xsl:otherwise>
  77. <xsl:value-of select="translate(., '&#xA;&amp;&lt;&gt;.,;: %()[]/\+', '___________________________')"/>
  78. </xsl:otherwise>
  79. </xsl:choose>
  80. </xsl:attribute>
  81. </xsl:template>
  82. <xsl:template match="text:line-break">
  83. <xsl:param name="listIndent"/>
  84. <xsl:element namespace="{$namespace}" name="br"/>
  85. <!-- line breaks in lists need an indent similar to the list label -->
  86. <xsl:if test="$listIndent">
  87. <xsl:element namespace="{$namespace}" name="span">
  88. <xsl:attribute name="style">margin-left:<xsl:value-of select="$listIndent"/>cm</xsl:attribute>
  89. </xsl:element>
  90. </xsl:if>
  91. </xsl:template>
  92. <!-- currently there have to be an explicit call of the style attribute nodes, maybe the attributes nodes have no priority only order relevant-->
  93. <xsl:template name="apply-styles-and-content">
  94. <xsl:param name="globalData"/>
  95. <xsl:param name="footnotePrefix" />
  96. <xsl:apply-templates select="@*">
  97. <xsl:with-param name="globalData" select="$globalData"/>
  98. </xsl:apply-templates>
  99. <!-- the footnote symbol is the prefix for a footnote in the footer -->
  100. <xsl:copy-of select="$footnotePrefix"/>
  101. <xsl:apply-templates select="node()">
  102. <xsl:with-param name="globalData" select="$globalData"/>
  103. </xsl:apply-templates>
  104. </xsl:template>
  105. <!-- ******************* -->
  106. <!-- *** References *** -->
  107. <!-- ******************* -->
  108. <xsl:template match="text:reference-ref | text:sequence-ref | text:bookmark-ref">
  109. <xsl:param name="globalData"/>
  110. <xsl:if test="*|text()">
  111. <xsl:element namespace="{$namespace}" name="a">
  112. <xsl:attribute name="href">
  113. <xsl:text>#</xsl:text>
  114. <xsl:choose>
  115. <xsl:when test="number(substring(@text:ref-name,1,1))">
  116. <!-- Heuristic: If the first character is a number a 'a_' will be set
  117. as prefix, as id have to be of type NMTOKEN -->
  118. <xsl:value-of select="concat('a_',translate(@text:ref-name, '&#xA;&amp;&lt;&gt;.,;: %()[]/\+', '___________________________'))"/>
  119. </xsl:when>
  120. <xsl:otherwise>
  121. <xsl:value-of select="translate(@text:ref-name, '&#xA;&amp;&lt;&gt;.,;: %()[]/\+', '___________________________')"/>
  122. </xsl:otherwise>
  123. </xsl:choose>
  124. </xsl:attribute>
  125. <xsl:apply-templates select="@* | node()">
  126. <xsl:with-param name="globalData" select="$globalData"/>
  127. </xsl:apply-templates>
  128. </xsl:element>
  129. </xsl:if>
  130. </xsl:template>
  131. <xsl:template match="@text:name">
  132. <xsl:attribute name="id">
  133. <xsl:choose>
  134. <xsl:when test="number(substring(.,1,1))">
  135. <!-- Heuristic: If the first character is a number a 'a_' will be set
  136. as prefix, as id have to be of type NMTOKEN -->
  137. <xsl:value-of select="concat('a_',translate(., '&#xA;&amp;&lt;&gt;.,;: %()[]/\+', '___________________________'))"/>
  138. </xsl:when>
  139. <xsl:otherwise>
  140. <xsl:value-of select="translate(., '&#xA;&amp;&lt;&gt;.,;: %()[]/\+', '___________________________')"/>
  141. </xsl:otherwise>
  142. </xsl:choose>
  143. </xsl:attribute>
  144. </xsl:template>
  145. <xsl:template match="text:sequence">
  146. <xsl:param name="globalData"/>
  147. <xsl:element namespace="{$namespace}" name="a">
  148. <xsl:apply-templates select="@*" />
  149. <xsl:attribute name="id">
  150. <xsl:choose>
  151. <xsl:when test="number(substring(@text:ref-name,1,1))">
  152. <!-- Heuristic: If the first character is a number a 'a_' will be set
  153. as prefix, as id have to be of type NMTOKEN -->
  154. <xsl:value-of select="concat('a_',translate(@text:ref-name, '&#xA;&amp;&lt;&gt;.,;: %()[]/\+', '___________________________'))"/>
  155. </xsl:when>
  156. <xsl:otherwise>
  157. <xsl:value-of select="translate(@text:ref-name, '&#xA;&amp;&lt;&gt;.,;: %()[]/\+', '___________________________')"/>
  158. </xsl:otherwise>
  159. </xsl:choose>
  160. </xsl:attribute>
  161. </xsl:element>
  162. <xsl:apply-templates>
  163. <xsl:with-param name="globalData" select="$globalData"/>
  164. </xsl:apply-templates>
  165. </xsl:template>
  166. <xsl:template match="text:reference-mark">
  167. <xsl:param name="globalData"/>
  168. <xsl:element namespace="{$namespace}" name="a">
  169. <xsl:apply-templates select="@*" />
  170. <xsl:attribute name="id">
  171. <xsl:choose>
  172. <xsl:when test="number(substring(@text:name,1,1))">
  173. <!-- Heuristic: If the first character is a number a 'a_' will be set
  174. as prefix, as id have to be of type NMTOKEN -->
  175. <xsl:value-of select="concat('a_',translate(@text:name, '&#xA;&amp;&lt;&gt;.,;: %()[]/\+', '___________________________'))"/>
  176. </xsl:when>
  177. <xsl:otherwise>
  178. <xsl:value-of select="translate(@text:name, '&#xA;&amp;&lt;&gt;.,;: %()[]/\+', '___________________________')"/>
  179. </xsl:otherwise>
  180. </xsl:choose>
  181. </xsl:attribute>
  182. </xsl:element>
  183. <xsl:apply-templates>
  184. <xsl:with-param name="globalData" select="$globalData"/>
  185. </xsl:apply-templates>
  186. </xsl:template>
  187. <xsl:template match="text:reference-mark-start">
  188. <xsl:param name="globalData"/>
  189. <xsl:element namespace="{$namespace}" name="a">
  190. <xsl:apply-templates select="@*" />
  191. </xsl:element>
  192. </xsl:template>
  193. <xsl:template match="text:bibliography-mark">
  194. <xsl:param name="globalData"/>
  195. <xsl:element namespace="{$namespace}" name="a">
  196. <xsl:apply-templates select="@* | node()">
  197. <xsl:with-param name="globalData" select="$globalData"/>
  198. </xsl:apply-templates>
  199. </xsl:element>
  200. </xsl:template>
  201. <!-- @text:title exist only in text:bibliography-mark -->
  202. <xsl:template match="@text:title">
  203. <xsl:attribute name="title">
  204. <xsl:value-of select="."/>
  205. </xsl:attribute>
  206. </xsl:template>
  207. <!-- @text:url exist only in text:bibliography-mark -->
  208. <xsl:template match="@text:url">
  209. <xsl:attribute name="href">
  210. <xsl:value-of select="."/>
  211. </xsl:attribute>
  212. </xsl:template>
  213. <xsl:template match="text:user-defined">
  214. <xsl:apply-templates/>
  215. </xsl:template>
  216. <xsl:template match="office:annotation">
  217. <xsl:element name="span">
  218. <xsl:attribute name="title">annotation</xsl:attribute>
  219. <xsl:attribute name="class">annotation_style_by_filter</xsl:attribute>
  220. <xsl:apply-templates select="@*" />
  221. <br/>
  222. <xsl:text>[ANNOTATION:</xsl:text>
  223. <br/>
  224. <xsl:apply-templates select="*" mode="annotation"/>
  225. <xsl:text>]</xsl:text>
  226. </xsl:element>
  227. </xsl:template>
  228. <xsl:template match="text:p" mode="annotation">
  229. <br/>
  230. <xsl:element name="span">
  231. <xsl:text>NOTE: '</xsl:text>
  232. <xsl:apply-templates />
  233. <xsl:text>'</xsl:text>
  234. </xsl:element>
  235. </xsl:template>
  236. <xsl:template match="dc:creator" mode="annotation">
  237. <br/>
  238. <xsl:element name="span">
  239. <xsl:attribute name="title">dc:creator</xsl:attribute>
  240. <xsl:text>BY '</xsl:text>
  241. <xsl:apply-templates />
  242. <xsl:text>'</xsl:text>
  243. </xsl:element>
  244. </xsl:template>
  245. <xsl:template match="dc:date" mode="annotation">
  246. <br/>
  247. <xsl:element name="span">
  248. <xsl:attribute name="title">dc:date</xsl:attribute>
  249. <xsl:text>ON '</xsl:text>
  250. <xsl:apply-templates />
  251. <xsl:text>'</xsl:text>
  252. </xsl:element>
  253. </xsl:template>
  254. <xsl:template match="meta:date-string" mode="annotation">
  255. <br/>
  256. <xsl:element name="span">
  257. <xsl:attribute name="title">meta-date-string</xsl:attribute>
  258. <xsl:text>META DATE '</xsl:text>
  259. <xsl:apply-templates />
  260. <xsl:text>'</xsl:text>
  261. </xsl:element>
  262. </xsl:template>
  263. <!-- *************** -->
  264. <!-- *** HELPER *** -->
  265. <!-- *************** -->
  266. <xsl:template name="create-href">
  267. <xsl:param name="href"/>
  268. <xsl:param name="mimetype"/>
  269. <xsl:choose>
  270. <!-- internal OOo URL used in content tables -->
  271. <xsl:when test="contains($href, '%7Coutline') or contains($href, '|outline')">
  272. <!-- the simplest workaround for content tables in a single document is to create an anchor from every heading element.
  273. Downside: multiple identical headings won't refer always to the first.
  274. -->
  275. <xsl:text>#</xsl:text>
  276. <xsl:variable name="title">
  277. <xsl:apply-templates mode="concatenate"/>
  278. </xsl:variable>
  279. <xsl:value-of select="concat('a_', translate(normalize-space($title), '.,;: %()[]/\+', '_____________'))"/>
  280. </xsl:when>
  281. <xsl:when test="self::draw:image[office:binary-data]">
  282. <xsl:choose>
  283. <xsl:when test="$mimetype">
  284. <xsl:text>data:</xsl:text><xsl:value-of select="$mimetype"/><xsl:text>;base64,</xsl:text><xsl:value-of select="office:binary-data"/>
  285. </xsl:when>
  286. <xsl:otherwise>
  287. <xsl:text>data:image/*;base64,</xsl:text><xsl:value-of select="office:binary-data"/>
  288. </xsl:otherwise>
  289. </xsl:choose>
  290. </xsl:when>
  291. <xsl:otherwise>
  292. <xsl:choose>
  293. <!-- in case of packed open office document -->
  294. <xsl:when test="starts-with($sourceBaseURL, 'jar:') or $isPackageFormat">
  295. <xsl:choose>
  296. <!-- for images relative to open office document -->
  297. <xsl:when test="starts-with($href, '../')">
  298. <!-- creating an absolute http URL to the packed image file (removing the '.')-->
  299. <xsl:value-of select="concat(substring-after(substring-before($sourceBaseURL, '!'), 'jar:'), '/', $href, $optionalURLSuffix)"/>
  300. </xsl:when>
  301. <!-- for absolute URLs & absolute paths -->
  302. <xsl:when test="contains($href, ':') or starts-with($href, '/')">
  303. <xsl:value-of select="concat($href, $optionalURLSuffix)"/>
  304. </xsl:when>
  305. <!-- for images jared in open office document -->
  306. <xsl:otherwise>
  307. <xsl:value-of select="concat($sourceBaseURL, $href, $optionalURLSuffix)"/>
  308. </xsl:otherwise>
  309. </xsl:choose>
  310. </xsl:when>
  311. <xsl:otherwise>
  312. <xsl:choose>
  313. <!-- for absolute URLs & Paths -->
  314. <xsl:when test="contains($href, ':') or starts-with($href, '/')">
  315. <xsl:value-of select="concat($href, $optionalURLSuffix)"/>
  316. </xsl:when>
  317. <!-- for relative URLs -->
  318. <xsl:when test="starts-with($href, '#')">
  319. <!-- intra document ref -->
  320. <xsl:value-of select="$href"/>
  321. </xsl:when>
  322. <xsl:otherwise>
  323. <xsl:value-of select="concat($sourceBaseURL, $href, $optionalURLSuffix)"/>
  324. </xsl:otherwise>
  325. </xsl:choose>
  326. </xsl:otherwise>
  327. </xsl:choose>
  328. </xsl:otherwise>
  329. </xsl:choose>
  330. </xsl:template>
  331. <xsl:template match="text()" mode="concatenate">
  332. <xsl:value-of select="."/>
  333. </xsl:template>
  334. <xsl:template match="*" mode="concatenate">
  335. <xsl:apply-templates mode="concatenate"/>
  336. </xsl:template>
  337. <!-- ******************** -->
  338. <!-- *** Common Rules *** -->
  339. <!-- ******************** -->
  340. <!-- ignore / neglect the following elements -->
  341. <xsl:template match="draw:custom-shape | draw:g | office:forms | text:alphabetical-index-mark | text:alphabetical-index-mark-end | text:alphabetical-index-mark-start | text:bibliography-source | text:number | text:reference-mark-end | text:sequence-decls | text:soft-page-break | text:table-of-content-source | text:tracked-changes | text:user-field-decls"/>
  342. <!-- default template used by purpose-->
  343. <xsl:template match="text:bibliography | text:change-end | text:change-start">
  344. <xsl:param name="globalData"/>
  345. <xsl:apply-templates>
  346. <xsl:with-param name="globalData" select="$globalData"/>
  347. </xsl:apply-templates>
  348. </xsl:template>
  349. <!-- default template for not recognized elements -->
  350. <xsl:template match="*">
  351. <xsl:param name="globalData"/>
  352. <xsl:message>Using default element rule for ODF element '<xsl:value-of select="name()"/>'.</xsl:message>
  353. <xsl:apply-templates>
  354. <xsl:with-param name="globalData" select="$globalData"/>
  355. </xsl:apply-templates>
  356. </xsl:template>
  357. <xsl:template match="@*"/>
  358. <!-- allowing all matched text nodes -->
  359. <xsl:template match="text()">
  360. <xsl:value-of select="."/>
  361. </xsl:template>
  362. </xsl:stylesheet>