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

(:~ 
Michelle Rodzis's avatar
Michelle Rodzis committed
4
5
6
7
 : 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
 : Text" (edited text) view on the website and the book and represent the latest 
 : layer of text.
MRodz's avatar
MRodz committed
8
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

MRodz's avatar
MRodz committed
16

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

20
import module namespace config="http://textgrid.de/ns/SADE/config" at "../config/config.xqm";
MRodz's avatar
MRodz committed
21
import module namespace console="http://exist-db.org/xquery/console";
22
import module namespace simpleHelpers="http://fontane-nb.dariah.eu/teisimplehelpers" at "teisimplehelpers.xqm";
MRodz's avatar
MRodz committed
23
import module namespace functx = "http://www.functx.com";
MRodz's avatar
MRodz committed
24
25
26
27
28
29
30

(:~ 
 : The main function initiates the transformation of a given notebook.
 : 
 : TODO: adapt to several input files?
 : 
 : :)
31
declare function fontaneSimple:main($file as xs:string) as xs:string? {
MRodz's avatar
MRodz committed
32
33
34
35
36
37
38
  let $doc := 
    try {
      (doc("/db/sade-projects/textgrid/data/xml/data/" || $file))
    } catch * {
      (console:log("It was not possible to open the requested file " || $file))
    }
    
MRodz's avatar
Fix #23    
MRodz committed
39
40
    let $front-covers := $doc//tei:sourceDoc/tei:surface[contains(@n, "front_cover")]
    let $back-covers := $doc//tei:sourceDoc/tei:surface[contains(@n, "back_cover")]
MRodz's avatar
MRodz committed
41
    let $content := $doc//tei:sourceDoc/tei:surface[not(contains(@n, "cover") 
MRodz's avatar
MRodz committed
42
        or matches(@n, "spine"))]
MRodz's avatar
MRodz committed
43
    
44
    let $tei := <TEI xmlns="http://www.tei-c.org/ns/1.0">
MRodz's avatar
MRodz committed
45
        {$doc//tei:teiHeader}
MRodz's avatar
MRodz committed
46
        <text>
47
48
49
            <front>{fontaneSimple:transform($front-covers)}</front>
            <body>{fontaneSimple:transform($content)}</body>
            <back>{fontaneSimple:transform($back-covers)}</back>
MRodz's avatar
MRodz committed
50
        </text>
MRodz's avatar
MRodz committed
51
      </TEI>
52
    return xmldb:store("/db/apps/SADE/resources/xml/", "tei-simple.xml", $tei)
MRodz's avatar
MRodz committed
53
54
};

55
(:~
MRodz's avatar
MRodz committed
56
57
58
59
60
61
62
63
 : Recursivly iterates the passed nodes and converts them according to the 
 : requirements for the "Edierter Text". 
 : 
 : The requirements are part of the encoding documentation, c.f.
 : https://fontane-nb.dariah.eu/doku.html.
 : 
 : @author Michelle Rodzis
 : @param $nodes
Michelle Rodzis's avatar
Michelle Rodzis committed
64
 : @return $node()* a TEI simplePrint element
MRodz's avatar
MRodz committed
65
 :)
