tei2teisimple.xqm 20 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 fontaneSimpleHelpers="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
            fontaneSimpleHelpers: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
                fontaneSimpleHelpers: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
                fontaneSimpleHelpers: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
                fontaneSimpleHelpers: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
121
                fontaneSimple:transform($node/node())
            else if(fontaneSimpleHelpers: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
                fontaneSimpleHelpers: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
                fontaneSimpleHelpers:make-head($node)
MRodz's avatar
MRodz committed
143
144
145
146
147
                
            else if(matches($node/@rendition, "black_letter")
            or matches($node/@rendition, "roman")) then
                fontaneSimpleHelpers:make-seg-with-rendition($node)
                
148
            else if(not($node/@type = "item")) then
149
                fontaneSimple:transform($node/node())
150
151
            else if($node/@type = "item" and not($node/@xml:id)) then
                element tei:item {
152
                    fontaneSimple:transform($node/node())
153
154
                }
            else if($node/@type = "item" 
155
            and fontaneSimpleHelpers:is-transposed($node)) then
MRodz's avatar
MRodz committed
156
                ()            
157
            else
158
                fontaneSimple:transform($node/node())
159
                        
160
        case element(tei:handShift) return
161
            if($node/@new) then
162
163
164
                if(fontaneSimpleHelpers:is-hand-valid($node)
                and not(fontaneSimpleHelpers:is-prev-valid-hand-same($node))) then
                    fontaneSimpleHelpers:copy-element($node)
165
166
                else
                    ()
167
            else
168
                (: tei:fontaneSimpleHelpers:copy-element($node)ft without @new denote the duct 
169
                of the current writer or a change of writing medium :)
170
171
                if(fontaneSimpleHelpers:is-hand-valid($node/preceding::tei:handShift[@new][1])) then
                    fontaneSimpleHelpers:copy-element($node)
172
173
174
                else
                    ()

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