tei2teisimple.xqm 34.4 KB
Newer Older
MRodz's avatar
MRodz committed
1
2
xquery version "3.1";

3
(:~
Michelle Rodzis's avatar
Michelle Rodzis committed
4
5
 : This modules handles the conversion of the Fontante-TEI/XML into TEI simplePrint
 : for the edited text. The resulting TEI simplePrint is the basis for the "Editerter
6
 : Text" (edited text) view on the website and the book. It represents the latest
Michelle Rodzis's avatar
Michelle Rodzis committed
7
 : layer of text.
8
 :
MRodz's avatar
MRodz committed
9
10
 : @author Michelle Rodzis
 : @version 0.1
Michelle Rodzis's avatar
Michelle Rodzis committed
11
 : @since TODO
MRodz's avatar
MRodz committed
12
13
 :)

14
module namespace fontaneSimple="http://fontane-nb.dariah.eu/teisimple";
MRodz's avatar
MRodz committed
15
16

declare namespace tei="http://www.tei-c.org/ns/1.0";
MRodz's avatar
MRodz committed
17
declare namespace test="http://exist-db.org/xquery/xqsuite";
MRodz's avatar
MRodz committed
18
19

import module namespace console="http://exist-db.org/xquery/console";
20
import module namespace simpleHelpers="http://fontane-nb.dariah.eu/teisimplehelpers" at "teisimplehelpers.xqm";
21
import module namespace index-info="http://fontane-nb.dariah.eu/index-info" at "index-info.xqm";
MRodz's avatar
MRodz committed
22

23
(:~
MRodz's avatar
MRodz committed
24
 : The main function initiates the transformation of a given notebook.
25
 :
MRodz's avatar
MRodz committed
26
 : TODO: adapt to several input files?
27
 :
MRodz's avatar
MRodz committed
28
 : :)
MRodz's avatar
MRodz committed
29
declare function fontaneSimple:main($file as xs:string) as node()? {
30
  let $doc :=
MRodz's avatar
MRodz committed
31
    try {
32
      (doc("/db/sade-projects/textgrid/data/xml/data/" || $file))
MRodz's avatar
MRodz committed
33
34
35
    } catch * {
      (console:log("It was not possible to open the requested file " || $file))
    }
36

MRodz's avatar
Fix #23    
MRodz committed
37
38
    let $front-covers := $doc//tei:sourceDoc/tei:surface[contains(@n, "front_cover")]
    let $back-covers := $doc//tei:sourceDoc/tei:surface[contains(@n, "back_cover")]
39
    let $content := $doc//tei:sourceDoc/tei:surface[not(contains(@n, "cover")
MRodz's avatar
MRodz committed
40
        or matches(@n, "spine"))]
41

42
    let $tei := <TEI xmlns="http://www.tei-c.org/ns/1.0">
MRodz's avatar
MRodz committed
43
        {$doc//tei:teiHeader}
MRodz's avatar
MRodz committed
44
        <text>
45
46
47
            <front>{fontaneSimple:transform($front-covers)}</front>
            <body>{fontaneSimple:transform($content)}</body>
            <back>{fontaneSimple:transform($back-covers)}</back>
MRodz's avatar
MRodz committed
48
        </text>
MRodz's avatar
MRodz committed
49
      </TEI>
50
     let $store := xmldb:store("/db/apps/SADE/resources/xml/", "tei-simple-pre.xml", $tei)
MRodz's avatar
MRodz committed
51
    return $tei
MRodz's avatar
MRodz committed
52
53
};

