helpers/mimeXhtmlPart-make-paragraphs.xsl
author František Kučera <franta-hg@frantovo.cz>
Mon, 17 Oct 2011 00:55:48 +0200
changeset 85 a76b94bcec92
parent 83 668014315a54
child 86 92b2e3903ef1
permissions -rwxr-xr-x
Drupal: oprava XHTML šablony: žádné zdvojování značek.
franta-hg@81
     1
<?xml version="1.0" encoding="UTF-8"?>
franta-hg@81
     2
<xsl:stylesheet version="2.0"
franta-hg@81
     3
	xmlns="http://www.w3.org/1999/xhtml"
franta-hg@81
     4
	xmlns:h="http://www.w3.org/1999/xhtml"
franta-hg@81
     5
	xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
franta-hg@81
     6
	xmlns:fn="http://www.w3.org/2005/xpath-functions"
franta-hg@81
     7
	xmlns:svg="http://www.w3.org/2000/svg"
franta-hg@81
     8
	xmlns:xs="http://www.w3.org/2001/XMLSchema"
franta-hg@81
     9
	xmlns:o="https://trac.frantovo.cz/odstavcovac-TODO-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-/wiki/xmlns/odstavcovac"
franta-hg@83
    10
	exclude-result-prefixes="fn h xs o">
franta-hg@81
    11
	<xsl:output method="xml" indent="yes" encoding="UTF-8"/>
franta-hg@81
    12
	
franta-hg@83
    13
	<xsl:param name="cssTřída"/>
franta-hg@81
    14
	
franta-hg@81
    15
	<!-- Celý dokument -->
franta-hg@81
    16
	<xsl:template match="/">
franta-hg@81
    17
		<html>
franta-hg@81
    18
			<body>
franta-hg@81
    19
			
franta-hg@81
    20
				<xsl:variable name="prvníKolo">
franta-hg@81
    21
					<xsl:apply-templates select="h:html/h:body/node()" mode="prvníKolo"/>
franta-hg@81
    22
				</xsl:variable>
franta-hg@81
    23
				
franta-hg@81
    24
				<xsl:variable name="druhéKolo">
franta-hg@81
    25
					<xsl:apply-templates select="$prvníKolo" mode="druhéKolo"/>
franta-hg@81
    26
				</xsl:variable>
franta-hg@81
    27
				
franta-hg@81
    28
				<xsl:apply-templates select="$druhéKolo" mode="třetíKolo"/>
franta-hg@81
    29
				
franta-hg@81
    30
			</body>
franta-hg@81
    31
		</html>
franta-hg@81
    32
	</xsl:template>
franta-hg@83
    33
	
franta-hg@83
    34
	
franta-hg@83
    35
	<!-- Kopírujeme elementy, ale vynecháme nepoužité xmlns deklarace: -->
franta-hg@83
    36
	<xsl:template match="*" mode="kopíruj">
franta-hg@83
    37
		<xsl:element name="{name()}">
franta-hg@83
    38
			<xsl:copy-of select="@*"/>
franta-hg@83
    39
			<xsl:apply-templates/>
franta-hg@83
    40
		</xsl:element>
franta-hg@83
    41
    </xsl:template>
franta-hg@81
    42
    
franta-hg@81
    43
    
franta-hg@81
    44
    <!-- Mezi odstavci je prázdný řádek, můžou být mezery/tabulátory. -->
franta-hg@81
    45
	<xsl:variable name="oddělovač" select="'\n\s*\n\s*'"/>
franta-hg@81
    46
    
franta-hg@81
    47
	
franta-hg@81
    48
	<!-- Funkce: zda jde o XHTML inline element – může se vyskytovat uvnitř odstavců. -->
franta-hg@81
    49
	<xsl:template name="inlineElement" as="xs:boolean">
franta-hg@81
    50
		<xsl:param name="prvek"/>
franta-hg@81
    51
		<xsl:sequence select="
franta-hg@81
    52
			$prvek/name() = 'a' or						
