1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/helpers/mimeXhtmlPart-make-paragraphs.xsl Sun Oct 16 20:55:46 2011 +0200
1.3 @@ -0,0 +1,227 @@
1.4 +<?xml version="1.0" encoding="UTF-8"?>
1.5 +<xsl:stylesheet version="2.0"
1.6 + xmlns="http://www.w3.org/1999/xhtml"
1.7 + xmlns:h="http://www.w3.org/1999/xhtml"
1.8 + xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
1.9 + xmlns:fn="http://www.w3.org/2005/xpath-functions"
1.10 + xmlns:svg="http://www.w3.org/2000/svg"
1.11 + xmlns:xs="http://www.w3.org/2001/XMLSchema"
1.12 + xmlns:o="https://trac.frantovo.cz/odstavcovac-TODO-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-/wiki/xmlns/odstavcovac"
1.13 + exclude-result-prefixes="fn h xs">
1.14 + <xsl:output method="xml" indent="yes" encoding="UTF-8"/>
1.15 +
1.16 +
1.17 + <!-- Celý dokument -->
1.18 + <xsl:template match="/">
1.19 + <html>
1.20 + <head>
1.21 + <style type="text/css">
1.22 + .mešuge {
1.23 + background-color: #afa;
1.24 + border: 1px solid #55f;
1.25 + }
1.26 + </style>
1.27 + </head>
1.28 +
1.29 + <body>
1.30 +
1.31 + <xsl:variable name="prvníKolo">
1.32 + <xsl:apply-templates select="h:html/h:body/node()" mode="prvníKolo"/>
1.33 + </xsl:variable>
1.34 +
1.35 + <xsl:variable name="druhéKolo">
1.36 + <xsl:apply-templates select="$prvníKolo" mode="druhéKolo"/>
1.37 + </xsl:variable>
1.38 +
1.39 + <xsl:apply-templates select="$druhéKolo" mode="třetíKolo"/>
1.40 +
1.41 + </body>
1.42 + </html>
1.43 + </xsl:template>
1.44 +
1.45 +
1.46 + <!-- Mezi odstavci je prázdný řádek, můžou být mezery/tabulátory. -->
1.47 + <xsl:variable name="oddělovač" select="'\n\s*\n\s*'"/>
1.48 +
1.49 +
1.50 + <!-- Funkce: zda jde o XHTML inline element – může se vyskytovat uvnitř odstavců. -->
1.51 + <xsl:template name="inlineElement" as="xs:boolean">
1.52 + <xsl:param name="prvek"/>
1.53 + <xsl:sequence select="
1.54 + $prvek/name() = 'a' or
1.55 + $prvek/name() = 'abbr' or
1.56 + $prvek/name() = 'acronym' or
1.57 + $prvek/name() = 'b' or
1.58 + $prvek/name() = 'br' or
1.59 + $prvek/name() = 'cite' or
1.60 + $prvek/name() = 'code' or
1.61 + $prvek/name() = 'em' or
1.62 + $prvek/name() = 'i' or
1.63 + $prvek/name() = 'img' or
1.64 + $prvek/name() = 'q' or
1.65 + $prvek/name() = 'span' or
1.66 + $prvek/name() = 'strong' or
1.67 + $prvek/name() = 'sub' or
1.68 + $prvek/name() = 'sup' or
1.69 + $prvek/name() = 'tt' or
1.70 + $prvek/name() = 'u' or
1.71 + $prvek/name() = 'var'
1.72 + "/>
1.73 + <!-- …případně další, pokud je budeme chtít podporovat. -->
1.74 + </xsl:template>
1.75 +
1.76 +
1.77 + <!-- Funkce: zda je prvek začátkem odstavce. -->
1.78 + <xsl:template name="začátekOdstavce" as="xs:boolean">
1.79 + <xsl:param name="prvek"/>
1.80 +
1.81 + <xsl:variable name="inlineElement" as="xs:boolean">
1.82 + <xsl:call-template name="inlineElement"><xsl:with-param name="prvek" select="$prvek"/></xsl:call-template>
1.83 + </xsl:variable>
1.84 +
1.85 + <xsl:variable name="předchůdce" select="$prvek/preceding-sibling::node()[1]"/>
1.86 +
1.87 + <xsl:variable name="inlineElementPředchůdce" as="xs:boolean">
1.88 + <xsl:call-template name="inlineElement"><xsl:with-param name="prvek" select="$předchůdce"/></xsl:call-template>
1.89 + </xsl:variable>
1.90 +
1.91 + <xsl:variable name="textovýUzel" select="boolean($prvek/self::text())"/>
1.92 +
1.93 + <xsl:sequence select="
1.94 + ($inlineElement or $textovýUzel)
1.95 + and
1.96 + (
1.97 + ($inlineElementPředchůdce and matches($prvek, concat('^', $oddělovač, '.*')))
1.98 + or
1.99 + not($inlineElementPředchůdce)
1.100 + or
1.101 + not($předchůdce)
1.102 + )
1.103 + and
1.104 + (
1.105 + not($předchůdce/self::text())
1.106 + or
1.107 + matches($předchůdce/self::text(), concat('.*', $oddělovač, '$'))
1.108 + )
1.109 + "/>
1.110 + </xsl:template>
1.111 +
1.112 +
1.113 + <!--
1.114 + V prvním kole zavřeme volný text a inline elementy do značek <o:odstavec typ=""/>,
1.115 + kde typ může být "začátek", což značí, že se jedná o první část budoucího odstavce <p/>.
1.116 + -->
1.117 + <xsl:template match="text()" mode="prvníKolo">
1.118 +
1.119 + <xsl:variable name="začátekOdstavce" as="xs:boolean">
1.120 + <xsl:call-template name="začátekOdstavce">
1.121 + <xsl:with-param name="prvek" select="."/>
1.122 + </xsl:call-template>
1.123 + </xsl:variable>
1.124 +
1.125 + <xsl:for-each select="fn:tokenize(., $oddělovač)">
1.126 + <xsl:element name="o:odstavec">
1.127 + <xsl:if test="$začátekOdstavce or not(position() = 1)">
1.128 + <xsl:attribute name="typ">začátek</xsl:attribute>
1.129 + </xsl:if>
1.130 + <xsl:value-of select="."/>
1.131 + </xsl:element>
1.132 + </xsl:for-each>
1.133 +
1.134 + </xsl:template>
1.135 +
1.136 + <!--
1.137 + Inline elementy zavíráme do <o:odstavec typ=""/>,
1.138 + ostatní vkládáme, jak jsou.
1.139 + -->
1.140 + <xsl:template match="*" mode="prvníKolo">
1.141 +
1.142 + <xsl:variable name="inlineElement" as="xs:boolean">
1.143 + <xsl:call-template name="inlineElement">
1.144 + <xsl:with-param name="prvek" select="."/>
1.145 + </xsl:call-template>
1.146 + </xsl:variable>
1.147 +
1.148 + <xsl:choose>
1.149 + <!-- TODO: zvláštní šablona (match="…") pro inline elementy místo větvení? -->
1.150 + <xsl:when test="$inlineElement">
1.151 + <xsl:variable name="začátekOdstavce" as="xs:boolean">
1.152 + <xsl:call-template name="začátekOdstavce">
1.153 + <xsl:with-param name="prvek" select="."/>
1.154 + </xsl:call-template>
1.155 + </xsl:variable>
1.156 + <xsl:element name="o:odstavec">
1.157 + <xsl:if test="$začátekOdstavce">
1.158 + <xsl:attribute name="typ">začátek</xsl:attribute>
1.159 + </xsl:if>
1.160 + <xsl:copy-of select="."/>
1.161 + </xsl:element>
1.162 + </xsl:when>
1.163 + <xsl:otherwise>
1.164 + <xsl:copy-of select="."/>
1.165 + </xsl:otherwise>
1.166 + </xsl:choose>
1.167 +
1.168 + </xsl:template>
1.169 +
1.170 + <!-- V druhém kole spojíme jednotlivé části odstavců. -->
1.171 + <xsl:template match="o:odstavec[@typ='začátek']" mode="druhéKolo">
1.172 + <o:odstavec>
1.173 + <xsl:call-template name="spojOdstavce">
1.174 + <xsl:with-param name="část" select="."/>
1.175 + </xsl:call-template>
1.176 + </o:odstavec>
1.177 + </xsl:template>
1.178 + <!-- Následující části odstavce přeskočíme – postará se o ně vnitřní smyčka volaná z předchozí šablony. -->
1.179 + <xsl:template match="o:odstavec" mode="druhéKolo"/>
1.180 + <!-- Neinline (blokové) elementy vložíme, jak jsou. -->
1.181 + <xsl:template match="*" mode="druhéKolo">
1.182 + <xsl:copy-of select="."/>
1.183 + </xsl:template>
1.184 +
1.185 +
1.186 + <!--
1.187 + Za první část (parametr, <o:odstavec typ="začátek"/>) resp. její vnitřek
1.188 + připojíme (rekurze) všechny další části téhož odstavce (oddělíme mezerou).
1.189 + Konec odstavce poznáme tak, že následovník je něco jiného než <o:odstavec/> nebo má atribut typ="začátek".
1.190 + -->
1.191 + <xsl:template name="spojOdstavce">
1.192 + <xsl:param name="část"/>
1.193 + <xsl:copy-of select="$část/child::node()"/>
1.194 + <xsl:variable name="následovník" select="$část/following-sibling::node()[1]"/>
1.195 + <xsl:if test="$následovník/name() = 'o:odstavec' and not($následovník/@typ = 'začátek')">
1.196 + <xsl:text> </xsl:text>
1.197 + <xsl:call-template name="spojOdstavce">
1.198 + <xsl:with-param name="část" select="$následovník"/>
1.199 + </xsl:call-template>
1.200 + </xsl:if>
1.201 + </xsl:template>
1.202 +
1.203 +
1.204 + <!-- Ve třetím kole smažeme prázdné mešuge odstavce. -->
1.205 + <xsl:template mode="třetíKolo" match="o:odstavec[
1.206 + count(child::node()) = 0
1.207 + or
1.208 + (
1.209 + count(child::node()) = 1
1.210 + and
1.211 + text()
1.212 + and
1.213 + matches(text(), '^\s*$')
1.214 + )
1.215 + ]">
1.216 + <xsl:text> </xsl:text>
1.217 + </xsl:template>
1.218 + <!-- Převedeme z <o:odstavec/> na <p/> -->
1.219 + <xsl:template match="o:odstavec" mode="třetíKolo">
1.220 + <p class="mešuge">
1.221 + <xsl:copy-of select="child::node()"/>
1.222 + </p>
1.223 + </xsl:template>
1.224 + <!-- Všechno ostatní zkopírujeme, jak je. -->
1.225 + <xsl:template match="*" mode="třetíKolo">
1.226 + <xsl:copy-of select="."/>
1.227 + </xsl:template>
1.228 +
1.229 +
1.230 +</xsl:stylesheet>