helpers/mimeXhtmlPart.xsl
author František Kučera <franta-hg@frantovo.cz>
Fri, 14 Oct 2011 15:36:54 +0200
changeset 79 245311d10726
parent 78 969f001a0f5f
child 80 1f9e5757caf4
permissions -rwxr-xr-x
Drupal: XSLT odstavce – vnořující se.
     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <xsl:stylesheet version="2.0"
     3 	xmlns="http://www.w3.org/1999/xhtml"
     4 	xmlns:h="http://www.w3.org/1999/xhtml"
     5 	xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     6 	xmlns:fn="http://www.w3.org/2005/xpath-functions"
     7 	xmlns:svg="http://www.w3.org/2000/svg"
     8 	xmlns:xs="http://www.w3.org/2001/XMLSchema"
     9 	exclude-result-prefixes="fn h xs">
    10 	<xsl:output 
    11 		method="xml" 
    12 		indent="yes" 
    13 		encoding="UTF-8"		
    14 		doctype-public="-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN" 
    15 		doctype-system="http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd"/>
    16 	
    17 		
    18 	<xsl:param name="title"/>
    19 	<xsl:param name="isRoot"/>
    20 	<xsl:param name="urlBase"/>
    21 	<xsl:param name="wwwRead"/>
    22 	<xsl:param name="wwwPost"/>
    23 	
    24 	
    25 	<!-- Celý dokument -->
    26 	<xsl:template match="/">
    27 		<html>
    28 			<head>
    29 				<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=utf-8" />
    30 				<meta http-equiv="X-NNTP-Generated" content="{fn:current-dateTime()}" />
    31 				<xsl:if test="$urlBase">
    32 					<base href="{$urlBase}"/>
    33 				</xsl:if>
    34 				<xsl:if test="$title">
    35 					<title><xsl:value-of select="$title"/></title>
    36 				</xsl:if>
    37 				<style type="text/css">
    38 					body {
    39 						font-family: sans-serif;
    40 						font-size: 16px;
    41 					}
    42 					
    43 					.wwwLinks {
    44 						border-top: 2px solid grey;
    45 						margin-top: 16px;
    46 						font-size: 66%;
    47 					}
    48 					
    49 					blockquote {
    50 						background-color: #eee;
    51 						font-style: italic;
    52 						padding: 2px 20px;
    53 						margin: 10px 32px;
    54 						border-left: 3px solid silver;
    55 					}
    56 					
    57 					pre {
    58 						background-color: #eee;
    59 						padding: 2px 20px;
    60 						margin: 10px 32px;
    61 						border-left: 3px solid #a00;
    62 					}
    63 					
    64 					img {
    65 						margin: 8px;
    66 					}
    67 					
    68 					a img {
    69 						border: none;
    70 					}
    71 					
    72 					/** TODO: smazat */
    73 					.mešuge {
    74 						background-color: #afa;
    75 					}
    76 				</style>
    77 			</head>
    78 			<body>
    79 				<xsl:if test="$title and $isRoot">
    80 					<h1><xsl:value-of select="$title"/></h1>			
    81 				</xsl:if>
    82 				<xsl:call-template name="zpracujTělo">
    83 					<xsl:with-param name="prvek" select="h:html/h:body/node()[1]"/>
    84 				</xsl:call-template>
    85 				
    86 				<xsl:if test="$wwwRead or $wwwPost">
    87 					<div class="wwwLinks">
    88 						<p>Přístup přes síť www:</p>
    89 						<ul>
    90 							<xsl:if test="$wwwRead"><li><a href="{$wwwRead}">číst tento příspěvek</a></li></xsl:if>
    91 							<xsl:if test="$wwwPost"><li><a href="{$wwwPost}">odpovědět na tento příspěvek</a></li></xsl:if>
    92 						</ul>
    93 					</div>
    94 				</xsl:if>
    95 			</body>
    96 		</html>
    97 	</xsl:template>
    98 	
    99 	
   100 	<!-- Odkazy -->
   101 	<xsl:template match="h:a">
   102 		<a href="{@href}" title="{@title}"><xsl:apply-templates/></a>
   103 	</xsl:template>
   104 	
   105 	
   106 	<!-- Obrázky -->
   107 	<xsl:template match="h:img">
   108 		<img src="{@src}" alt="{@alt}" title="{@title}"><xsl:apply-templates/></img>
   109 	</xsl:template>
   110 	
   111 	<!-- Zkratky -->
   112 	<xsl:template match="h:abbr">
   113 		<abbr title="{@title}"><xsl:apply-templates/></abbr>
   114 	</xsl:template>
   115 	
   116 	
   117 	<!-- Další povolené značky – ostatní odfiltrujeme (zbude z nich jen text) -->
   118 	<xsl:template match="*">
   119 		<xsl:choose>		
   120 			<xsl:when test="
   121 				name() = 'h1' or
   122 				name() = 'h2' or
   123 				name() = 'h3' or
   124 				name() = 'h4' or
   125 				name() = 'h5' or
   126 				name() = 'h6' or
   127 				name() = 'p' or
   128 				name() = 'div' or
   129 				name() = 'br' or
   130 				name() = 'strong' or
   131 				name() = 'em' or
   132 				name() = 'sub' or
   133 				name() = 'sup' or
   134 				name() = 'del' or
   135 				name() = 'ul' or
   136 				name() = 'ol' or
   137 				name() = 'li' or
   138 				name() = 'pre' or
   139 				name() = 'code' or
   140 				name() = 'blockquote'">
   141 				<xsl:element name="{name()}">
   142 					<xsl:apply-templates/>
   143 				</xsl:element>
   144 			</xsl:when>
   145 			<xsl:otherwise>
   146 				<xsl:value-of select="."/>
   147 			</xsl:otherwise>
   148 		</xsl:choose>		
   149     </xsl:template>
   150     
   151     
   152     <!-- 
   153     	Z neuzavřeného (nevalidně se vyskytujícího v body) textu uděláme odstavce.
   154     -->
   155 	<xsl:template name="zpracujTělo">
   156 		<xsl:param name="prvek"/>
   157 		<xsl:if test="$prvek">
   158 			<xsl:choose>
   159 				<xsl:when test="$prvek/self::text()">
   160 					<!--
   161 						Textový uzel → budeme dělat odstavce
   162 						(rekurzivně se opět zavolá šablona zpracujTělo)
   163 					-->
   164 					<xsl:call-template name="dělejOdstavceX">
   165 						<xsl:with-param name="blokTextu" select="$prvek"/>
   166 					</xsl:call-template>
   167 				</xsl:when>
   168 				<xsl:otherwise>
   169 					<!--
   170 						Jiný uzel → aplikujeme obecné šablony
   171 						a zpracujeme následující uzel.
   172 					-->
   173 					<xsl:apply-templates select="$prvek"/>
   174 					<xsl:call-template name="zpracujTělo">
   175 						<xsl:with-param name="prvek" select="$prvek/following-sibling::node()[1]"/>
   176 					</xsl:call-template>
   177 				</xsl:otherwise>					
   178 			</xsl:choose>				
   179 		</xsl:if>
   180 	</xsl:template>
   181 	
   182 	<xsl:template name="dělejOdstavceX">
   183 		<xsl:param name="blokTextu"/>
   184 		<xsl:variable name="oddělovač" select="'\n\s+\n\s+'"/>
   185 		<xsl:variable name="dalšíUzel" select="$blokTextu/following-sibling::node()[1]"/>
   186 		
   187 		<xsl:variable name="navázat" select="
   188 				not(fn:matches($blokTextu, concat('.*', $oddělovač ,'$'))) and
   189 				$dalšíUzel and
   190 				not(
   191 					$dalšíUzel/name() = 'p' or
   192 					$dalšíUzel/name() = 'div' or								
   193 					$dalšíUzel/name() = 'h1' or								
   194 					$dalšíUzel/name() = 'h2' or								
   195 					$dalšíUzel/name() = 'h3' or								
   196 					$dalšíUzel/name() = 'h4' or								
   197 					$dalšíUzel/name() = 'h5' or								
   198 					$dalšíUzel/name() = 'h6' or								
   199 					$dalšíUzel/name() = 'pre' or								
   200 					$dalšíUzel/name() = 'table' or								
   201 					$dalšíUzel/name() = 'blockquote' or								
   202 					$dalšíUzel/name() = 'hr'								
   203 				)
   204 				"/>
   205 		
   206 		<xsl:for-each select="fn:tokenize($blokTextu, $oddělovač)">
   207 			<xsl:if test="normalize-space(.)">
   208 				<p class="mešuge">
   209 					<xsl:value-of select="."/>
   210 					<xsl:if test="$navázat and position() = last()">
   211 						<xsl:apply-templates select="$dalšíUzel"/>
   212 					</xsl:if>
   213 					<xsl:call-template name="zpracujTělo">
   214 						<xsl:with-param name="prvek" select="$dalšíUzel/following-sibling::node()[1]"/>
   215 					</xsl:call-template>
   216 				</p>
   217 			</xsl:if>
   218 		</xsl:for-each>
   219 		
   220 		<xsl:if test="not($navázat)">
   221 			<xsl:call-template name="zpracujTělo">
   222 				<xsl:with-param name="prvek" select="$dalšíUzel"/>
   223 			</xsl:call-template>
   224 		</xsl:if>
   225 	</xsl:template>
   226 	
   227 	
   228 	
   229 	
   230 	
   231 	
   232 	<xsl:template name="dělejOdstavce">
   233 		<xsl:param name="blokTextu"/>
   234 		<xsl:variable name="oddělovač" select="'\n\s+\n\s+'"/>
   235 		<xsl:for-each select="fn:tokenize(., $oddělovač)">
   236 			<xsl:if test="normalize-space(.)">
   237 				<p class="mešuge">
   238 					<xsl:value-of select="."/>
   239 					<!-- 
   240 						Toto je poslední odstavec bloku textu 
   241 						a blok nekončí dvěma konci řádku → 
   242 						může za ním následovat značka (např. odkaz nebo tučné písmo)
   243 						vnořená do téhož odstavce
   244 					-->
   245 					<xsl:if test="
   246 						position() = last() and
   247 						not(fn:matches($blokTextu, concat('.*', $oddělovač ,'$')))
   248 						">
   249 						<xsl:variable name="n" select="$blokTextu/following-sibling::*[1]"/>
   250 						<xsl:variable name="nn" select="$n/name()"/>
   251 						<!--
   252 							Za blokem textu nenásleduje značka, která nemůže být uvnitř odstavce.
   253 						-->
   254 						<xsl:if test="not(
   255 								$nn = 'p' or
   256 								$nn = 'div' or								
   257 								$nn = 'h1' or								
   258 								$nn = 'h2' or								
   259 								$nn = 'h3' or								
   260 								$nn = 'h4' or								
   261 								$nn = 'h5' or								
   262 								$nn = 'h6' or								
   263 								$nn = 'pre' or								
   264 								$nn = 'table' or								
   265 								$nn = 'blockquote' or								
   266 								$nn = 'hr'								
   267 							)">
   268 							<xsl:apply-templates select="$n"/>
   269 						</xsl:if>
   270 						
   271 						<xsl:call-template name="zpracujTělo">
   272 							<xsl:with-param name="prvek" select="$blokTextu/following-sibling::node()[1]"/>
   273 						</xsl:call-template>
   274 				
   275 					</xsl:if>
   276 				</p>				
   277 			</xsl:if>
   278 		</xsl:for-each>
   279 	</xsl:template>
   280     
   281 	
   282 </xsl:stylesheet>