My theme for forester (+plugins)
1<?xml version="1.0"?>
2<!-- SPDX-License-Identifier: CC0-1.0 -->
3<xsl:stylesheet version="1.0"
4 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
5 xmlns:f="http://www.forester-notes.org">
6
7 <xsl:key name="tree-with-uri" match="/f:tree/f:mainmatter//f:tree" use="f:frontmatter/f:uri/text()" />
8
9 <xsl:template match="/">
10 <html xmlns="http://www.w3.org/1999/xhtml" data-base-url="{/f:tree/@base-url}">
11 <head>
12 <meta name="viewport" content="width=device-width" />
13 <link rel="stylesheet" href="{/f:tree/@base-url}style.css" />
14 <link rel="stylesheet" href="{/f:tree/@base-url}katex.min.css" />
15 <link href="https://fonts.googleapis.com/css?family=Crimson+Text:400,700,700italic,400italic" rel="stylesheet" type="text/css" />
16 <link href="{/f:tree/@base-url}gabc.css" rel="stylesheet" type="text/css" />
17 <script type="text/javascript">
18 <xsl:if test="/f:tree/f:frontmatter/f:source-path">
19 <xsl:text>window.sourcePath = '</xsl:text>
20 <xsl:value-of select="/f:tree/f:frontmatter/f:source-path" />
21 <xsl:text>'</xsl:text>
22 </xsl:if>
23 </script>
24 <script type="module" src="{/f:tree/@base-url}forester.js"></script>
25 <title>
26 <xsl:value-of select="/f:tree/f:frontmatter/f:title/@text" />
27 </title>
28 </head>
29 <body>
30 <ninja-keys placeholder="Start typing a note title or ID"></ninja-keys>
31 <xsl:if test="not(/f:tree[@root = 'true'])">
32 <header class="header">
33 <nav class="nav">
34 <div class="logo">
35 <a href="{/f:tree/@base-url}index.html" title="Home">
36 <xsl:text>« Home</xsl:text>
37 </a>
38 </div>
39 </nav>
40 </header>
41 </xsl:if>
42 <div id="grid-wrapper">
43 <article>
44 <xsl:apply-templates select="f:tree" />
45 </article>
46 <xsl:if test="f:tree/f:mainmatter/f:tree[not(@toc='false')] and not(/f:tree/f:frontmatter/f:meta[@name = 'toc']/.='false')">
47 <nav id="toc">
48 <div class="block">
49 <h1>Table of Contents</h1>
50 <xsl:apply-templates select="f:tree/f:mainmatter" mode="toc" />
51 </div>
52 </nav>
53 </xsl:if>
54 </div>
55 <script type="text/javascript" src="{/f:tree/@base-url}/exsurge.min.js"></script>
56 <script type="module" src="{/f:tree/@base-url}/shikiblock.js"></script>
57 <script type="module" src="{/f:tree/@base-url}/tsvtable.js"></script>
58 <script type="text/javascript" src="{/f:tree/@base-url}/gabc.js">
59 </script>
60 </body>
61 </html>
62 </xsl:template>
63
64 <xsl:template match="f:tree" mode="tree-taxon-with-number">
65 <xsl:param name="suffix" select="''" />
66 <xsl:param name="taxon" select="f:frontmatter/f:taxon" />
67 <xsl:param name="number" select="f:frontmatter/f:number" />
68 <xsl:param name="fallback-number" />
69 <xsl:param name="in-backmatter" select="ancestor::f:backmatter" />
70
71 <xsl:variable name="tree-is-root" select="not(parent::*)" />
72
73 <xsl:variable name="explicitly-unnumbered" select="boolean(ancestor-or-self::f:tree[@numbered='false' or @toc='false'])" />
74 <xsl:variable name="implicitly-unnumbered" select="count(../f:tree) = 1 and not(count(f:mainmatter/f:tree) > 1)" />
75
76 <xsl:variable name="should-number" select="$number != '' or (not($in-backmatter) and not($tree-is-root) and not($explicitly-unnumbered)) and not($implicitly-unnumbered)" />
77
78 <xsl:if test="$taxon != ''">
79 <xsl:value-of select="$taxon" />
80 <xsl:if test="$should-number or $fallback-number != ''">
81 <xsl:text> </xsl:text>
82 </xsl:if>
83 </xsl:if>
84
85 <xsl:choose>
86 <xsl:when test="$should-number">
87 <xsl:choose>
88 <xsl:when test="$number != ''">
89 <xsl:value-of select="$number" />
90 </xsl:when>
91 <xsl:otherwise>
92 <xsl:number format="1.1" count="f:tree[ancestor::f:tree and (not(@toc='false' or @numbered='false'))]" level="multiple" />
93 </xsl:otherwise>
94 </xsl:choose>
95 </xsl:when>
96 <xsl:when test="$fallback-number != ''">
97 <xsl:value-of select="$fallback-number" />
98 </xsl:when>
99 </xsl:choose>
100
101 <xsl:if test="$taxon != '' or $fallback-number != '' or $should-number">
102 <xsl:value-of select="$suffix" />
103 </xsl:if>
104 </xsl:template>
105
106 <xsl:template match="f:tree" mode="contextual-number">
107 <xsl:param name="suffix" select="''" />
108 <xsl:param name="number" select="f:frontmatter/f:number" />
109 <xsl:param name="fallback-number" />
110 <xsl:param name="in-backmatter" select="ancestor::f:backmatter" />
111
112 <xsl:variable name="tree-is-root" select="not(parent::*)" />
113
114 <xsl:variable name="explicitly-unnumbered" select="boolean(ancestor-or-self::f:tree[@numbered='false' or @toc='false'])" />
115 <xsl:variable name="implicitly-unnumbered" select="count(../f:tree) = 1 and not(count(f:mainmatter/f:tree) > 1)" />
116
117 <xsl:variable name="should-number" select="$number != '' or (not($in-backmatter) and not($tree-is-root) and not($explicitly-unnumbered)) and not($implicitly-unnumbered)" />
118
119 <xsl:choose>
120 <xsl:when test="$should-number">
121 <xsl:choose>
122 <xsl:when test="$number != ''">
123 <xsl:value-of select="$number" />
124 </xsl:when>
125 <xsl:otherwise>
126 <xsl:number format="1.1" count="f:tree[ancestor::f:tree and (not(@toc='false' or @numbered='false'))]" level="multiple" />
127 </xsl:otherwise>
128 </xsl:choose>
129 </xsl:when>
130 <xsl:when test="$fallback-number != ''">
131 <xsl:value-of select="$fallback-number" />
132 </xsl:when>
133 </xsl:choose>
134
135 <xsl:if test="$fallback-number != '' or $should-number">
136 <xsl:value-of select="$suffix" />
137 </xsl:if>
138 </xsl:template>
139
140 <xsl:template match="f:tree" mode="toc">
141 <li>
142 <xsl:for-each select="f:frontmatter">
143 <a class="bullet">
144 <xsl:choose>
145 <xsl:when test="f:display-uri and f:route">
146 <xsl:attribute name="href">
147 <xsl:value-of select="f:route" />
148 </xsl:attribute>
149 <xsl:attribute name="title">
150 <xsl:value-of select="f:title/@text" />
151 <xsl:text> [</xsl:text>
152 <xsl:value-of select="f:display-uri" />
153 <xsl:text>]</xsl:text>
154 </xsl:attribute>
155 </xsl:when>
156 <xsl:otherwise>
157 <xsl:attribute name="href">
158 <xsl:text>#</xsl:text>
159 <xsl:value-of select="generate-id(..)" />
160 </xsl:attribute>
161 <xsl:attribute name="title">
162 <xsl:value-of select="f:title" />
163 </xsl:attribute>
164 </xsl:otherwise>
165 </xsl:choose>
166 <xsl:text>■</xsl:text>
167 </a>
168 <span class="link local" data-target="#{generate-id(..)}">
169 <span class="taxon">
170 <xsl:apply-templates select=".." mode="tree-taxon-with-number">
171 <xsl:with-param name="suffix">. </xsl:with-param>
172 </xsl:apply-templates>
173 </span>
174
175 <xsl:apply-templates select="f:title" />
176 </span>
177 </xsl:for-each>
178 <xsl:apply-templates select="f:mainmatter" mode="toc" />
179 </li>
180 </xsl:template>
181
182 <xsl:template match="f:mainmatter" mode="toc">
183 <ul class="block">
184 <xsl:apply-templates select="f:tree[not(@toc='false')]" mode="toc" />
185 </ul>
186 </xsl:template>
187
188 <xsl:template match="f:frontmatter/f:title">
189 <xsl:apply-templates />
190 </xsl:template>
191
192 <xsl:template match="f:mainmatter">
193 <xsl:apply-templates />
194 </xsl:template>
195
196 <xsl:template match="f:display-uri[../f:route]">
197 <a class="slug" href="{../f:route}">
198 <xsl:text>[</xsl:text>
199 <xsl:value-of select="." />
200 <xsl:text>]</xsl:text>
201 </a>
202 </xsl:template>
203
204 <xsl:template match="f:display-uri[not(../f:route)]">
205 </xsl:template>
206
207 <xsl:template match="f:resource">
208 <xsl:apply-templates select="f:resource-content" />
209 </xsl:template>
210
211 <xsl:template match="f:resource-content">
212 <xsl:apply-templates />
213 </xsl:template>
214
215 <xsl:template match="f:source-path">
216 <a class="edit-button" href="{concat('vscode://file', .)}">
217 <xsl:text>[edit]</xsl:text>
218 </a>
219 </xsl:template>
220
221 <xsl:template match="f:taxon">
222 <xsl:value-of select="." />
223 </xsl:template>
224
225 <xsl:template match="f:frontmatter">
226 <header>
227 <h1>
228 <span class="taxon">
229 <xsl:apply-templates select=".." mode="tree-taxon-with-number">
230 <xsl:with-param name="suffix">. </xsl:with-param>
231 </xsl:apply-templates>
232 </span>
233
234 <xsl:apply-templates select="f:title" />
235 <xsl:text> </xsl:text>
236 <xsl:apply-templates select="f:display-uri" />
237 <xsl:text> </xsl:text>
238 <xsl:apply-templates select="f:source-path" />
239 </h1>
240 <div class="metadata">
241 <ul>
242 <xsl:apply-templates select="f:date" />
243 <xsl:if test="not(f:meta[@name = 'author']/.='false')">
244 <xsl:apply-templates select="f:authors" />
245 </xsl:if>
246 <xsl:apply-templates select="f:meta[@name='position']" />
247 <xsl:apply-templates select="f:meta[@name='institution']" />
248 <xsl:apply-templates select="f:meta[@name='venue']" />
249 <xsl:apply-templates select="f:meta[@name='source']" />
250 <xsl:apply-templates select="f:meta[@name='doi']" />
251 <xsl:apply-templates select="f:meta[@name='orcid']" />
252 <xsl:apply-templates select="f:meta[@name='external']" />
253 <xsl:apply-templates select="f:meta[@name='download']" />
254 <xsl:apply-templates select="f:meta[@name='slides']" />
255 <xsl:apply-templates select="f:meta[@name='video']" />
256 </ul>
257 </div>
258 </header>
259 </xsl:template>
260
261 <xsl:template match="f:ref">
262 <xsl:variable name="fallback-number">
263 <xsl:text>[</xsl:text>
264 <xsl:value-of select="@uri" />
265 <xsl:text>]</xsl:text>
266 </xsl:variable>
267
268 <xsl:variable name="taxon">
269 <xsl:choose>
270 <xsl:when test="@taxon">
271 <xsl:value-of select="@taxon" />
272 </xsl:when>
273 <xsl:otherwise>
274 <xsl:text>§</xsl:text>
275 </xsl:otherwise>
276 </xsl:choose>
277 </xsl:variable>
278
279 <a class="link local">
280 <xsl:attribute name="href">
281 <xsl:choose>
282 <xsl:when test="key('tree-with-uri',current()/@uri)">
283 <xsl:text>#</xsl:text>
284 <xsl:value-of select="generate-id(key('tree-with-uri',current()/@uri))" />
285 </xsl:when>
286 <xsl:otherwise>
287 <xsl:value-of select="@href" />
288 </xsl:otherwise>
289 </xsl:choose>
290 </xsl:attribute>
291
292 <xsl:choose>
293 <xsl:when test="key('tree-with-uri', current()/@uri)">
294 <xsl:apply-templates select="key('tree-with-uri', current()/@uri)" mode="tree-taxon-with-number">
295 <xsl:with-param name="in-backmatter" select="boolean(ancestor::f:backmatter)" />
296 <xsl:with-param name="number" select="@number" />
297 <xsl:with-param name="fallback-number" select="$fallback-number" />
298 <xsl:with-param name="taxon" select="$taxon" />
299 </xsl:apply-templates>
300 </xsl:when>
301 <xsl:otherwise>
302 <xsl:value-of select="$taxon" />
303 <xsl:text> </xsl:text>
304 <xsl:choose>
305 <xsl:when test="@number">
306 <xsl:value-of select="@number" />
307 </xsl:when>
308 <xsl:otherwise>
309 <xsl:value-of select="$fallback-number" />
310 </xsl:otherwise>
311 </xsl:choose>
312 </xsl:otherwise>
313 </xsl:choose>
314 </a>
315 </xsl:template>
316
317 <xsl:template match="f:contextual-number[@uri]">
318 <xsl:variable name="fallback-number">
319 <xsl:text>[</xsl:text>
320 <xsl:value-of select="@display-uri" />
321 <xsl:text>]</xsl:text>
322 </xsl:variable>
323
324 <xsl:choose>
325 <xsl:when test="key('tree-with-uri', current()/@uri)">
326 <xsl:apply-templates select="key('tree-with-uri', current()/@uri)" mode="contextual-number">
327 <xsl:with-param name="in-backmatter" select="boolean(ancestor::f:backmatter)" />
328 <xsl:with-param name="fallback-number" select="$fallback-number" />
329 </xsl:apply-templates>
330 </xsl:when>
331 <xsl:otherwise>
332 <xsl:value-of select="$fallback-number" />
333 </xsl:otherwise>
334 </xsl:choose>
335 </xsl:template>
336
337 <xsl:template match="/f:tree[@root='true']/f:backmatter">
338 </xsl:template>
339
340 <xsl:template match="/f:tree[not(@root='true')]/f:backmatter">
341 <footer>
342 <xsl:apply-templates />
343 </footer>
344 </xsl:template>
345
346 <xsl:template match="f:mainmatter//f:backmatter">
347 </xsl:template>
348
349 <xsl:template match="f:backmatter//f:backmatter">
350 </xsl:template>
351
352 <xsl:template match="f:tree[f:mainmatter[*] or not(@hidden-when-empty = 'true')]">
353 <section>
354 <xsl:attribute name="lang">
355 <xsl:choose>
356 <xsl:when test="f:frontmatter/f:meta[@name='lang']">
357 <xsl:value-of select="f:frontmatter/f:meta[@name='lang']" />
358 </xsl:when>
359 <xsl:otherwise>en</xsl:otherwise>
360 </xsl:choose>
361 </xsl:attribute>
362
363 <xsl:choose>
364 <xsl:when test="@show-metadata = 'false'">
365 <xsl:attribute name="class">block hide-metadata</xsl:attribute>
366 </xsl:when>
367 <xsl:otherwise>
368 <xsl:attribute name="class">block</xsl:attribute>
369 </xsl:otherwise>
370 </xsl:choose>
371 <xsl:if test="f:frontmatter/f:taxon">
372 <xsl:attribute name="data-taxon">
373 <xsl:value-of select="f:frontmatter/f:taxon" />
374 </xsl:attribute>
375 </xsl:if>
376
377 <xsl:choose>
378 <xsl:when test="not(@show-heading='false')">
379 <details id="{generate-id(.)}">
380 <xsl:if test="not(@expanded = 'false')">
381 <xsl:attribute name="open">open</xsl:attribute>
382 </xsl:if>
383 <summary>
384 <xsl:apply-templates select="f:frontmatter" />
385 </summary>
386 <xsl:apply-templates select="f:mainmatter" />
387 <xsl:apply-templates select="f:frontmatter/f:meta[@name='bibtex']" />
388 </details>
389 </xsl:when>
390 <xsl:otherwise>
391 <xsl:apply-templates select="f:mainmatter" />
392 </xsl:otherwise>
393 </xsl:choose>
394 </section>
395
396 <xsl:apply-templates select="f:backmatter" />
397 </xsl:template>
398
399 <xsl:template match="f:tree"></xsl:template>
400
401</xsl:stylesheet>