franta-hg@81
    53
			$prvek/name() = 'abbr' or						
franta-hg@81
    54
			$prvek/name() = 'acronym' or						
franta-hg@81
    55
			$prvek/name() = 'b' or						
franta-hg@81
    56
			$prvek/name() = 'br' or						
franta-hg@81
    57
			$prvek/name() = 'cite' or						
franta-hg@81
    58
			$prvek/name() = 'code' or						
franta-hg@81
    59
			$prvek/name() = 'em' or						
franta-hg@81
    60
			$prvek/name() = 'i' or						
franta-hg@81
    61
			$prvek/name() = 'img' or						
franta-hg@81
    62
			$prvek/name() = 'q' or
franta-hg@81
    63
			$prvek/name() = 'span' or
franta-hg@81
    64
			$prvek/name() = 'strong' or
franta-hg@81
    65
			$prvek/name() = 'sub' or
franta-hg@81
    66
			$prvek/name() = 'sup' or
franta-hg@81
    67
			$prvek/name() = 'tt' or
franta-hg@81
    68
			$prvek/name() = 'u' or
franta-hg@81
    69
			$prvek/name() = 'var'
franta-hg@81
    70
			"/>
franta-hg@81
    71
		<!-- …případně další, pokud je budeme chtít podporovat. -->
franta-hg@81
    72
	</xsl:template>
franta-hg@81
    73
	
franta-hg@81
    74
	
franta-hg@81
    75
	<!-- Funkce: zda je prvek začátkem odstavce. -->
franta-hg@81
    76
	<xsl:template name="začátekOdstavce" as="xs:boolean">
franta-hg@81
    77
		<xsl:param name="prvek"/>
franta-hg@81
    78
		
franta-hg@81
    79
		<xsl:variable name="inlineElement" as="xs:boolean">
franta-hg@81
    80
			<xsl:call-template name="inlineElement"><xsl:with-param name="prvek" select="$prvek"/></xsl:call-template>
franta-hg@81
    81
		</xsl:variable>
franta-hg@81
    82
		
franta-hg@81
    83
		<xsl:variable name="předchůdce" select="$prvek/preceding-sibling::node()[1]"/>
franta-hg@81
    84
		
franta-hg@81
    85
		<xsl:variable name="inlineElementPředchůdce" as="xs:boolean">
franta-hg@81
    86
			<xsl:call-template name="inlineElement"><xsl:with-param name="prvek" select="$předchůdce"/></xsl:call-template>
franta-hg@81
    87
		</xsl:variable>
franta-hg@81
    88
		
franta-hg@81
    89
		<xsl:variable name="textovýUzel" select="boolean($prvek/self::text())"/>
franta-hg@81
    90
				
franta-hg@81
    91
		<xsl:sequence select="
franta-hg@81
    92
			($inlineElement or $textovýUzel) 
franta-hg@81
    93
			and 
franta-hg@81
    94
			(
franta-hg@81
    95
				($inlineElementPředchůdce and matches($prvek, concat('^', $oddělovač, '.*')))
franta-hg@81
    96
				or
franta-hg@81
    97
				not($inlineElementPředchůdce)
franta-hg@81
    98
				or
franta-hg@81
    99
				not($předchůdce)
franta-hg@81
   100
			)
franta-hg@81
   101
			and
franta-hg@81
   102
			(
franta-hg@81
   103
				not($předchůdce/self::text())
franta-hg@81
   104
				or
franta-hg@81
   105
				matches($předchůdce/self::text(), concat('.*', $oddělovač, '$'))
franta-hg@81
   106
			)
franta-hg@81
   107
			"/>
franta-hg@81
   108
	</xsl:template>
franta-hg@81
   109
	
franta-hg@81
   110
	
franta-hg@81
   111
	<!--
franta-hg@81
   112
		V prvním kole zavřeme volný text a inline elementy do značek <o:odstavec typ=""/>,
franta-hg@81
   113
		kde typ může být "začátek", což značí, že se jedná o první část budoucího odstavce <p/>.
