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