54
(:~
55
56
57
58
59
60
61
62
63
 : Recursivly iterates the passed nodes and converts them according to the
 : requirements for the "Edierter Text". While it convers almost all of the
 : requirements stated in the encoding documentation (c.f.
 : https://fontane-nb.dariah.eu/doku.html), some parts of it are handled in a
 : second step (c.f. TODO) - especially the removal of tei:handShift duplicates
 : and the tei:milestone expansion to tei:div[@type = "section"] resp. tei:p -
 : because it is easier to perform these steps after the XML hierarchy has been
 : flattened a bit.
 :
MRodz's avatar
MRodz committed
64
 : @author Michelle Rodzis
65
 : @param $nodes the elements of the book covers and the book content
Michelle Rodzis's avatar
Michelle Rodzis committed
66
 : @return $node()* a TEI simplePrint element
MRodz's avatar
MRodz committed
67
 :)
68
declare function fontaneSimple:transform($nodes as node()*) as node()* {
MRodz's avatar
MRodz committed
69
70
71
    for $node in $nodes
      return
        typeswitch ($node)
MRodz's avatar
MRodz committed
72
        case text() return
MRodz's avatar
MRodz committed
73
74
75
76
77
78
79
            if($node/ancestor::tei:line
            or $node/ancestor::tei:figDesc
            or $node/ancestor::tei:desc[@type = "edited_text"]
            or $node/ancestor::tei:note[@type = "editorial"]) then
                simpleHelpers:prepare-text($node)
            else
                ()
80

MRodz's avatar
MRodz committed
81
82
83
        case element(tei:lb) return
            if($node[@break = "keepHyphen"]) then
                ()
84
85
            else if($node[@break = "no"]) then
                fontaneSimple:mark-intervention($node)
MRodz's avatar
MRodz committed
86
            else
87
                fontaneSimple:copy-element($node)
88

MRodz's avatar
MRodz committed
89
90
91
92
        case element(tei:g) return
            if($node[@ref = "#vds"]) then
                ()
            else if($node/@ref ="#rth" or $node/@ref ="#hb") then
93
                fontaneSimple:copy-element($node)
MRodz's avatar
MRodz committed
94
            else
95
                fontaneSimple:transform($node/node())
96

MRodz's avatar
MRodz committed
97
98
        case element(tei:del) return
            if($node/parent::tei:restore) then
99
                fontaneSimple:transform($node/node())
MRodz's avatar
MRodz committed
100
            else if($node/descendant::tei:restore) then
101
                fontaneSimple:transform($node/descendant::tei:restore)
MRodz's avatar
MRodz committed
102
            else
MRodz's avatar
MRodz committed
103
                ()
104

MRodz's avatar
MRodz committed
105
106
107
108
109
        case element(tei:restore) return
            if(count($node/child::*) = 1 and $node/child::tei:del
            and $node/ancestor::tei:del) then
                ()
            else
110
                fontaneSimple:transform($node/node())
111

MRodz's avatar
MRodz committed
112
113
114
        case element(tei:retrace) return
            if($node/@rend) then
                element tei:seg {
Michelle Rodzis's avatar
Michelle Rodzis committed
115
                    attribute rendition {$node/@rend},
116
                    fontaneSimple:transform($node/node())
MRodz's avatar
MRodz committed
117
118
                }
            else
119
                fontaneSimple:transform($node/node())
120

121
        case element(tei:add) return
122
            if($node/@type = "edited_text"
123
            or $node/child::tei:seg[@type = "multiphrase"]) then
124
                fontaneSimple:copy-element($node)
125
126
127
128
(:                :)
(:            else if($node[matches(@copyOf, $node/preceding::tei:seg/@xml:id):)
(:                and not(@cause = "unclear")]) then:)
(:                fontaneSimple:mark-intervention($node):)
129
                
130
131
132
133
134
            
            else if($node/@cause = "unclear") then
                ()
                
            else if($node[matches(@copyOf, $node/preceding::tei:seg/@xml:id)]) then
135
                fontaneSimple:mark-intervention($node)
136
                
137
            else if($node/@cause ="catchword") then
MRodz's avatar
MRodz committed
138
                ()
139
                
MRodz's avatar
MRodz committed
140
            else if($node/@rend ="|") then
141
                fontaneSimple:transform($node/node())
142
                
143
            else if(not($node/@xml:id)) then
144
                fontaneSimple:transform($node/node())
145
                
146
            else if(simpleHelpers:is-transposed($node)) then
147
148
                let $corresp := //tei:metamark[matches(@target, $node/@xml:id)]
                return
149
150
                    (fontaneSimple:transform($corresp/node()),
                    fontaneSimple:transform($node/node()))
151
                    
152
            else
153
                fontaneSimple:transform($node/node())
154

155
156
        case element(tei:addSpan) return
            if($node/@type = "edited_text") then
157
                fontaneSimple:copy-element($node)
158
            else
159
160
                ()

161
162
        case element(tei:fw) return
            ()
163

164
        case element(tei:line) return
Michelle Rodzis's avatar
Michelle Rodzis committed
165
            if($node/@type = "heading") then
166
                fontaneSimple:make-head($node)
167

168
            else if(simpleHelpers:has-valid-style($node)
169
            or matches($node/@rendition, "black_letter")
170
            or matches($node/@rendition, "roman")) then
171
                fontaneSimple:make-seg-with-rendition($node)
172
173
                
            else if($node/following::*[1][self::tei:lb[@break = "no"]]) then
174
                (simpleHelpers:start-line($node),
175
                simpleHelpers:trim-last-char($node))
176
177
                
            else if ($node/preceding::*[1][self::tei:lb[@break = "no"]]) then
178
                (simpleHelpers:start-line($node),
179
                simpleHelpers:trim-first-char($node))
180
181
                
            else if($node/@type = "verse") then
MRodz's avatar
MRodz committed
182
183
184
185
186
187
188
189
190
191
192
193
194
                if(not($node/@next)) then
                    (if(not($node/preceding-sibling::tei:line[@type = "verse"])) then
                        fontaneSimple:mark-linegroup-beginning()
                    else
                        (),
                    element tei:l {
                            fontaneSimple:transform($node/node())
                        },
                    if(not($node/following-sibling::tei:line[@type = "verse"])) then
                        fontaneSimple:mark-linegroup-end()
                    else
                        ())  
                (: 3.8.2.2.1.3 Vers mit anderer Beschriftung in einer Zeile :)
195
                else
MRodz's avatar
MRodz committed
196
197
198
199
200
201
202
203
204
205
206
207
208
                    let $corresp := $node/following::tei:seg[@type = "verse" 
                        and matches($node/@next, @xml:id)]
                    return
                        (fontaneSimple:mark-linegroup-beginning(),
                        element tei:l {
                            fontaneSimple:transform($node/node()),
                            simpleHelpers:start-line($node),
                            fontaneSimple:transform($corresp/node())
                        },
                        fontaneSimple:mark-linegroup-end())
                    
            else if($node/parent::tei:zone[@type = "verse"]/child::*[1] = $node) then
                fontaneSimple:transform($node/node())             
209
                
210
211
212
            (: with opting for a tei:milestone we try to meet the project's
            requirements on the one hand while avoiding to run into hierarchical
            problems in the further processing on the other hand:)
213
            else if(not($node/@type = "item")) then
214
                (simpleHelpers:start-line($node),
215
                fontaneSimple:transform($node/node()))
216
                
MRodz's avatar
MRodz committed
217
            else if($node/@type = "item") then
218
                element tei:item {
MRodz's avatar
MRodz committed
219
                    $node/(@* except (@rend, @type, @style)),
Michelle Rodzis's avatar
Michelle Rodzis committed
220
221
222
223
                    if($node/@rend) then
                        attribute rendition {$node/@rend}
                    else
                        (),
224
                    fontaneSimple:transform($node/node())
225
                }
226
                
227
            else
228
                (simpleHelpers:start-line($node),
229
                fontaneSimple:transform($node/node()))
230

231
        case element(tei:handShift) return
232
            fontaneSimple:enhance-handshift($node)
233

234
        case element(tei:stamp) return
Michelle Rodzis's avatar
Michelle Rodzis committed
235
236
237
238
            if($node/ancestor::tei:surface[matches(@n, "Beilage")]) then
                fontaneSimple:copy-element($node)
            else
                ()
239

240
        case element(tei:seg) return
241
            if(count($node/*) = 1 and
Michelle Rodzis's avatar
Michelle Rodzis committed
242
243
244
            (($node/tei:stamp 
                and not($node/ancestor::tei:surface[matches(@n, "Beilage")]))
            or $node/tei:metamark[@function = "caret"]))
245
246
                then
                    ()
247

MRodz's avatar
MRodz committed
248
            else if($node/@type = "heading") then
MRodz's avatar
MRodz committed
249
                fontaneSimple:make-head($node)
250
251

            else if(matches($node/@style, "underline")
252
            and not(matches($node/@style, "vertical-align"))) then
253
                fontaneSimple:transform($node/node())
254

255
            else if(simpleHelpers:has-valid-style($node)
256
            or matches($node/@rendition, "black_letter")
257
            or matches($node/@rendition, "roman")) then
258
                fontaneSimple:make-seg-with-rendition($node)
259
260
261

            else if($node/@type = "initials"
            or $node/@type = "monogram"
MRodz's avatar
MRodz committed
262
263
            or $node/@type = "multiphrase"
            or $node/@xml:lang)
264
                then
265
                    fontaneSimple:copy-element($node)
266
267

            else if($node/@type = "auction_number"
268
            or $node/@type = "cancel"
MRodz's avatar
MRodz committed
269
270
            or $node/@type = "abort"
            or $node/@function ="unknown")
271
272
                then
                    ()
273
274
275
                    
            else if($node/parent::tei:add and $node/@copyOf) then
                fontaneSimple:mark-intervention($node)
MRodz's avatar
MRodz committed
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
                
            else if($node/@type = "verse" and $node/@prev) then
                ()
                
            else if($node/@type = "said") then
                if($node/@next) then
                    let $next := replace($node/@next, "#", "")
                    let $corresp := $node/following::*[@xml:id = $next]
                    return
                        (element tei:seg {
                            $node/@type,
                            fontaneSimple:transform($node/node()),
                            fontaneSimple:transform($corresp/node())
                        },
                        element tei:lb {
                            attribute type {"edited_text"}
                        })
                else
                    element tei:seg {
                        $node/@type,
                        fontaneSimple:transform($node/node())
                    }
298

299
            else
300
                fontaneSimple:transform($node/node())
301

MRodz's avatar
MRodz committed
302
        case element(tei:hi) return
303
            fontaneSimple:copy-element($node)
304
305

        (: TODO if $node/@type = "highlighted" then make
306
        a hi[@type = "vertical-mark"] in the second stage of creating the
307
        simple format. use simpleHelpers:get-xml-chunk($node) for this.:)
308
309
        case element(tei:mod) return
            if($node/@type = "highlighted"
310
            and simpleHelpers:is-hand-contemporary($node/@hand)) then
311
                $node
312
313
            else
                fontaneSimple:transform($node/node())
314

315
        case element(tei:anchor) return
316
            fontaneSimple:copy-element($node)
317
318

        case element(tei:surface) return
MRodz's avatar
MRodz committed
319
            if(matches($node/@n, "cover")) then
Michelle Rodzis's avatar
Michelle Rodzis committed
320
321
                (fontaneSimple:make-pb-with-type($node/@n),
                fontaneSimple:transform($node/node()))
Michelle Rodzis's avatar
Michelle Rodzis committed
322
323
324
325
326
327
328
329
330
331
332
333
334
                
            else if(matches($node/@n, "Beilage")) then
                element tei:div {
                    $node/@*,
                    fontaneSimple:transform($node/node())
                }
                
            else if($node/@type = "pocket") then
                (fontaneSimple:make-pb($node),
                element tei:div {
                    $node/(@* except (@n, @ulx, @uly, @lry, @lrx)),
                    fontaneSimple:transform($node/node())
                })
Michelle Rodzis's avatar
Michelle Rodzis committed
335
            
336
            else if(simpleHelpers:is-page($node)
MRodz's avatar
MRodz committed
337
            and $node/@type = "clipping") then
338
                (fontaneSimple:make-pb($node),
MRodz's avatar
MRodz committed
339
340
                (if(not($node/@subtype = "Kalenderblatt"
                or $node/@subtype = "Zeitungsausschnitt_Fragment")) then
Michelle Rodzis's avatar
Michelle Rodzis committed
341
342
343
344
                    element tei:div {
                        $node/(@* except (@n, @ulx, @uly, @lry, @lrx)),
                        fontaneSimple:transform($node/node())
                    }
MRodz's avatar
MRodz committed
345
346
                else
                    ()))
Michelle Rodzis's avatar
Michelle Rodzis committed
347
            
348
            else if(simpleHelpers:is-page($node)) then
349
                (fontaneSimple:make-pb($node),
350
                fontaneSimple:transform($node/node()))
Michelle Rodzis's avatar
Michelle Rodzis committed
351
            
352
            else if($node/@type = "label" and
353
            (contains($node/@subtype, "Fontane")
354
            or contains($node/@subtype, "Hersteller"))
355
            ) then
356
                fontaneSimple:make-div($node)
Michelle Rodzis's avatar
Michelle Rodzis committed
357
            
MRodz's avatar
MRodz committed
358
359
            else
                ()
360

MRodz's avatar
MRodz committed
361
362
363
364
        case element(tei:milestone) return
            if($node/@unit = "illustration") then
                ()
            else
365
                fontaneSimple:copy-element($node)
366

367
        case element(tei:gap) return
368
            fontaneSimple:copy-element($node)
369

370
        case element(tei:metamark) return
371
            if($node/@function = "integrate"
372
373
374
375
            or $node/@function = "authorial_note") then
                element tei:ab {
                    $node/@*
                }
376
            else if($node/@function = "placeholder"
377
378
            or $node/@function ="etc."
            or $node/@function ="caret"
MRodz's avatar
MRodz committed
379
            or $node/@function = "footnote-mark"
380
381
382
            or $node/@function ="footnotes"
            or $node/@function ="ellipsis"
            or $node/@function = "paragraph") then
MRodz's avatar
MRodz committed
383
384
                element tei:ab {
                    attribute type {$node/@function},
385
                    fontaneSimple:transform($node/node())
386
                }
387
388
            else
                ()
389

390
        case element(tei:surplus) return
391
            fontaneSimple:mark-intervention($node)
392

MRodz's avatar
MRodz committed
393
        case element(tei:zone) return
394
            if(matches($node/@style, "border-style:solid")
MRodz's avatar
MRodz committed
395
396
397
398
            and not(matches($node/@style, "border-radius"))
            and not($node/@rend = "border-style:house")) then
                element tei:div {
                    attribute type {"frame"},
399
                    fontaneSimple:transform($node/node())
MRodz's avatar
MRodz committed
400
                }
401

MRodz's avatar
MRodz committed
402
            else if(matches($node/@rend, "border-bottom-style:brace")) then
403
                (fontaneSimple:transform($node/node()),
MRodz's avatar
MRodz committed
404
405
                element tei:ab {
                    attribute type {"bottom-brace"}
406
407
                })

MRodz's avatar
MRodz committed
408
409
            else if($node/@type = "cancel") then
                ()
410

MRodz's avatar
MRodz committed
411
412
413
414
            else if($node/@type = "marked_off") then
                element tei:seg {
                    $node/@type,
                    $node/@xml:id,
415
                    fontaneSimple:transform($node/node())
MRodz's avatar
MRodz committed
416
                }
417

MRodz's avatar
MRodz committed
418
419
            else if($node/@type = "highlighted") then
                if($node/child::tei:zone[@type = "highlighted"]) then
420
                    fontaneSimple:transform($node/node())
MRodz's avatar
MRodz committed
421
422
423
                else
                    element tei:hi {
                        attribute type {"vertical-mark"},
424
                        fontaneSimple:transform($node/node())
MRodz's avatar
MRodz committed
425
                    }
426

427
428
            else if($node/@type = "illustration"
            or $node/@type = "printed_illustration") then
MRodz's avatar
MRodz committed
429
430
431
432
433
434
435
                if(not($node//tei:figure/parent::tei:del)) then
                    element {QName("http://www.tei-c.org/ns/1.0", "ab")}{
                        (if($node/child::tei:zone[@type = "illustration"]) then
                            attribute type {"composed-sketch"}
                        else
                            (attribute type {"sketch"},
                            if($node/parent::tei:zone[@type = "illustration"]) then
436
                                attribute rendition {"margin-left:" || $node/@ulx
MRodz's avatar
MRodz committed
437
438
439
440
441
                                || "cm; " || "margin-top:" || $node/@uly || "cm"}
                            else
                                ()
                            )
                        ),
442
                        fontaneSimple:transform($node/node())
MRodz's avatar
MRodz committed
443
                    }
444
                else
MRodz's avatar
MRodz committed
445
                    ()
446

447
448
            else if($node/parent::tei:zone/@type = "illustration"
            or $node/parent::tei:zone/@type = "printed_illustration") then
MRodz's avatar
MRodz committed
449
450
                element {QName("http://www.tei-c.org/ns/1.0", "seg")}{
                    attribute type {"caption"},
451
                    attribute rendition {"margin-left:" || $node/@ulx || "cm; "
MRodz's avatar
MRodz committed
452
                        || "margin-top:" || $node/@uly || "cm"},
453
                    fontaneSimple:transform($node/node())
MRodz's avatar
MRodz committed
454
                }
455

MRodz's avatar
MRodz committed
456
            else if($node/@type = "heading") then
457
                fontaneSimple:make-head($node)
458

MRodz's avatar
MRodz committed
459
            else if($node/@type = "list" or $node/@type = "item") then
460
                element {QName("http://www.tei-c.org/ns/1.0", $node/@type)} {
Michelle Rodzis's avatar
Michelle Rodzis committed
461
462
463
464
465
                    $node/(@xml:id, @subtype, @rendition, @prev, @next),
                    if($node/@rend) then
                        attribute rendition {$node/@rend}
                    else
                        (),                    
466
                    fontaneSimple:transform($node/node())
467
                }
Michelle Rodzis's avatar
Michelle Rodzis committed
468
                
MRodz's avatar
MRodz committed
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
            else if($node/@type = "dialogue") then
                element tei:div {
                    $node/@type,
                    fontaneSimple:transform($node/node())
                }
                
            else if($node/@type = "verse") then
                (fontaneSimple:mark-linegroup-beginning(),
                element tei:l {
                    fontaneSimple:transform($node/node())
                },
                fontaneSimple:mark-linegroup-end())
                
            else if($node/@type = "said" and $node/@prev) then
                ()
                
            else if($node/@type = "said") then
                element tei:seg {
                    $node/@type,
                    fontaneSimple:transform($node/node())
                }
                
MRodz's avatar
MRodz committed
491
492
493
494
            else if($node/@type = "toc" 
            and matches($node/@subtype, "ungültig")) then
                ()
                
Michelle Rodzis's avatar
Michelle Rodzis committed
495
496
            else if($node/@type = "toc") then
                element tei:list {
497
                    $node/(@type, @subtype),
Michelle Rodzis's avatar
Michelle Rodzis committed
498
499
                    fontaneSimple:transform($node/node())
                }
500

MRodz's avatar
MRodz committed
501
502
            else if($node/@type = "legend") then
                element {QName("http://www.tei-c.org/ns/1.0", "div")}{
503
                    (if($node/@style
504
505
506
507
508
                    or $node/@rendition) then
                        attribute rendition {simpleHelpers:filter-rendition($node)}
                    else
                        ()),
                    $node/(@* except (@rendition, @style)),
509
                    fontaneSimple:transform($node/node())
510
                }
Michelle Rodzis's avatar
Michelle Rodzis committed
511
512
513
514
515
516
                
            else if($node/@type = "additional") then
                element tei:ab {
                    $node/(@* except (@ulx, @uly, @lry, @lrx)),
                    fontaneSimple:transform($node/node())
                }
517

518
            else if(simpleHelpers:has-valid-style($node)
519
            or matches($node/@rendition, "black_letter")
520
            or matches($node/@rendition, "script")
521
            or matches($node/@rendition, "roman")) then
522
                fontaneSimple:make-seg-with-rendition($node)
523

524
            else if(not($node/@xml:id)) then
525
                fontaneSimple:transform($node/node())
526

527
528
529
530
531
532
533
534
            else if($node/@xml:id) then
                element tei:seg {
                    $node/@xml:id,
                    $node/@prev,
                    $node/@next,
                    $node/@corresp,
                    fontaneSimple:transform($node/node())
                }
535

MRodz's avatar
MRodz committed
536
            else
537
                fontaneSimple:transform($node/node())
MRodz's avatar
MRodz committed
538
539
540
541
542
543
544
545
546
547
548
549
                
        case element(tei:said) return
            (element tei:seg {
                attribute type {"said"},
                fontaneSimple:transform($node/node())
            },
            if($node/ancestor::tei:zone[@type = "dialogue"]/descendant::tei:said[position() != last()] = $node) then
                element tei:lb {
                        attribute type {"edited_text"}
                }
            else
                ())
550

MRodz's avatar
MRodz committed
551
        case element(tei:figure) return
552
            if(count($node/child::*) = 1 and $node/child::tei:figDesc) then
553
                (: genealogy lines probably shouldn't be displayed, but I still have to
554
555
556
557
                check that. in case they should be serialized, I leave the code :)
(:                if(matches($node/descendant::tei:ref, "Stammbaumverbindungslinie")) then:)
(:                    element tei:seg {:)
(:                        $node/@*,:)
558
(:                        fontaneSimple:transform($node/node()):)
559
560
561
562
563
564
(:                    }:)
(:                else if(matches($node/descendant::tei:ref, "Schlusslinie")):)
                if(matches($node/descendant::tei:ref, "Schlusslinie"))
                    then
                        element tei:ab {
                            switch ($node/descendant::tei:ref)
565
566
567
                                case "horizontale einfache Schlusslinie" return
                                    attribute type {"long-end-line"}
                                case "Schlusslinie; horizontale Halbschleife von links oben nach rechts" return
568
                                    attribute type {"long-end-line"}
569
                                case "horizontale einfache Schlusslinie (gewellt)" return
570
                                    attribute type {"long-end-line-wavy"}
571
                                case "Schlusslinien; horizontale Schleife von links oben nach rechts unten" return
572
                                    attribute type {"bottom-brace-short"}
573
574
                                default return
                                    attribute type {"end-line"}
575
576
                        }
                else if(matches($node/descendant::tei:ref, "Absatzlinie")
577
578
                (: in case of double paragraph lines the single lines are
                encoded with "oberer" resp. "unterer Teil", but we only
579
580
581
582
583
584
585
586
587
588
                serialize the encoding for the upper line :)
                and not(matches($node/descendant::tei:ref, "unterer Teil"))
                and not(matches($node/descendant::tei:figDesc, "unsicher"))) then
                    element tei:ab {
                        if(matches($node/descendant::tei:ref, "doppelt"))
                            then
                                attribute type {"short-paragraph-line-double"}
                            else
                                attribute type {"short-paragraph-line"}
                    }
MRodz's avatar
MRodz committed
589
                else if($node/ancestor::tei:zone[@type = "illustration"]) then
MRodz's avatar
MRodz committed
590
                    element {QName("http://www.tei-c.org/ns/1.0", $node/name())}{
Michelle Rodzis's avatar
Michelle Rodzis committed
591
592
                        $node/@*,
                        fontaneSimple:transform($nodes/node())
MRodz's avatar
MRodz committed
593
                    }
594
                else
MRodz's avatar
MRodz committed
595
596
                    ()
            else
597
                fontaneSimple:copy-element($node)
598

MRodz's avatar
MRodz committed
599
        case element(tei:note) return
600
            if($node/@type = "authorial"
601
            and not($node/@subtype = "footnote")) then
MRodz's avatar
MRodz committed
602
                ()
603
            else
604
                fontaneSimple:copy-element($node)
605

MRodz's avatar
MRodz committed
606
607
608
609
610
611
        case element(tei:certainty) return
            element {QName("http://www.tei-c.org/ns/1.0", "note")}{
                attribute type {"editorial"},
                attribute subtype {"certainty"},
                $node/@cert,
                $node/@target,
612
                fontaneSimple:transform($node/node())
MRodz's avatar
MRodz committed
613
            }
614

MRodz's avatar
MRodz committed
615
        case element(tei:figDesc) return
616
            fontaneSimple:copy-element($node)
617

MRodz's avatar
MRodz committed
618
        case element(tei:ref) return
619
            fontaneSimple:copy-element($node)
620

MRodz's avatar
MRodz committed
621
        case element(tei:space) return
622
            fontaneSimple:copy-element($node)
623

MRodz's avatar
MRodz committed
624
        case element(tei:choice) return
625
            fontaneSimple:copy-element($node)
626

MRodz's avatar
MRodz committed
627
        case element(tei:abbr) return
628
            fontaneSimple:copy-element($node)
629

MRodz's avatar
MRodz committed
630
        case element(tei:expan) return
631
            fontaneSimple:copy-element($node)
632
633
634
635
636
637
            
        case element(tei:sic) return
            fontaneSimple:copy-element($node)     
            
        case element(tei:corr) return
            fontaneSimple:copy-element($node)
638

MRodz's avatar
MRodz committed
639
        case element(tei:rs) return
MRodz's avatar
MRodz committed
640
641
            let $index-type := substring-before($node/@ref, ":")
            return
MRodz's avatar
MRodz committed
642
                element tei:rs {
MRodz's avatar
MRodz committed
643
                    $node/@*,
MRodz's avatar
MRodz committed
644
                    fontaneSimple:make-index-infos($node, $index-type),
MRodz's avatar
MRodz committed
645
                    fontaneSimple:transform($node/node())
MRodz's avatar
MRodz committed
646
                }
647

MRodz's avatar
MRodz committed
648
        case element(tei:date) return
649
            element {QName("http://www.tei-c.org/ns/1.0", $node/name())}{
650
651
                (if($node/@when-iso) then
                    attribute when {$node/@when-iso}
652
653
                else
                    ()),
654
655
                (if($node/@from-iso) then
                    attribute from {$node/@from-iso}
656
657
                else
                    ()),
658
659
                (if($node/@to-iso) then
                    attribute to {$node/@to-iso}
Michelle Rodzis's avatar
Michelle Rodzis committed
660
                else
661
                    ()),
Michelle Rodzis's avatar
Michelle Rodzis committed
662
663
                (if($node/@notAfter-iso) then
                    attribute notAfter {$node/@notAfter-iso}
664
                else
665
                    ()),
Michelle Rodzis's avatar
Michelle Rodzis committed
666
                $node/(@* except (@when-iso, @to-iso, @from-iso, @notAfter-iso)),
667
                fontaneSimple:transform($node/node())
668
            }
669

670
        case element(tei:ptr) return
671
            ()
672

MRodz's avatar
MRodz committed
673
        default return
674
            fontaneSimple:transform($node/node())
675
};
676
677
678
679
680
681
682
683
684
685

(:~
 : Takes a given element over as is since it is compliant to TEI simplePrint.
 :
 : @author Michelle Rodzis
 : @param $node the current text node
 : @return node() a copy of the current node
 :)
declare function fontaneSimple:copy-element($node as node()) as node() {
    element {QName("http://www.tei-c.org/ns/1.0", $node/name())}{
Michelle Rodzis's avatar
Michelle Rodzis committed
686
687
688
689
690
        $node/(@* except @rend),
        if($node/@rend) then
            attribute rendition {$node/@rend}
        else
            (),
691
692
693
694
695
696
697
698
699
700
701
702
703
704
        fontaneSimple:transform($node/node())
    }
};

(:~
 : Creates a tei:head with an @rendition and a font-size, if available.
 :
 : @author Michelle Rodzis
 : @param $node the current tei:line, tei:zone or tei:seg node
 : @return element(tei:head)
 : :)
declare function fontaneSimple:make-head($node as node()) as element(tei:head) {
    element tei:head {
        (if($node/descendant::tei:seg[matches(@style, "font-size")]) then
MRodz's avatar
MRodz committed
705
            attribute style {simpleHelpers:get-font-size($node)}
706
        else
MRodz's avatar
MRodz committed
707
            attribute style {"default"}
708
        ),
MRodz's avatar
MRodz committed
709
        attribute type {"former-" || $node/name()},
710
711
712
713
        $node/@subtype,
        (if($node/@rendition) then
            $node/@rendition
        else
MRodz's avatar
MRodz committed
714
715
716
717
718
            ()),         
        (if($node/@rend) then
            $node/@rend
        else
            ()),        
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
        fontaneSimple:transform($node/node())
    }
};

(:~
 : Creates a tei:div.
 :
 : @author Michelle Rodzis
 : @param $node the current tei:surface node
 : @return element(tei:div)
 : :)
declare function fontaneSimple:make-div($node as element(tei:surface))
as element(tei:div) {
    element tei:div{
        $node/(@* except (@facs, @n, @attachment, @subtype, @ulx, @uly, @lrx, @lry, @points)),
        fontaneSimple:transform($node/node())
    }
};

(:~
 : Creates a new tei:seg with all relevant rendition information.
 :
 : @author Michelle Rodzis
 : @param $node the current tei:zone, tei:line, or tei:seg element
 : @return element(tei:seg)
 :)
declare function fontaneSimple:make-seg-with-rendition($node as element(*))
as element(tei:seg) {
    element tei:seg {
        attribute rendition {simpleHelpers:filter-rendition($node)},
        $node/(@* except (@style, @rendition)),
750
751
752
753
        (if($node[self::tei:line or self::tei:zone]) then
            attribute unit {$node/name()}
        else
            ()),
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
        fontaneSimple:transform($node/node())
    }
};


(:~
 : Creates a tei:pb.
 :
 : @author Michelle Rodzis
 : @param $node the current tei:surface node
 : @return element(tei:pb)
 :)
declare function fontaneSimple:make-pb($node as element(tei:surface))
as element(tei:pb) {
    element {QName("http://www.tei-c.org/ns/1.0", "pb")}{
        $node/@n
    }
};


(:~
 : Creates a tei:pb with a type instead of a @n representing the pagination.
 : This function is mainly used to separate the inner and outer book covers from
 : each other.
 :
 : @author Michelle Rodzis
 : @param $node the current tei:surface node
 : @return element(tei:pb)
 :)
declare function fontaneSimple:make-pb-with-type($type as xs:string)
as element(tei:pb) {
    element {QName("http://www.tei-c.org/ns/1.0", "pb")}{
        attribute type {$type}
    }
};

declare function fontaneSimple:enhance-handshift($node as element(tei:handShift))
791
as element(tei:milestone) {
792
793
    let $prev-hand := $node/preceding::tei:handShift[@new][1]
    return
794
795
796
797
798
799
        element tei:milestone {
            attribute type {"handshift"},
            attribute subtype {if($node/@new) then $node/@new else $prev-hand/@new},
            attribute rend {concat("script(", (if($node/@script) then $node/@script else ""), ") ",
                "medium(", (if($node/@medium) then $node/@medium else ""), ")")},
            $node/(@* except (@new, @medium, @script))
800
801
        }
};
802
803


804
declare function fontaneSimple:mark-intervention($node as element(*)) 
805
806
as element(tei:seg) {
    element tei:seg {
807
808
809
810
811
812
        if($node[self::tei:lb]) then
            attribute type {"missing-hyphen"}
        else if($node[self::tei:surplus]) then
            attribute type {"surplus"}
        else
            attribute type {"reduplication"},
813
            
814
        <tei:hi xmlns="http://www.tei-c.org/ns/1.0">‹</tei:hi>,
815
        
816
817
818
819
        if($node[self::tei:lb]) then
            simpleHelpers:find-chars($node)
        else
            fontaneSimple:transform($node/node()),
820
            
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
        <tei:hi xmlns="http://www.tei-c.org/ns/1.0">›</tei:hi>
    }
};


declare function fontaneSimple:mark-missing-hyphen($node as element(tei:lb)) as
element(tei:seg) {
    element tei:seg {
        attribute type {"missing-hyphen"},
        <tei:hi xmlns="http://www.tei-c.org/ns/1.0">‹</tei:hi>,
        simpleHelpers:find-chars($node),
        <tei:hi xmlns="http://www.tei-c.org/ns/1.0">›</tei:hi>
    }
};


(:~ In this first serialization step the beginning and end of line groups are 
 : simply marked with milestones, which are expanded to a full tei:lg in the 
 : second serialization step. :)
declare function fontaneSimple:mark-linegroup-beginning() as
element(tei:milestone) {
    element tei:milestone {
        attribute unit {"start-lg"}
    }
};

declare function fontaneSimple:mark-linegroup-end() as
element(tei:milestone) {
    element tei:milestone {
        attribute unit {"end-lg"}
851
    }
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
};

declare function fontaneSimple:has-pb-inbetween($node as node(), 
$corresp as node()*) as xs:boolean {
    if($node/following::tei:surface[. << $corresp]) then
        true()
    else
        false()
};

declare function fontaneSimple:separates-corresp-nodes($node as element(tei:surface)) 
as xs:boolean {
    some $prev in $node/preceding::*[@next]
    satisfies contains($prev/@next, $node/descendant::*/@xml:id)
        or contains($prev/@next, $node/following::*/@xml:id)
MRodz's avatar
MRodz committed
867
868
};

MRodz's avatar
MRodz committed
869
870
declare function fontaneSimple:make-index-infos($node as element(tei:rs), 
$index-type as xs:string) as element()* {
MRodz's avatar
MRodz committed
871
872
873
874
875
876
    let $refs := tokenize($node/@ref, " ")
    let $no-of-refs := count($refs)
    return
        for $iii in 1 to $no-of-refs
        let $ref := $refs[$iii]
        return
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
            element tei:index {
                attribute indexName {$index-type},
                element tei:term {
                    attribute type {"main"},
                    index-info:get-info-about($index-type, $ref, "regular-name")
                },
                    switch ($index-type)
                        case "eve" return 
                            let $place := index-info:get-info-about($index-type, $ref, "place")
                            return
                                fontaneSimple:make-term("place", $place)
                        case "org" return 
                            ()
                            
                        case "plc" return
                            let $subref := index-info:get-info-about($index-type, $ref, "subref-of")
                            return
                                fontaneSimple:make-term("subref-of", $subref)
                                
                        case "psn" return
                            let $birth := index-info:get-info-about($index-type, $ref, "birth")
                            let $death := index-info:get-info-about($index-type, $ref, "death")
                            let $occupation := index-info:get-info-about($index-type, $ref, "occupation")
                            return
                                (fontaneSimple:make-term("birth", $birth),
                                fontaneSimple:make-term("death", $death),
                                fontaneSimple:make-term("occupation", $occupation))
                                
                        case "wrk" return 
                            ()
                            
                        default return 
                            ()
            }
};

declare function fontaneSimple:make-term($type as xs:string, $info as xs:string) 
as element(tei:term)* {
    if($info != "") then
        element tei:term {
            attribute type {$type},
            $info
        }
    else
        ()
922
};