Adjust the toc structure a bit.
[thenextsample.git] / pottery2docbook.xsl
blob8d7cc923eaf1699c03cc71ab294642ea54832b2e
1 <?xml version='1.0' encoding="UTF-8"?>
2 <!DOCTYPE book SYSTEM "-//OASIS//DTD DocBook V5.0//EN">
3 <xsl:stylesheet version="1.0"
4 xml:lang="en"
5 xmlns="http://docbook.org/ns/docbook"
6 xmlns:db="http://docbook.org/ns/docbook"
7 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
8 xmlns:xlink="http://www.w3.org/1999/xlink"
9 xmlns:ex="http://exslt.org/dates-and-times"
10 xmlns:em="http://exslt.org/math"
11 xmlns:es="http://exslt.org/sets"
12 xmlns:ec="http://exslt.org/common"
13 xmlns:p="tag:fenglich.fastmail.fm,2007:Pottery">
16 <!-- Do some business logic validation. -->
17 <xsl:template match="/">
18 <!-- glazing referencing brushons. -->
19 <xsl:variable name="invalidGlazeRef">
20 <xsl:for-each select="//p:glazing">
21 <xsl:variable name="name" select="@idref"/>
22 <xsl:value-of select="//p:glaze[@xml:id = $name and @type = 'BrushOn']/@xml:id"/>
23 </xsl:for-each>
24 </xsl:variable>
26 <xsl:if test="string-length(normalize-space($invalidGlazeRef)) > 0">
27 <xsl:message terminate="yes"><xsl:value-of select="$invalidGlazeRef"/> is referenced as a non-brushon, while it in fact is.</xsl:message>
28 </xsl:if>
30 <!-- brushons referencing non-brushons. -->
31 <xsl:variable name="invalidBrushOnGlazeRef">
32 <xsl:for-each select="//p:brushon">
33 <xsl:variable name="name" select="@idref"/>
34 <xsl:value-of select="//p:glaze[@xml:id = $name and @type != 'BrushOn']/@xml:id"/>
35 </xsl:for-each>
36 </xsl:variable>
38 <xsl:if test="string-length(normalize-space($invalidBrushOnGlazeRef)) > 0">
39 <xsl:message terminate="yes"><xsl:value-of select="$invalidBrushOnGlazeRef"/> are referenced as a brushon, while it isn't.</xsl:message>
40 </xsl:if>
42 <xsl:apply-templates/>
43 </xsl:template>
45 <xsl:template match="p:pottery">
46 <book xml:lang="en">
47 <info>
48 <title>The Next Sample</title>
49 <author>
50 <personname>
51 <firstname>Frans</firstname>
52 <surname>Englich</surname>
53 </personname>
54 <email>fenglich@fastmail.fm</email>
55 <address>
56 <phone>+46-702-411091</phone>
57 </address>
58 </author>
59 <pubdate><xsl:value-of select="ex:date()"/></pubdate>
60 <legalnotice>
61 <para>Copyright (c) 2007-2008 Frans Englich</para>
62 <para>Permission is granted to copy, distribute and/or modify this document
63 under the terms of the GNU Free Documentation License, Version 1.2
64 or any later version published by the Free Software Foundation;
65 with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
66 Texts. A copy of the license can be obtained at the <phrase xlink:href="http://www.gnu.org/licenses/fdl.html">Free Software Foundation's website</phrase> or by contacting the author.</para>
67 </legalnotice>
68 </info>
70 <xsl:apply-templates select="p:pieces"/>
71 <xsl:apply-templates select="p:glazes"/>
72 <xsl:apply-templates select="p:clays"/>
74 <chapter>
75 <title>Non-glaze Samples</title>
76 <para>This section contains samples which aren't of glazes,
77 such as melt tests. See also the samples that have at least
78 <phrase xlink:href="#Transparent">transparent
79 glaze</phrase> as glazing, which contains similar kind
80 samples.</para>
82 <xsl:apply-templates select="p:samples/p:sample[not(p:glazing | p:brushon)]"/>
83 </chapter>
86 <chapter>
87 <title>Oven Programs</title>
89 <para>Unless otherwise stated, all firings were done with the following settings.</para>
90 <informaltable>
91 <tgroup cols="8">
92 <thead>
93 <row>
94 <entry>Program Code</entry>
95 <entry>Type</entry>
96 <entry>C/h 1</entry>
97 <entry>Temp 1</entry>
98 <entry>Time 1</entry>
99 <entry>C/h 2</entry>
100 <entry>Temp 2</entry>
101 <entry>Time 2</entry>
102 <entry>C/h 3</entry>
103 </row>
104 </thead>
105 <tbody>
106 <row>
107 <entry>P1</entry>
108 <entry>Bisque</entry>
109 <entry>80</entry>
110 <entry>80</entry>
111 <entry>300</entry>
112 <entry>150</entry>
113 <entry>960</entry>
114 <entry>30</entry>
115 <entry>700</entry>
116 </row>
117 <row>
118 <entry>P2</entry>
119 <entry>Decal &amp; Luster</entry>
120 <entry>150</entry>
121 <entry>650</entry>
122 <entry>0</entry>
123 <entry>200</entry>
124 <entry>780</entry>
125 <entry>0</entry>
126 <entry>700</entry>
127 </row>
128 <row>
129 <entry>P3</entry>
130 <entry>Unused Bisque Program</entry>
131 <entry>80</entry>
132 <entry>80</entry>
133 <entry>540</entry>
134 <entry>150</entry>
135 <entry>960</entry>
136 <entry>0</entry>
137 <entry>500</entry>
138 </row>
139 <row>
140 <entry>P4</entry>
141 <entry>Glaze</entry>
142 <entry>150</entry>
143 <entry>600</entry>
144 <entry>0</entry>
145 <entry>200</entry>
146 <entry>1240</entry>
147 <entry>10</entry>
148 <entry>500</entry>
149 </row>
150 </tbody>
151 </tgroup>
152 </informaltable>
154 </chapter>
156 <xsl:call-template name="sourcesAppendix"/>
157 </book>
158 </xsl:template>
160 <xsl:template match="p:pieces">
161 <chapter>
162 <title>Pieces</title>
164 <para>A total of <xsl:value-of select="count(p:piece)"/> pieces.</para>
166 <para>The IDs assigned to pieces are arbitrary and not sequential. They don't reflect cronologically
167 the creation. However, they are sorted numerically in this document for quick lookup.</para>
169 <xsl:apply-templates select="p:piece">
170 <xsl:sort data-type="number" select="number(substring(@xml:id, 2))"/>
171 </xsl:apply-templates>
172 </chapter>
173 </xsl:template>
175 <xsl:template match="p:piece">
176 <section>
177 <xsl:attribute name="xml:id"><xsl:value-of select="@xml:id"/></xsl:attribute>
178 <title>
179 <xsl:value-of select="substring(@xml:id, 2)"/>
180 </title>
181 <xsl:apply-templates/>
182 </section>
183 </xsl:template>
185 <xsl:template match="p:clayref">
186 <para>
187 <emphasis>Clay</emphasis>: <phrase xlink:href="#{@idref}">
188 <xsl:value-of select="/p:pottery/p:clays/p:clay[@xml:id = current()/@idref]/@name"/></phrase>
189 <xsl:apply-templates select="@weightWhenWet"/>
190 </para>
192 </xsl:template>
194 <xsl:template match="@weightWhenWet">
195 <xsl:text>, weight </xsl:text>
196 <emphasis>when wet</emphasis>:
197 <constant><xsl:value-of select="."/></constant> g
198 </xsl:template>
200 <xsl:template match="p:note">
201 <formalpara>
202 <title><xsl:value-of select="@date"/></title>
203 <para><xsl:value-of select="."/></para>
204 </formalpara>
205 </xsl:template>
207 <xsl:template match="p:glazes">
208 <chapter>
209 <title>Glazes</title>
211 <para>A total of <xsl:value-of select="count(//p:sample)"/> sample bricks.</para>
213 <xsl:apply-templates select="p:glaze">
214 <xsl:sort select="@name"/>
215 </xsl:apply-templates>
216 </chapter>
217 </xsl:template>
219 <xsl:template match="p:glaze">
220 <section>
221 <xsl:attribute name="xml:id"><xsl:value-of select="@xml:id"/></xsl:attribute>
222 <title>
223 <xsl:value-of select="@name"/>
224 <xsl:if test="@productID">,
225 <xsl:value-of select="@productID"/>
226 </xsl:if>
227 <xsl:if test="@type = 'BrushOn'"> (brush-on)</xsl:if>
228 </title>
230 <xsl:apply-templates select="db:para"/>
232 <xsl:apply-templates select="p:recipe"/>
234 <xsl:variable name="piecesUsing" select="//p:pieces/p:piece[p:glazing/@idref = current()/@xml:id]"/>
235 <xsl:if test="$piecesUsing">
236 <db:para>Used on:
237 <xsl:for-each select="$piecesUsing">
238 <db:xref xlink:href="#{@xml:id}"/>
239 <xsl:if test="position() = last() - 1">
240 <xsl:text> and </xsl:text>
241 </xsl:if>
242 <xsl:if test="position() &lt; last() - 1">
243 <xsl:text>, </xsl:text>
244 </xsl:if>
245 <xsl:if test="position() = last()">
246 <xsl:text>.</xsl:text>
247 </xsl:if>
248 </xsl:for-each>
249 </db:para>
250 </xsl:if>
252 <xsl:apply-templates select="//p:samples/p:sample[(p:brushon | p:glazing)[@idref = current()/@xml:id]]">
253 <!-- TODO This just doesn't seem to work. -->
254 <xsl:sort data-type="number" select="number(substring(@xml:id, 2))"/>
255 <!--<xsl:sort data-type="number" select="number(p:glazing/@hydrometerGravity)"/>-->
256 <xsl:with-param name="mainGlaze" select="@xml:id"/>
257 </xsl:apply-templates>
259 </section>
260 </xsl:template>
262 <xsl:template name="imageForSample">
263 <xsl:param name="sampleName"/>
264 <xsl:param name="imageName"/>
265 <mediaobject>
266 <imageobject>
267 <imagedata align="right" format="JPG" fileref="../Images/Samples/{$sampleName}/{$imageName}.jpg"/>
268 </imageobject>
269 </mediaobject>
270 </xsl:template>
272 <xsl:template match="p:piece/p:image">
273 <mediaobject>
274 <imageobject>
275 <imagedata align="right" format="JPG" fileref="../Images/Pieces/{../@xml:id}/{.}.jpg"/>
276 </imageobject>
277 </mediaobject>
278 </xsl:template>
280 <xsl:template match="p:sample">
281 <xsl:param name="mainGlaze"/>
282 <section>
283 <title><xsl:apply-templates select="p:brick"/></title>
285 <para><date><xsl:value-of select="@date"/></date></para>
286 <para>
287 <xsl:apply-templates select="(p:glazing | p:brushon)[@idref = $mainGlaze]" mode="lowKeyGlazing"/>
288 </para>
289 <xsl:variable name="additionalGlazes" select="(p:brushon | p:glazing)[@idref != $mainGlaze]"/>
290 <xsl:if test="(p:brushon | p:glazing)[@idref != $mainGlaze]">
291 <para>Additional glaze<xsl:if test="count($additionalGlazes) > 1">s</xsl:if>:</para>
292 <xsl:apply-templates select="(p:brushon | p:glazing)[@idref != $mainGlaze]"/>
293 </xsl:if>
294 <xsl:apply-templates select="p:clayref"/>
295 <xsl:apply-templates select="db:para"/>
296 <xsl:apply-templates mode="doImage" select="p:brick"/>
297 </section>
298 </xsl:template>
300 <xsl:template mode="doImage" match="p:brick">
301 <xsl:call-template name="imageForSample">
302 <xsl:with-param name="sampleName" select="@xml:id"/>
303 <xsl:with-param name="imageName" select="@xml:id"/>
304 </xsl:call-template>
305 </xsl:template>
307 <xsl:template match="p:sample/p:para">
308 <formalpara>
309 <title><xsl:value-of select="../@date"/></title>
310 <xsl:copy>
311 <xsl:apply-templates select="."/>
312 </xsl:copy>
313 </formalpara>
314 </xsl:template>
316 <xsl:template match="p:glazing">
317 <para><phrase xlink:href="#{@idref}"><xsl:value-of select="/p:pottery/p:glazes/p:glaze[@xml:id = current()/@idref]/@name"/></phrase>,
318 <xsl:apply-templates select="." mode="lowKeyGlazing"/>
319 </para>
320 </xsl:template>
322 <xsl:template match="p:brushon">
323 <para><phrase xlink:href="#{@idref}"><xsl:value-of select="/p:pottery/p:glazes/p:glaze[@xml:id = current()/@idref]/@name"/></phrase></para>
324 </xsl:template>
326 <xsl:template match="p:glazing" mode="lowKeyGlazing">
327 <xsl:apply-templates select="@hydrometerGravity"/>
328 <xsl:apply-templates select="@sieved"/>
329 </xsl:template>
331 <xsl:template match="@hydrometerGravity">
332 <emphasis>hydrometer gravity</emphasis>
333 <xsl:text> </xsl:text>
334 <constant><xsl:value-of select="."/></constant>
335 </xsl:template>
337 <xsl:template match="@sieved">,
338 <emphasis>
339 <xsl:choose>
340 <xsl:when test=". = 'WithMixer'">
341 with mixer
342 </xsl:when>
343 <xsl:when test=". = 'no'">
344 not sieved
345 </xsl:when>
346 <xsl:otherwise>
347 sieved with mesh size <constant><xsl:value-of select="."/></constant>
348 </xsl:otherwise>
349 </xsl:choose>
350 </emphasis>
351 </xsl:template>
353 <xsl:template match="p:brick">
354 <xsl:value-of select="@xml:id"/>
355 <xsl:text> </xsl:text>
356 </xsl:template>
358 <xsl:template name="sourcesAppendix">
359 <appendix>
360 <title>Sources</title>
361 <para>This document was generated from the following sources. The string following the file date is the git SHA1 checksum.</para>
362 <itemizedlist>
363 <xsl:apply-templates select="document('sources.xml')/p:sources/p:source"/>
364 </itemizedlist>
365 </appendix>
366 </xsl:template>
368 <xsl:template match="p:source">
369 <listitem>
370 <para>
371 <filename><xsl:value-of select="@href"/></filename>
372 <xsl:text>, </xsl:text>
373 <date><xsl:value-of select="@date"/></date>
374 <xsl:text>, </xsl:text>
375 <systemitem><xsl:value-of select="@gitSHA1"/></systemitem>
376 </para>
377 </listitem>
378 </xsl:template>
380 <xsl:template match="p:clays">
381 <chapter>
382 <title>Clays</title>
383 <xsl:apply-templates/>
384 </chapter>
385 </xsl:template>
387 <xsl:template match="p:clay">
388 <section>
389 <xsl:attribute name="xml:id"><xsl:value-of select="@xml:id"/></xsl:attribute>
390 <title>
391 <xsl:value-of select="@name"/>
392 <xsl:if test="@productID">,
393 <xsl:value-of select="@productID"/>
394 </xsl:if>
395 </title>
396 <para/>
397 </section>
398 </xsl:template>
400 <xsl:template match="@* | db:* | @xlink:*">
401 <xsl:copy>
402 <xsl:apply-templates select="@*|node()"/>
403 </xsl:copy>
404 </xsl:template>
406 <xsl:template match="db:date">
407 <emphasis><xsl:value-of select="."/></emphasis>
408 <xsl:text> </xsl:text>
409 </xsl:template>
411 <xsl:template match="p:recipe">
412 <informaltable>
413 <tgroup cols="2">
414 <xsl:variable name="hasReplacement" select="p:component/@replacementFor"/>
415 <thead>
416 <row>
417 <entry>Component</entry>
418 <xsl:if test="$hasReplacement">
419 <entry>Source/Replacement For</entry>
420 </xsl:if>
421 <entry>Parts</entry>
422 <entry>Price/kg, MVA</entry>
423 </row>
424 </thead>
425 <tfoot>
426 <row>
427 <entry/>
428 <xsl:if test="sum(p:component/@parts) &lt; 100">
429 <xsl:message terminate="yes">The components for glaze <xsl:value-of select="../@name"/> amount to less than 100 parts</xsl:message>
430 </xsl:if>
431 <xsl:if test="$hasReplacement">
432 <entry/>
433 </xsl:if>
434 <entry>Total <xsl:value-of select="sum(p:component/@parts)"/></entry>
435 <entry>
436 <xsl:variable name="componentPrices">
437 <xsl:apply-templates mode="computePrice" select="p:component"/>
438 </xsl:variable>
440 Kilo price: TODO <xsl:value-of select="sum(ec:node-set($componentPrices))"/>
441 </entry>
442 </row>
443 </tfoot>
444 <tbody>
445 <xsl:apply-templates select="p:component">
446 <xsl:with-param name="hasReplacement" select="$hasReplacement"/>
447 </xsl:apply-templates>
448 </tbody>
449 </tgroup>
450 </informaltable>
451 </xsl:template>
453 <xsl:template match="p:component">
454 <xsl:param name="hasReplacement"/>
456 <row>
457 <xsl:variable name="component" select="/p:pottery/p:components/p:component[@xml:id = current()/@idref]"/>
458 <xsl:call-template name="checkComponentRef">
459 <xsl:with-param name="component" select="$component"/>
460 <xsl:with-param name="name" select="@idref"/>
461 </xsl:call-template>
462 <entry><xsl:value-of select="$component"/></entry>
463 <xsl:if test="@replacementFor">
464 <xsl:variable name="replacement" select="/p:pottery/p:components/p:component[@xml:id = current()/@replacementFor]"/>
465 <xsl:call-template name="checkComponentRef">
466 <xsl:with-param name="component" select="$replacement"/>
467 <xsl:with-param name="name" select="@replacementFor"/>
468 </xsl:call-template>
469 <entry><xsl:value-of select="$replacement"/></entry>
470 </xsl:if>
472 <xsl:if test="$hasReplacement and not(@replacementFor)">
473 <entry/>
474 </xsl:if>
475 <entry><constant><xsl:value-of select="@parts"/></constant></entry>
477 <entry>
478 <xsl:apply-templates mode="computePrice" select="."/>
479 </entry>
480 </row>
481 </xsl:template>
483 <xsl:template mode="computePrice" match="p:component">
484 <constant>
485 <xsl:variable name="price" select="number(/p:pottery/p:components/p:component[@xml:id = current()/@idref]/@price)"/>
486 <xsl:variable name="priceIsFor" select="number(/p:pottery/p:components/p:component[@xml:id = current()/@idref]/@priceIsFor)"/>
488 <xsl:value-of select="round((($price div ($priceIsFor div 1000)) * (@parts div 100)) * 1.25)"/>
489 </constant>
490 </xsl:template>
492 <xsl:template match="p:measurementsWhenDone">
493 <para>Measurements: height <constant><xsl:value-of select="@height"/></constant> mm,
494 <xsl:choose>
495 <xsl:when test="@width = @depth">
496 diameter <constant><xsl:value-of select="@width"/></constant> mm
497 </xsl:when>
498 <xsl:otherwise>
499 width <constant><xsl:value-of select="@width"/></constant> mm,
500 depth <constant><xsl:value-of select="@depth"/></constant> mm
501 </xsl:otherwise>
502 </xsl:choose>
503 </para>
504 </xsl:template>
506 <xsl:template name="checkComponentRef">
507 <xsl:param name="component"/>
508 <xsl:param name="name"/>
510 <xsl:if test="not($component)">
511 <xsl:message terminate="yes">Component for reference <xsl:value-of select="$name"/> couldn't be found.</xsl:message>
512 </xsl:if>
513 </xsl:template>
515 <!-- We don't use it directly. -->
516 <xsl:template match="p:samples"/>
518 <!-- Flag things we miss. -->
519 <xsl:template match="* | @*">
520 <xsl:message terminate="yes">
521 Unmatched node: <xsl:value-of select="name()"/> <xsl:value-of select="string()"/>
522 </xsl:message>
523 </xsl:template>
525 </xsl:stylesheet>
527 <!--
528 vim: et:ts=4:sw=4:sts=4