66
declare function fontaneSimple:transform($nodes as node()*) as node()* {
MRodz's avatar
MRodz committed
67
68
69
    for $node in $nodes
      return
        typeswitch ($node)
MRodz's avatar
MRodz committed
70
        case text() return
71
            simpleHelpers:prepare-text($node)
MRodz's avatar
MRodz committed
72
73
74
75
76
        
        case element(tei:lb) return
            if($node[@break = "keepHyphen"]) then
                ()
            else
77
                simpleHelpers:copy-element($node)
MRodz's avatar
MRodz committed
78
79
80
81
82
                
        case element(tei:g) return
            if($node[@ref = "#vds"]) then
                ()
            else if($node/@ref ="#rth" or $node/@ref ="#hb") then
83
                simpleHelpers:copy-element($node)
MRodz's avatar
MRodz committed
84
            else
85
                fontaneSimple:transform($node/node())
86
                
MRodz's avatar
MRodz committed
87
88
        case element(tei:del) return
            if($node/parent::tei:restore) then
89
                fontaneSimple:transform($node/node())
MRodz's avatar
MRodz committed
90
            else if($node/descendant::tei:restore) then
91
                fontaneSimple:transform($node/descendant::tei:restore)
MRodz's avatar
MRodz committed
92
            else
MRodz's avatar
MRodz committed
93
                ()
94
                
MRodz's avatar
MRodz committed
95
96
97
98
99
        case element(tei:restore) return
            if(count($node/child::*) = 1 and $node/child::tei:del
            and $node/ancestor::tei:del) then
                ()
            else
100
                fontaneSimple:transform($node/node())
101
                
MRodz's avatar
MRodz committed
102
103
104
        case element(tei:retrace) return
            if($node/@rend) then
                element tei:seg {
Michelle Rodzis's avatar
Michelle Rodzis committed
105
                    attribute rendition {$node/@rend},
106
                    fontaneSimple:transform($node/node())
MRodz's avatar
MRodz committed
107
108
                }
            else
109
                fontaneSimple:transform($node/node())
110
111
                
        case element(tei:add) return
112
113
            if($node/@type = "edited_text" 
            or $node/child::tei:seg[@type = "multiphrase"]) then
114
                simpleHelpers:copy-element($node)
MRodz's avatar
MRodz committed
115
116
            else if($node/@cause ="catchword" or $node/@cause ="unclear") then
                ()
MRodz's avatar
MRodz committed
117
            else if($node/@rend ="|") then
118
                fontaneSimple:transform($node/node())
119
            else if(not($node/@xml:id)) then
120
                fontaneSimple:transform($node/node())
121
            else if(simpleHelpers:is-transposed($node)) then
122
123
                let $corresp := //tei:metamark[matches(@target, $node/@xml:id)]
                return
124
125
                    (fontaneSimple:transform($corresp/node()),
                    fontaneSimple:transform($node/node()))
126
            else
127
                fontaneSimple:transform($node/node())
128
129
130
                
        case element(tei:addSpan) return
            if($node/@type = "edited_text") then
131
                simpleHelpers:copy-element($node)
132
133
134
            else
                ()       
                
135
136
        case element(tei:fw) return
            ()
137
                
138
139
140
        case element(tei:line) return
            if(count($node/*) = 1 and $node/child::tei:fw) then
                ()
MRodz's avatar
MRodz committed
141
            else if($node/@type = "heading") then
142
                simpleHelpers:make-head($node)
MRodz's avatar
MRodz committed
143
                
144
145
146
147
148
            else if((simpleHelpers:has-valid-style($node)
            or matches($node/@rendition, "black_letter")
            or matches($node/@rendition, "roman"))
            and simpleHelpers:has-valid-text($node)) then
                simpleHelpers:make-seg-with-rendition($node)
MRodz's avatar
MRodz committed
149
                
150
            else if(not($node/@type = "item")) then
151
                fontaneSimple:transform($node/node())
152
153
            else if($node/@type = "item" and not($node/@xml:id)) then
                element tei:item {
154
                    fontaneSimple:transform($node/node())
155
156
                }
            else if($node/@type = "item" 
157
            and simpleHelpers:is-transposed($node)) then
MRodz's avatar
MRodz committed
158
                ()            
159
            else
160
                fontaneSimple:transform($node/node())
161
                        
162
        case element(tei:handShift) return
163
            if($node/@new) then
164
165
166
                if(simpleHelpers:is-hand-valid($node)
                and not(simpleHelpers:is-prev-valid-hand-same($node))) then
                    simpleHelpers:copy-element($node)
167
168
                else
                    ()
169
            else
170
                (: tei:simpleHelpers:copy-element($node)ft without @new denote the duct 
171
                of the current writer or a change of writing medium :)
172
173
                if(simpleHelpers:is-hand-valid($node/preceding::tei:handShift[@new][1])) then
                    simpleHelpers:copy-element($node)
174
175
176
                else
                    ()

177
178
        case element(tei:stamp) return
            ()
179
                
180
181
182
183
184
        case element(tei:seg) return
            if(count($node/*) = 1 and 
            ($node/child::tei:stamp or $node/child::tei:metamark[@function = "caret"]))
                then
                    ()
MRodz's avatar
MRodz committed
185
                    
MRodz's avatar
MRodz committed
186
            else if($node/@type = "heading") then
187
                simpleHelpers:make-head($node)
MRodz's avatar
MRodz committed
188
                
189
190
            else if(matches($node/@style, "underline") 
            and not(matches($node/@style, "vertical-align"))) then
191
                fontaneSimple:transform($node/node())
MRodz's avatar
MRodz committed
192
                
193
194
195
196
197
            else if((simpleHelpers:has-valid-style($node)
            or matches($node/@rendition, "black_letter")
            or matches($node/@rendition, "roman"))
            and simpleHelpers:has-valid-text($node)) then
                simpleHelpers:make-seg-with-rendition($node)     
MRodz's avatar
MRodz committed
198
                
MRodz's avatar
MRodz committed
199
200
201
202
            else if($node/@type = "initials" 
            or $node/@type = "monogram" 
            or $node/@type = "multiphrase"
            or $node/@xml:lang)
203
                then
204
                    simpleHelpers:copy-element($node)
MRodz's avatar
MRodz committed
205
                    
206
207
            else if($node/@type = "auction_number" 
            or $node/@type = "cancel"
MRodz's avatar
MRodz committed
208
209
            or $node/@type = "abort"
            or $node/@function ="unknown")
210
211
                then
                    ()
MRodz's avatar
MRodz committed
212
                    
213
            else
214
                fontaneSimple:transform($node/node())
MRodz's avatar
MRodz committed
215
216
                    
        case element(tei:hi) return
217
            simpleHelpers:copy-element($node)
218
        
219
220
        (: TODO if $node/@type = "highlighted" then make 
        a hi[@type = "vertical-mark"] in the second stage of creating the
221
        simple format. use simpleHelpers:get-xml-chunk($node) for this.:)
222
223
        case element(tei:mod) return
            if($node/@type = "highlighted"
224
225
            and simpleHelpers:is-hand-contemporary($node/@hand)) then
                simpleHelpers:copy-element($node)
226
227
228
            else
                fontaneSimple:transform($node/node())
        
229
        case element(tei:anchor) return
230
            simpleHelpers:copy-element($node)
231
                        
232
        case element(tei:surface) return 
MRodz's avatar
MRodz committed
233
            if(matches($node/@n, "cover")) then
234
235
                simpleHelpers:make-pb-with-type($node/@n)
            else if(simpleHelpers:is-page($node)
MRodz's avatar
MRodz committed
236
            and $node/@type = "clipping") then
237
                (simpleHelpers:make-pb($node),
MRodz's avatar
MRodz committed
238
239
                (if(not($node/@subtype = "Kalenderblatt"
                or $node/@subtype = "Zeitungsausschnitt_Fragment")) then
240
                    fontaneSimple:transform($node/node())
MRodz's avatar
MRodz committed
241
242
                else
                    ()))
243
244
            else if(simpleHelpers:is-page($node)) then
                (simpleHelpers:make-pb($node),
245
                fontaneSimple:transform($node/node()))
246
            else if($node/@type = "label" and
247
248
249
            (contains($node/@subtype, "Fontane")
            or contains($node/@subtype, "Hersteller"))    
            ) then
250
                simpleHelpers:make-div($node)
MRodz's avatar
MRodz committed
251
252
            else
                ()
MRodz's avatar
MRodz committed
253
254
255
256
        
        case element(tei:milestone) return
            if($node/@unit = "illustration") then
                ()
257
(:            else if($node/@unit = "section") then:)
258
(:                simpleHelpers:make-section($node):)
259
260
(:            else if($node/@unit = "pararaph") then:)
(:                fontaneSimple:make-paragraph($node):)
MRodz's avatar
MRodz committed
261
            else
262
                simpleHelpers:copy-element($node)
263
264
                    
        case element(tei:gap) return
265
            simpleHelpers:copy-element($node)
266
                
267
268
269
270
271
272
        case element(tei:metamark) return
            if($node/@function = "integrate" 
            or $node/@function = "authorial_note") then
                element tei:ab {
                    $node/@*
                }
273
274
275
276
277
278
            else if($node/@function = "placeholder" 
            or $node/@function ="etc."
            or $node/@function ="caret"
            or $node/@function ="footnotes"
            or $node/@function ="ellipsis"
            or $node/@function = "paragraph") then
MRodz's avatar
MRodz committed
279
280
                element tei:ab {
                    attribute type {$node/@function},
281
                    fontaneSimple:transform($node/node())
282
                }            
283
284
            else
                ()
285
286
287
288
289
        
        (: TODO: check if correct :)
        case element(tei:surplus) return
            ()
            
MRodz's avatar
MRodz committed
290
291
292
293
294
295
        case element(tei:zone) return
            if(matches($node/@style, "border-style:solid") 
            and not(matches($node/@style, "border-radius"))
            and not($node/@rend = "border-style:house")) then
                element tei:div {
                    attribute type {"frame"},
296
                    fontaneSimple:transform($node/node())
MRodz's avatar
MRodz committed
297
                }
MRodz's avatar
MRodz committed
298
                
MRodz's avatar
MRodz committed
299
            else if(matches($node/@rend, "border-bottom-style:brace")) then
300
                (fontaneSimple:transform($node/node()),
MRodz's avatar
MRodz committed
301
302
                element tei:ab {
                    attribute type {"bottom-brace"}
MRodz's avatar
MRodz committed
303
304
                })  
                
MRodz's avatar
MRodz committed
305
306
            else if($node/@type = "cancel") then
                ()
MRodz's avatar
MRodz committed
307
                
MRodz's avatar
MRodz committed
308
309
310
311
            else if($node/@type = "marked_off") then
                element tei:seg {
                    $node/@type,
                    $node/@xml:id,
312
                    fontaneSimple:transform($node/node())
MRodz's avatar
MRodz committed
313
                }
MRodz's avatar
MRodz committed
314
                
MRodz's avatar
MRodz committed
315
316
            else if($node/@type = "highlighted") then
                if($node/child::tei:zone[@type = "highlighted"]) then
317
                    fontaneSimple:transform($node/node())
MRodz's avatar
MRodz committed
318
319
320
                else
                    element tei:hi {
                        attribute type {"vertical-mark"},
321
                        fontaneSimple:transform($node/node())
MRodz's avatar
MRodz committed
322
                    }
MRodz's avatar
MRodz committed
323
                    
324
325
            else if($node/@type = "illustration"
            or $node/@type = "printed_illustration") then
MRodz's avatar
MRodz committed
326
327
328
329
330
331
332
333
334
335
336
337
338
                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
                                attribute rendition {"margin-left:" || $node/@ulx 
                                || "cm; " || "margin-top:" || $node/@uly || "cm"}
                            else
                                ()
                            )
                        ),
339
                        fontaneSimple:transform($node/node())
MRodz's avatar
MRodz committed
340
341
342
                    }
                else 
                    ()
MRodz's avatar
MRodz committed
343
                    
344
345
            else if($node/parent::tei:zone/@type = "illustration"
            or $node/parent::tei:zone/@type = "printed_illustration") then
MRodz's avatar
MRodz committed
346
347
348
349
                element {QName("http://www.tei-c.org/ns/1.0", "seg")}{
                    attribute type {"caption"},
                    attribute rendition {"margin-left:" || $node/@ulx || "cm; " 
                        || "margin-top:" || $node/@uly || "cm"},
350
                    fontaneSimple:transform($node/node())
MRodz's avatar
MRodz committed
351
                }
MRodz's avatar
MRodz committed
352
                
MRodz's avatar
MRodz committed
353
            else if($node/@type = "heading") then
354
                simpleHelpers:make-head($node)              
MRodz's avatar
MRodz committed
355
                
MRodz's avatar
MRodz committed
356
357
            else if($node/@type = "list" or $node/@type = "item") then
                element {QName("http://www.tei-c.org/ns/1.0", $node/@type)}{
358
                    $node/(@* except (@type, @ulx, @uly, @lrx, @lry, @rotate)),
359
                    fontaneSimple:transform($node/node())
MRodz's avatar
MRodz committed
360
                }            
MRodz's avatar
MRodz committed
361
                
MRodz's avatar
MRodz committed
362
363
            else if($node/@type = "legend") then
                element {QName("http://www.tei-c.org/ns/1.0", "div")}{
364
365
366
367
368
369
                    (if($node/@style 
                    or $node/@rendition) then
                        attribute rendition {simpleHelpers:filter-rendition($node)}
                    else
                        ()),
                    $node/(@* except (@rendition, @style)),
370
                    fontaneSimple:transform($node/node())
MRodz's avatar
MRodz committed
371
372
                }    
            
373
374
375
376
377
            else if((simpleHelpers:has-valid-style($node)
            or matches($node/@rendition, "black_letter")
            or matches($node/@rendition, "roman"))
            and simpleHelpers:has-valid-text($node)) then
                simpleHelpers:make-seg-with-rendition($node)
MRodz's avatar
MRodz committed
378
                
379
            else if(not($node/@xml:id)) then
380
                fontaneSimple:transform($node/node())
MRodz's avatar
MRodz committed
381
                
382
            else if($node/@xml:id and simpleHelpers:is-transposed($node)) then
383
                ()
MRodz's avatar
MRodz committed
384
                
MRodz's avatar
MRodz committed
385
            else
386
                fontaneSimple:transform($node/node())
387
                
MRodz's avatar
MRodz committed
388
        case element(tei:figure) return
389
390
391
392
393
394
            if(count($node/child::*) = 1 and $node/child::tei:figDesc) then
                (: genealogy lines probably shouldn't be displayed, but I still have to 
                check that. in case they should be serialized, I leave the code :)
(:                if(matches($node/descendant::tei:ref, "Stammbaumverbindungslinie")) then:)
(:                    element tei:seg {:)
(:                        $node/@*,:)
395
(:                        fontaneSimple:transform($node/node()):)
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
(:                    }:)
(:                else if(matches($node/descendant::tei:ref, "Schlusslinie")):)
                if(matches($node/descendant::tei:ref, "Schlusslinie"))
                    then
                        element tei:ab {
                            switch ($node/descendant::tei:ref)
                                case "horizontale einfache Schlusslinie" return 
                                    attribute type {"long-end-line"}                                    
                                case "Schlusslinie; horizontale Halbschleife von links oben nach rechts" return 
                                    attribute type {"long-end-line"}
                                case "horizontale einfache Schlusslinie (gewellt)" return 
                                    attribute type {"long-end-line-wavy"}
                                case "Schlusslinien; horizontale Schleife von links oben nach rechts unten" return 
                                    attribute type {"bottom-brace-short"}
                                default return 
                                    attribute type {"end-line"}  
                        }
                else if(matches($node/descendant::tei:ref, "Absatzlinie")
                (: in case of double paragraph lines the single lines are 
                encoded with "oberer" resp. "unterer Teil", but we only 
                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
426
427
428
429
                else if($node/parent::tei:zone[@type = "illustration"]) then
                    element {QName("http://www.tei-c.org/ns/1.0", $node/name())}{
                        $node/@*
                    }
430
                else
MRodz's avatar
MRodz committed
431
432
                    ()
            else
433
                simpleHelpers:copy-element($node)
434
                    
MRodz's avatar
MRodz committed
435
        case element(tei:note) return
436
437
            if($node/@type = "authorial" 
            and not($node/@subtype = "footnote")) then
MRodz's avatar
MRodz committed
438
439
                ()
            else 
440
                simpleHelpers:copy-element($node)
MRodz's avatar
MRodz committed
441
442
443
444
445
446
447
                
        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,
448
                fontaneSimple:transform($node/node())
MRodz's avatar
MRodz committed
449
            }
MRodz's avatar
MRodz committed
450
                    
MRodz's avatar
MRodz committed
451
        case element(tei:figDesc) return
452
            simpleHelpers:copy-element($node)
453
            
MRodz's avatar
MRodz committed
454
        case element(tei:ref) return
455
            simpleHelpers:copy-element($node)
MRodz's avatar
MRodz committed
456
457
        
        case element(tei:space) return
458
            simpleHelpers:copy-element($node)
MRodz's avatar
MRodz committed
459
460
            
        case element(tei:choice) return
461
            simpleHelpers:copy-element($node)
MRodz's avatar
MRodz committed
462
463
            
        case element(tei:abbr) return
464
            simpleHelpers:copy-element($node)
MRodz's avatar
MRodz committed
465
466
            
        case element(tei:expan) return
467
            simpleHelpers:copy-element($node)        
MRodz's avatar
MRodz committed
468
469
            
        case element(tei:rs) return
470
            simpleHelpers:copy-element($node)        
MRodz's avatar
MRodz committed
471
472
            
        case element(tei:date) return
473
            element {QName("http://www.tei-c.org/ns/1.0", $node/name())}{
474
475
476
                (if($node/@when-iso) then
                    attribute when {$node/@when-iso}
                else 
477
478
479
480
481
                    ()), 
                (if($node/@from-iso) then
                    attribute from {$node/@from-iso}
                else 
                    ()),                    
482
483
484
485
                (if($node/@to-iso) then
                    attribute to {$node/@to-iso}
                else 
                    ()),
486
                $node/(@* except (@when-iso, @to-iso, @from-iso)),
487
                fontaneSimple:transform($node/node())
488
            }
489
490
491
492
            
        case element(tei:ptr) return
            let $target-id := substring-after($node/@target, "#")
            let $target := $node/ancestor::tei:TEI//*[matches(@xml:id, $target-id)]
493
            let $stripped-target := simpleHelpers:strip-element($target)
494
            return fontaneSimple:transform($stripped-target)
MRodz's avatar
MRodz committed
495
            
MRodz's avatar
MRodz committed
496
        default return
497
            fontaneSimple:transform($node/node())
498
};