Drupal: lámání textu na odstavce – XSLT 2.0, TODO:…
authorFrantišek Kučera <franta-hg@frantovo.cz>
Fri, 14 Oct 2011 12:41:14 +0200
changeset 77623025c704c5
parent 76 b5690fc25af6
child 78 969f001a0f5f
Drupal: lámání textu na odstavce – XSLT 2.0, TODO:…
helpers/mimeXhtmlPart.xsl
     1.1 --- a/helpers/mimeXhtmlPart.xsl	Fri Oct 14 00:45:06 2011 +0200
     1.2 +++ b/helpers/mimeXhtmlPart.xsl	Fri Oct 14 12:41:14 2011 +0200
     1.3 @@ -1,5 +1,5 @@
     1.4  <?xml version="1.0" encoding="UTF-8"?>
     1.5 -<xsl:stylesheet version="1.0"
     1.6 +<xsl:stylesheet version="2.0"
     1.7  	xmlns="http://www.w3.org/1999/xhtml"
     1.8  	xmlns:h="http://www.w3.org/1999/xhtml"
     1.9  	xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    1.10 @@ -27,6 +27,7 @@
    1.11  		<html>
    1.12  			<head>
    1.13  				<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=utf-8" />
    1.14 +				<meta http-equiv="X-NNTP-Generated" content="{fn:current-dateTime()}" />
    1.15  				<xsl:if test="$urlBase">
    1.16  					<base href="{$urlBase}"/>
    1.17  				</xsl:if>
    1.18 @@ -67,6 +68,11 @@
    1.19  					a img {
    1.20  						border: none;
    1.21  					}
    1.22 +					
    1.23 +					/** TODO: smazat */
    1.24 +					.mešuge {
    1.25 +						background-color: #afa;
    1.26 +					}
    1.27  				</style>
    1.28  			</head>
    1.29  			<body>
    1.30 @@ -143,57 +149,57 @@
    1.31      
    1.32      <!-- 
    1.33      	Z neuzavřeného (nevalidně se vyskytujícího v body) textu uděláme odstavce.
    1.34 -    	Bohužel nefunguje, když neuzavřený text obsahuje jiné značky (odkazy atd.),
    1.35 -    	pak se totiž jedná o dva textové uzly (před značkou a za ní) a vzniknou dva odstavce.
    1.36      -->
    1.37  	<xsl:template match="h:body/text()">
    1.38 -		<xsl:call-template name="makeParagraphs">
    1.39 -			<xsl:with-param name="string" select="."/>
    1.40 -		</xsl:call-template>
    1.41 +		<xsl:call-template name="dělejOdstavce">
    1.42 +			<xsl:with-param name="blokTextu" select="."/>
    1.43 +		</xsl:call-template>		
    1.44  	</xsl:template>
    1.45 -    <xsl:variable name="newLinePlaceholder" select="'ߜ'"/>
    1.46 -    <xsl:template name="makeParagraphs">
    1.47 -    	<xsl:param name="string" />
    1.48 -    	<xsl:call-template name="makeParagraphsInternal">
    1.49 -    		<!--
    1.50 -    			Konec řádku převedeme na obskurní znak, 
    1.51 -    			normalizací pročistíme bílé znaky → 
    1.52 -    			dva obskurní znaky oddělené mezerou pak značí předěl mezi odstavci
    1.53 -    		-->
    1.54 -    		<xsl:with-param name="string" select="normalize-space(translate(., '&#10;', $newLinePlaceholder))"/>
    1.55 -    	</xsl:call-template>
    1.56 -    </xsl:template>
    1.57 -	<xsl:template name="makeParagraphsInternal">
    1.58 -		<xsl:param name="string" />
    1.59 -		<xsl:if test="ends-with($string, $newLinePlaceholder)"><xsl:comment>končí na $newLinePlaceholder</xsl:comment> </xsl:if>
    1.60 -		<!-- V XSLT 2.0 můžeme použít fn:tokenize -->
    1.61 -		<xsl:param name="delimiter" select="concat($newLinePlaceholder, ' ', $newLinePlaceholder)"/>
    1.62 -		<xsl:choose>
    1.63 -			<xsl:when test="$delimiter and contains($string, $delimiter)">
    1.64 -				<xsl:call-template name="makeParagraph">
    1.65 -					<xsl:with-param name="string" select="substring-before($string, $delimiter)"></xsl:with-param>
    1.66 -				</xsl:call-template>
    1.67 -				<xsl:call-template name="makeParagraphsInternal">
    1.68 -					<xsl:with-param name="string" select="substring-after($string, $delimiter)" />
    1.69 -					<xsl:with-param name="delimiter" select="$delimiter" />
    1.70 -				</xsl:call-template>
    1.71 -			</xsl:when>
    1.72 -			<xsl:otherwise>
    1.73 -				<!--
    1.74 -					Poslední odstavec → zkontrolovat, zda je za ním  
    1.75 -				-->
    1.76 -				<xsl:call-template name="makeParagraph">
    1.77 -					<xsl:with-param name="string" select="$string"></xsl:with-param>
    1.78 -				</xsl:call-template>
    1.79 -			</xsl:otherwise>
    1.80 -		</xsl:choose>
    1.81 +	<xsl:template name="dělejOdstavce">
    1.82 +		<xsl:param name="blokTextu"/>
    1.83 +		<xsl:variable name="oddělovač" select="'\n\s+\n\s+'"/>
    1.84 +		<xsl:for-each select="fn:tokenize(., $oddělovač)">
    1.85 +			<xsl:if test="normalize-space(.)">
    1.86 +				<p class="mešuge">
    1.87 +					<xsl:value-of select="."/>
    1.88 +					<!-- 
    1.89 +						Toto je poslední odstavec bloku textu 
    1.90 +						a blok nekončí dvěma konci řádku → 
    1.91 +						může za ním následovat značka (např. odkaz nebo tučné písmo)
    1.92 +						vnořená do téhož odstavce
    1.93 +					-->
    1.94 +					<xsl:if test="
    1.95 +						position() = last() and
    1.96 +						not(fn:matches($blokTextu, concat('.*', $oddělovač ,'$')))
    1.97 +						">
    1.98 +						
    1.99 +						<xsl:variable name="n" select="$blokTextu/following-sibling::*[position() = 1]"/>
   1.100 +						<xsl:variable name="nn" select="$n/name()"/>
   1.101 +						<!--
   1.102 +							Za blokem textu nenásleduje značka, která nemůže být uvnitř odstavce.
   1.103 +						-->
   1.104 +						<xsl:if test="not(
   1.105 +								$nn = 'p' or
   1.106 +								$nn = 'div' or								
   1.107 +								$nn = 'h1' or								
   1.108 +								$nn = 'h2' or								
   1.109 +								$nn = 'h3' or								
   1.110 +								$nn = 'h4' or								
   1.111 +								$nn = 'h5' or								
   1.112 +								$nn = 'h6' or								
   1.113 +								$nn = 'pre' or								
   1.114 +								$nn = 'table' or								
   1.115 +								$nn = 'blockquote' or								
   1.116 +								$nn = 'hr'								
   1.117 +							)">
   1.118 +							<xsl:apply-templates select="$n"/>
   1.119 +							<xsl:apply-templates select="$n/following-sibling::text()[position() = 1]"/>
   1.120 +						</xsl:if>						
   1.121 +					</xsl:if>
   1.122 +				</p>
   1.123 +			</xsl:if>
   1.124 +		</xsl:for-each>
   1.125  	</xsl:template>
   1.126 -	<xsl:template name="makeParagraph">
   1.127 -		<xsl:param name="string" />
   1.128 -			<!-- prázdné textové uzly nás nezajímají – nechceme prázdné odstavce -->
   1.129 -			<xsl:if test="normalize-space($string)">
   1.130 -				<p class="mešuge"><xsl:value-of select="translate($string, $newLinePlaceholder, '&#10;')" /></p>				
   1.131 -			</xsl:if>
   1.132 -	</xsl:template>
   1.133 -
   1.134 +    
   1.135 +	
   1.136  </xsl:stylesheet>