franta-hg@81
   114
	-->
franta-hg@81
   115
	<xsl:template match="text()" mode="prvníKolo">
franta-hg@81
   116
	
franta-hg@81
   117
		<xsl:variable name="začátekOdstavce" as="xs:boolean">
franta-hg@81
   118
			<xsl:call-template name="začátekOdstavce">
franta-hg@81
   119
				<xsl:with-param name="prvek" select="."/>
franta-hg@81
   120
			</xsl:call-template>
franta-hg@81
   121
		</xsl:variable>
franta-hg@81
   122
		
franta-hg@81
   123
		<xsl:for-each select="fn:tokenize(., $oddělovač)">
franta-hg@81
   124
			<xsl:element name="o:odstavec">
franta-hg@81
   125
				<xsl:if test="$začátekOdstavce or not(position() = 1)">
franta-hg@81
   126
					<xsl:attribute name="typ">začátek</xsl:attribute>
franta-hg@81
   127
				</xsl:if>
franta-hg@81
   128
				<xsl:value-of select="."/>
franta-hg@81
   129
			</xsl:element>
franta-hg@81
   130
		</xsl:for-each>
franta-hg@81
   131
	
franta-hg@81
   132
	</xsl:template>
franta-hg@81
   133
	
franta-hg@81
   134
	<!-- 
franta-hg@81
   135
		Inline elementy zavíráme do <o:odstavec typ=""/>,
franta-hg@81
   136
		ostatní vkládáme, jak jsou.
franta-hg@81
   137
	-->
franta-hg@81
   138
	<xsl:template match="*" mode="prvníKolo">
franta-hg@81
   139
	
franta-hg@81
   140
		<xsl:variable name="inlineElement" as="xs:boolean">
franta-hg@81
   141
			<xsl:call-template name="inlineElement">
franta-hg@81
   142
				<xsl:with-param name="prvek" select="."/>
franta-hg@81
   143
			</xsl:call-template>
franta-hg@81
   144
		</xsl:variable>
franta-hg@81
   145
		
franta-hg@81
   146
		<xsl:choose>
franta-hg@81
   147
			<!-- TODO: zvláštní šablona (match="…") pro inline elementy místo větvení? -->
franta-hg@81
   148
			<xsl:when test="$inlineElement">
franta-hg@81
   149
				<xsl:variable name="začátekOdstavce" as="xs:boolean">
franta-hg@81
   150
					<xsl:call-template name="začátekOdstavce">
franta-hg@81
   151
						<xsl:with-param name="prvek" select="."/>
franta-hg@81
   152
					</xsl:call-template>
franta-hg@81
   153
				</xsl:variable>
franta-hg@81
   154
				<xsl:element name="o:odstavec">
franta-hg@81
   155
					<xsl:if test="$začátekOdstavce">
franta-hg@81
   156
						<xsl:attribute name="typ">začátek</xsl:attribute>
franta-hg@81
   157
					</xsl:if>
franta-hg@81
   158
					<xsl:copy-of select="."/>
franta-hg@81
   159
				</xsl:element>
franta-hg@81
   160
			</xsl:when>
franta-hg@83
   161
			<xsl:otherwise>				
franta-hg@81
   162
				<xsl:copy-of select="."/>
franta-hg@81
   163
			</xsl:otherwise>		
franta-hg@81
   164
		</xsl:choose>
franta-hg@81
   165
	
franta-hg@81
   166
	</xsl:template>
franta-hg@81
   167
	
franta-hg@81
   168
	<!-- V druhém kole spojíme jednotlivé části odstavců. -->
franta-hg@81
   169
	<xsl:template match="o:odstavec[@typ='začátek']" mode="druhéKolo">
franta-hg@81
   170
		<o:odstavec>
franta-hg@81
   171
			<xsl:call-template name="spojOdstavce">
franta-hg@81
   172
				<xsl:with-param name="část" select="."/>
franta-hg@81
   173
			</xsl:call-template>
franta-hg@81
   174
		</o:odstavec>
franta-hg@81
   175
	</xsl:template>
franta-hg@81
   176
	<!-- Následující části odstavce přeskočíme – postará se o ně vnitřní smyčka volaná z předchozí šablony. -->
franta-hg@81
   177
	<xsl:template match="o:odstavec" mode="druhéKolo"/>
franta-hg@81
   178
	<!-- Neinline (blokové) elementy vložíme, jak jsou. -->
franta-hg@81
   179
	<xsl:template match="*" mode="druhéKolo">
franta-hg@81
   180
		<xsl:copy-of select="."/>
franta-hg@81
   181
	</xsl:template>
franta-hg@81
   182
	
franta-hg@81
   183
	
franta-hg@81
   184
	<!--
franta-hg@81
   185
		Za první část (parametr, <o:odstavec typ="začátek"/>) resp. její vnitřek
franta-hg@81
   186
		připojíme (rekurze) všechny další části téhož odstavce (oddělíme mezerou).
franta-hg@81
   187
		Konec odstavce poznáme tak, že následovník je něco jiného než <o:odstavec/> nebo má atribut typ="začátek".
franta-hg@81
   188
	-->
franta-hg@81
   189
	<xsl:template name="spojOdstavce">
franta-hg@81
   190
		<xsl:param name="část"/>
franta-hg@81
   191
		<xsl:copy-of select="$část/child::node()"/>
franta-hg@81
   192
		<xsl:variable name="následovník" select="$část/following-sibling::node()[1]"/>
franta-hg@81
   193
		<xsl:if test="$následovník/name() = 'o:odstavec' and not($následovník/@typ = 'začátek')">
franta-hg@81
   194
			<xsl:text> </xsl:text>
franta-hg@81
   195
			<xsl:call-template name="spojOdstavce">
franta-hg@81
   196
				<xsl:with-param name="část" select="$následovník"/>
franta-hg@81
   197
			</xsl:call-template>
franta-hg@81
   198
		</xsl:if>
franta-hg@81
   199
	</xsl:template>
franta-hg@81
   200
	
franta-hg@81
   201
	
franta-hg@81
   202
	<!-- Ve třetím kole smažeme prázdné mešuge odstavce. -->
franta-hg@81
   203
	<xsl:template mode="třetíKolo" match="o:odstavec[
franta-hg@81
   204
		count(child::node()) = 0 
franta-hg@81
   205
		or 
franta-hg@81
   206
		(
franta-hg@81
   207
			count(child::node()) = 1 
franta-hg@81
   208
			and
franta-hg@81
   209
			text()
franta-hg@81
   210
			and
franta-hg@81
   211
			matches(text(), '^\s*$')
franta-hg@81
   212
		)
franta-hg@81
   213
		]">
franta-hg@81
   214
		<xsl:text> </xsl:text>	
franta-hg@81
   215
	</xsl:template>
franta-hg@81
   216
	<!-- Převedeme z <o:odstavec/> na <p/> -->
franta-hg@81
   217
	<xsl:template match="o:odstavec" mode="třetíKolo">
franta-hg@83
   218
		<xsl:element name="p">
franta-hg@83
   219
			<xsl:if test="$cssTřída">
franta-hg@83
   220
				<xsl:attribute name="class"><xsl:value-of select="$cssTřída"/></xsl:attribute>
franta-hg@83
   221
			</xsl:if>
franta-hg@83
   222
			<xsl:apply-templates select="child::node()" mode="kopíruj"/>
franta-hg@83
   223
		</xsl:element>
franta-hg@81
   224
	</xsl:template>
franta-hg@81
   225
	<!-- Všechno ostatní zkopírujeme, jak je. -->
franta-hg@81
   226
	<xsl:template match="*" mode="třetíKolo">
franta-hg@81
   227
		<xsl:copy-of select="."/>
franta-hg@81
   228
	</xsl:template>
franta-hg@81
   229
	
franta-hg@81
   230
	
franta-hg@81
   231
</xsl:stylesheet>