diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..c0bb7e6b5 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,9 @@ +version: 2 +updates: + # Maintain dependencies for GitHub Actions + - package-ecosystem: 'github-actions' + directory: '/' + schedule: + interval: 'weekly' + labels: + - 'gh actions dependencies' diff --git a/.github/workflows/docker-ci.yml b/.github/workflows/docker-ci.yml index cc386f981..a46ad5129 100644 --- a/.github/workflows/docker-ci.yml +++ b/.github/workflows/docker-ci.yml @@ -1,10 +1,10 @@ -name: Docker build PR +name: Build on: -# push: -# branches: [ main ] + push: + branches: [ develop ] pull_request: - types: [opened, edited, reopened] + types: [ opened, synchronize, reopened ] branches: [ develop, main ] env: @@ -13,26 +13,29 @@ env: jobs: build: - + name: Build Edirom Online runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - name: Build Edirom Online from ${{ GITHUB_REF }} - run: docker run --rm -v `pwd`:/app -w /app --entrypoint ./build.sh bwbohl/sencha-cmd - - uses: actions/upload-artifact@v2 + - name: Chekout repository + uses: actions/checkout@v4 + + - name: Get short sha + uses: benjlevesque/short-sha@v2.2 + id: short-sha with: - name: EdiromOnline_${{ GITHUB_REF }}.zip - path: build-xar/EdiromOnline*.xar - if-no-files-found: error # 'warn' or 'ignore' are also available, defaults to `warn` + length: 7 + + - name: Build Edirom Online from ${{ github.ref }} at ${{ github.sha }} + run: docker run --rm -v $(pwd):/app -w /app --entrypoint ./build.sh bwbohl/sencha-cmd -# deploy: -# needs: build -# runs-on: ubuntu-latest -# steps: -# - name: deploy -# uses: jaapio/keelsh-deploy@master -# with: -# keelBaseUrl: http://keel.euryanthe.de -# image: 'bazga/existdb' -# tag: 'latest' + - name: Upload Artifacts to action run + if: github.repository == 'Edirom/Edirom-Online' + uses: actions/upload-artifact@v4.3.0 + with: + # The name that the artifact will be made available under + name: EdiromOnline_${{ steps.short-sha.outputs.sha }}.zip + # The path to retrieve the artifact + path: ${{ github.workspace }}/build-xar/Edirom-Online-*.xar + if-no-files-found: warn # 'warn' or 'ignore' are also available, defaults to `warn` + #optional retention-days: 1 to 90 diff --git a/.gitignore b/.gitignore index d5b603f5d..ef633cde5 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ Thumbs.db /tmp *.xpr local.properties +.idea/ diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 000000000..afe8f047f --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "packages/eoTheme/resources/fonts/euryanthe"] + path = packages/eoTheme/resources/fonts/euryanthe + url = https://github.com/Edirom/EuryantheFont diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..183f8d0ae --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,89 @@ +# Edirom Online Contributing Guidelines + +# General Guidelines + +* do not combine code-linting and content work in one commit + +## Whitespace handling + +1. Use whitespaces, not tabs to indent code +2. Close file with a newline character + + +# XQuery + +## xqDoc + +We use [xqDoc](https://xqdoc.org) for documenting the XQueries in this repository. Please refer to the section [xqDoc Comments](https://xqdoc.org/xqdoc_comments_doc.html) of the xqDoc-website for details on formatting the documentation comment blocks. + +* XQuery modules must have a library module xqDoc comment preceding the module declaration. +* Function declarations must have a library module xqDoc function comment preceding the function. + +## XQuery document structure + +### XQuery version + +```xquery +xquery version 3.1; +``` + +### License Statement + +```xquery +(: +For LICENSE-Details please refer to the LICENSE file in the root directory of this repository. +:) +``` + +### File Header + +1. `declare namespace` statements + * sort alphabetically by prefix +2. `import module namespace` statements of registered modules + * sort alphabetically by prefix +3. `import module namespace` statements of custom modules + * sort alphabetically by prefix + * Always use relative URIs for `import module namespace` statements that import for modules not registered with eXist-db. + +### Declare variables + +* Use `declare variable` statements for all required external parameters + +### Function declarations + +* functions have to be preceded by an xqDoc comment + +### XQuery body + +* Strings: escape with U+00027 APOSTROPHE: `'` + + +# Javascript + +## AJAX calls + +The class `EdiromOnline.controller.AJAXController` provides a central method `doAJAXRequest` for performing AJAX requests. The method is provided globally as `window.doAJAXRequest`. + +`doAJAXRequest` takes the following arguments: + +* `url`: The URL of the requestet site or end point. +* `method`: The HTTP method like `PUT`, `GET`, `POST`. +* `params`: An object containing key-value-pairs of parameters for the request. +* `successFn`: A callback function which is called when the AJAX request was successfull. +* `retryNo`: The number of retries, if the requests fails. Standard is 2 retries. +* `async`: Defines the async parameter for AJAX calls. Default is 'true'. + +An example of using the function would be: + +```javascript +window.doAJAXRequest('data/xql/getAnnotationMeta.xql', + 'GET', + { + uri: uri, + lang: lang + }, + Ext.bind(function(response){ + view.setMeta(response.responseText); + }, this) +); +``` diff --git a/README.md b/README.md index 3fa18aa24..49a4b0d66 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,28 @@ +[![Build](https://github.com/Edirom/Edirom-Online/actions/workflows/docker-ci.yml/badge.svg?branch=develop&event=push)](https://github.com/Edirom/Edirom-Online/actions/workflows/docker-ci.yml) + # Edirom Online -Edirom Online is a web application written in XQuery and Javascript, and designed for deployment in eXist-db[http://exist-db.org/exist/apps/homepage/index.html](http://exist-db.org/exist/apps/homepage/index.html). It is based on the work of the [_Edirom_-Project](https://edirom.de/edirom-projekt/) that originally was funded by the German Research Foundation (DFG). This software brings paperbased historio-critical editions of music texts to the web. +Edirom Online is a web application written in XQuery and JavaScript, and designed for deployment in [eXist-db](https://exist-db.org/). It is based on the work of the [_Edirom_-Project](https://edirom.de/edirom-projekt/) that originally was funded by the German Research Foundation (DFG). This software brings paperbased historio-critical editions of music texts to the web. The software is still under high development and has to be seen as beta software. +## Cloning this repository + +Since this repository uses submodules for e.g. fonts, it is necessary to clone the repository with the recursive addition. + +```bash +git clone --recursive +``` + +If the submodules are not yet present after cloning, you can update them with: + +```bash +git submodule update --init --recursive +``` + ## Dependencies -Edirom Online depends heavily on the javascript framework ExtJS () which is included in parts in our code base. We use ExtJS 4.2.1 in the GPL version. Edirom Online also includes the Raphaël javscript library (, MIT License) and the ACE editor (, BSD license). +Edirom Online depends heavily on the JavaScript framework [Ext JS](https://www.sencha.com/products/extjs) which is included in parts in our code base. We use Ext JS 4.2.1 in the GPL version. Edirom Online also includes the Raphaël javscript library (, MIT License) and the ACE editor (, BSD license). ## Contributing diff --git a/add/controller.xql b/add/controller.xql index acedaa4d7..41ce373cd 100755 --- a/add/controller.xql +++ b/add/controller.xql @@ -1,5 +1,6 @@ -xquery version "1.0"; +xquery version "3.1"; +import module namespace edition="http://www.edirom.de/xquery/edition" at "data/xqm/edition.xqm"; import module namespace eutil = "http://www.edirom.de/xquery/util" at "data/xqm/util.xqm"; declare variable $exist:path external; @@ -20,12 +21,13 @@ return else if ($exist:path eq "/") then (: redirect root path to index.html :) - + else if ($exist:path eq "/index.html") then (: forward index.html to index.xql :) + diff --git a/add/data/locale/edirom-lang-de.xml b/add/data/locale/edirom-lang-de.xml index 21f3437ee..943934a3d 100644 --- a/add/data/locale/edirom-lang-de.xml +++ b/add/data/locale/edirom-lang-de.xml @@ -176,5 +176,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/add/data/locale/edirom-lang-en.xml b/add/data/locale/edirom-lang-en.xml index 8e39ac716..44d568e4a 100644 --- a/add/data/locale/edirom-lang-en.xml +++ b/add/data/locale/edirom-lang-en.xml @@ -176,5 +176,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/add/data/xql/getAnnotationInfos.xql b/add/data/xql/getAnnotationInfos.xql index a3dbe0f7d..4b5775baf 100644 --- a/add/data/xql/getAnnotationInfos.xql +++ b/add/data/xql/getAnnotationInfos.xql @@ -1,102 +1,85 @@ xquery version "3.1"; (: - Edirom Online - Copyright (C) 2011 The Edirom Project - http://www.edirom.de - - Edirom Online is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Edirom Online is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Edirom Online. If not, see . - - ID: $Id: getAnnotationInfos.xql 1261 2012-02-28 15:50:45Z daniel $ +For LICENSE-Details please refer to the LICENSE file in the root directory of this repository. :) - -import module namespace eutil="http://www.edirom.de/xquery/util" at "../xqm/util.xqm"; -import module namespace annotation = "http://www.edirom.de/xquery/annotation" at "../xqm/annotation.xqm"; - -declare namespace request="http://exist-db.org/xquery/request"; -declare namespace mei="http://www.music-encoding.org/ns/mei"; -declare namespace xlink="http://www.w3.org/1999/xlink"; -declare namespace xmldb="http://exist-db.org/xquery/xmldb"; +declare namespace mei = "http://www.music-encoding.org/ns/mei"; declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization"; +declare namespace request = "http://exist-db.org/xquery/request"; -declare option output:method "text"; -declare option output:media-type "text/plain"; +import module namespace annotation = "http://www.edirom.de/xquery/annotation" at "../xqm/annotation.xqm"; +import module namespace eutil = "http://www.edirom.de/xquery/util" at "../xqm/util.xqm"; +declare option output:method "json"; +declare option output:media-type "application/json"; -declare variable $lang := request:get-parameter('lang', ''); +declare variable $uri := request:get-parameter('uri', ''); +declare variable $edition := request:get-parameter('edition', ''); +declare variable $edition_path := eutil:getPreference('edition_path', $edition); +(:~ + : Returns distinct list of catagories + :) declare function local:getDistinctCategories($annots as element()*) as xs:string* { - - let $oldCats := distinct-values($annots/mei:ptr[@type="categories"]/replace(@target, '#', '')) - let $newCats := distinct-values(for $annot in $annots return tokenize(replace(normalize-space($annot/@class),'#',''),' '))[contains(., 'annotation.category')] - - return distinct-values(($oldCats, $newCats)[string-length() gt 0]) + + let $oldCats := distinct-values($annots/mei:ptr[@type = "categories"]/replace(@target, '#', '')) + let $newCats := distinct-values(for $annot in $annots + return + tokenize(replace(normalize-space($annot/@class), '#', ''), ' '))[contains(., 'annotation.category')] + + return + distinct-values(($oldCats, $newCats)[string-length() gt 0]) }; +(:~ + : Returns distinct list of annotation priorities + :) declare function local:getDistinctPriorities($annots as element()*) as xs:string* { - - distinct-values( - for $annot in $annots - let $oldLink := $annot/mei:ptr[@type="priority"]/replace(@target, '#', '') - let $classes := tokenize(replace(normalize-space($annot/@class),'#',''),' ') - let $newLink := $classes[starts-with(.,'ediromAnnotPrio')] - return - distinct-values(($oldLink, $newLink))[string-length(.) gt 0] - ) + + distinct-values( + for $annot in $annots + let $oldLink := $annot/mei:ptr[@type = "priority"]/replace(@target, '#', '') + let $classes := tokenize(replace(normalize-space($annot/@class), '#', ''), ' ') + let $newLink := $classes[starts-with(., 'ediromAnnotPrio')] + return + distinct-values(($oldLink, $newLink))[string-length(.) gt 0] + ) }; -let $uri := request:get-parameter('uri', '') -let $edition := request:get-parameter('edition', '') let $mei := doc($uri)/root() -let $edition_path := eutil:getPreference('edition_path', $edition) let $annots := collection($edition_path)//mei:annot[matches(@plist, $uri)] | $mei//mei:annot - -let $categories := - for $category in local:getDistinctCategories($annots) - let $categoryElement := (collection($edition_path)/id($category)[mei:label or mei:name])[1] - let $name := annotation:category_getName($categoryElement, eutil:getLanguage($edition)) - order by $name - return map { - 'id': $category, - 'name': $name - } - -let $prios := - for $priority in local:getDistinctPriorities($annots) - let $name := annotation:getPriorityLabel((collection($edition_path)//id($priority)[mei:label or mei:name])[1]) - order by $name - return map { - 'id': $priority, - 'name': $name - } - -let $map := - map { - 'categories': array { $categories }, - 'priorities': array { $prios }, - 'count': count($annots) - } - -let $options := - map { - 'method': 'json', - 'media-type': 'text/plain' - } - -return serialize($map, $options) - -(: +let $categories := +for $category in local:getDistinctCategories($annots) +let $categoryElement := (collection($edition_path)/id($category)[mei:label or mei:name])[1] +let $name := annotation:category_getName($categoryElement, eutil:getLanguage($edition)) + order by $name +return + map { + 'id': $category, + 'name': $name + } + +let $prios := +for $priority in local:getDistinctPriorities($annots) +let $name := annotation:getPriorityLabel((collection($edition_path)//id($priority)[mei:label or mei:name])[1]) + order by $name +return + map { + 'id': $priority, + 'name': $name + } + +let $map := +map { + 'categories': array {$categories}, + 'priorities': array {$prios}, + 'count': count($annots) +} + +return + $map + + (: return concat('{categories: [', string-join( diff --git a/add/data/xql/getAnnotationPreviews.xql b/add/data/xql/getAnnotationPreviews.xql index 1d4992018..577b3e3ea 100644 --- a/add/data/xql/getAnnotationPreviews.xql +++ b/add/data/xql/getAnnotationPreviews.xql @@ -1,74 +1,58 @@ xquery version "3.1"; (: - Edirom Online - Copyright (C) 2011 The Edirom Project - http://www.edirom.de - - Edirom Online is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Edirom Online is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Edirom Online. If not, see . - - ID: $Id: getAnnotationPreviews.xql 1455 2012-10-11 10:42:55Z daniel $ +For LICENSE-Details please refer to the LICENSE file in the root directory of this repository. :) (:~ Returns the HTML for a specific annotation for an AnnotationView. - + @author Daniel Röwenstrunk @author Benjamin W. Bohl :) -import module namespace annotation="http://www.edirom.de/xquery/annotation" at "../xqm/annotation.xqm"; -import module namespace source="http://www.edirom.de/xquery/source" at "../xqm/source.xqm"; -import module namespace teitext="http://www.edirom.de/xquery/teitext" at "../xqm/teitext.xqm"; -import module namespace eutil = "http://www.edirom.de/xquery/util" at "../xqm/util.xqm"; -import module namespace edition="http://www.edirom.de/xquery/edition" at "../xqm/edition.xqm"; -import module namespace functx = "http://www.functx.com" at "../xqm/functx-1.0-nodoc-2007-01.xq"; -declare namespace exist="http://exist.sourceforge.net/NS/exist"; -declare namespace request="http://exist-db.org/xquery/request"; -declare namespace mei="http://www.music-encoding.org/ns/mei"; -declare namespace edirom_image="http://www.edirom.de/ns/image"; +declare namespace mei = "http://www.music-encoding.org/ns/mei"; +declare namespace request = "http://exist-db.org/xquery/request"; +declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization"; -declare namespace xmldb="http://exist-db.org/xquery/xmldb"; -declare namespace output="http://www.w3.org/2010/xslt-xquery-serialization"; +import module namespace source = "http://www.edirom.de/xquery/source" at "../xqm/source.xqm"; +import module namespace teitext = "http://www.edirom.de/xquery/teitext" at "../xqm/teitext.xqm"; +import module namespace eutil = "http://www.edirom.de/xquery/util" at "../xqm/util.xqm"; -declare option output:method "text"; -declare option output:media-type "text/plain"; +declare option output:method "json"; +declare option output:media-type "application/json"; declare variable $lang := request:get-parameter('lang', ''); -declare variable $imageWidth := 600; - declare variable $edition := request:get-parameter('edition', ''); -declare variable $imageserver := eutil:getPreference('image_server', $edition); -declare variable $imageBasePath := if($imageserver = 'leaflet') - then(eutil:getPreference('leaflet_prefix', $edition)) - else(eutil:getPreference('image_prefix', $edition)); +declare variable $imageserver := eutil:getPreference('image_server', $edition); +declare variable $uri := request:get-parameter('uri', ''); +declare variable $imageBasePath := if ($imageserver = 'leaflet') +then + (eutil:getPreference('leaflet_prefix', $edition)) +else + (eutil:getPreference('image_prefix', $edition)); declare function local:getParticipants($annot as element()) as map(*)* { - + let $participants := tokenize($annot/string(@plist), ' ') - let $docs := distinct-values(for $p in $participants return substring-before($p, '#')) + let $docs := distinct-values(for $p in $participants + return + substring-before($p, '#')) return for $doc in $docs - order by $doc + order by $doc return - if(source:isSource($doc)) - then(local:getSourceParticipants($participants[starts-with(., $doc)], $doc)) - - else if(teitext:isText($doc)) - then(local:getTextParticipants($participants[starts-with(., $doc)], $doc)) - - else() + if (source:isSource($doc)) + then + (local:getSourceParticipants($participants[starts-with(., $doc)], $doc)) + + else + if (teitext:isText($doc)) + then + (local:getTextParticipants($participants[starts-with(., $doc)], $doc)) + + else + () }; declare function local:getTextParticipants($participants as xs:string*, $doc as xs:string) as map(*)* { @@ -76,82 +60,95 @@ declare function local:getTextParticipants($participants as xs:string*, $doc as for $participant in $participants let $id := substring-after($participant, '#') let $hiddenData := concat('uri:', $doc, '__$$__participantId:', $id) - return map { - 'type': 'text', - 'label': 'Textstelle', - 'mdiv': '', - 'part': '', - 'page': '', - 'source': teitext:getLabel($doc, $edition), - 'siglum': '', - 'digilibBaseParams': '', - 'digilibSizeParams': '', - 'hiddenData': $hiddenData, - 'content': normalize-space(local:getTextNoteContent($doc, $id)), - 'linkUri': $participant - } + return + map { + 'type': 'text', + 'label': 'Textstelle', + 'mdiv': '', + 'part': '', + 'page': '', + 'source': teitext:getLabel($doc, $edition), + 'siglum': '', + 'digilibBaseParams': '', + 'digilibSizeParams': '', + 'hiddenData': $hiddenData, + 'content': normalize-space(local:getTextNoteContent($doc, $id)), + 'linkUri': $participant + } }; declare function local:getTextNoteContent($doc as xs:string, $id as xs:string) as xs:string { let $elem := doc($doc)/id($id) let $content := data($elem) return - if(string-length($content) gt 0) - then($content) - else(local:getTextNotePrecedingContent($elem)) + if (string-length($content) gt 0) + then + ($content) + else + (local:getTextNotePrecedingContent($elem)) }; declare function local:getTextNotePrecedingContent($elem as element()) as xs:string { let $preceding := $elem/preceding-sibling::*[1] let $content := data($preceding) return - if(string-length($content) gt 0) - then($content) - else(local:getTextNotePrecedingContent($preceding)) + if (string-length($content) gt 0) + then + ($content) + else + (local:getTextNotePrecedingContent($preceding)) }; declare function local:getSourceParticipants($participants as xs:string*, $doc as xs:string) as map(*)* { - + let $combs := local:groupParticipants($participants, $doc) - - return - + + return + for $comb in distinct-values($combs) - let $partIndices := tokenize($comb,'-') - - let $elems := - for $p in distinct-values($partIndices) - let $relevant.participant := $participants[starts-with(., $doc)][number($p)] - let $element.id := substring-after($relevant.participant,'#') - let $elem := local:getElement($relevant.participant) - (:return if(exists($elem)) then(local-name($elem)) else($relevant.participant):) + let $partIndices := tokenize($comb, '-') + + let $elems := + for $p in distinct-values($partIndices) + let $relevant.participant := $participants[starts-with(., $doc)][number($p)] + let $element.id := substring-after($relevant.participant, '#') + let $elem := local:getElement($relevant.participant) + (:return if(exists($elem)) then(local-name($elem)) else($relevant.participant):) where exists($elem) order by count($elem/preceding::*) - return $elem - - where count($elems) gt 0 - - let $zones := for $elem in $elems return local:getZone($elem) - + return + $elem + + where count($elems) gt 0 + + let $zones := for $elem in $elems + return + local:getZone($elem) + let $type := local:getType($zones) let $label := local:getItemLabel($elems) - - let $mdiv := ''(: TODO if($elem/ancestor-or-self::mei:mdiv) then($elem/ancestor-or-self::mei:mdiv/@label) else(''):) - let $page := if($zones[1]/parent::mei:surface/@label != '') then($zones[1]/parent::mei:surface/string(@label)) else($zones[1]/parent::mei:surface/string(@n)) + + let $mdiv := '' (: TODO if($elem/ancestor-or-self::mei:mdiv) then($elem/ancestor-or-self::mei:mdiv/@label) else(''):) + let $page := if ($zones[1]/parent::mei:surface/@label != '') then + ($zones[1]/parent::mei:surface/string(@label)) + else + ($zones[1]/parent::mei:surface/string(@n)) let $sourceLabel := source:getLabel($doc, $edition) let $siglum := ($elems[1]/root()//mei:*[@type eq 'siglum'])[1]/text() - - let $part := string-join(distinct-values(for $e in $elems return $e/ancestor::mei:part/string(@label)),'-') - + + let $part := string-join(distinct-values(for $e in $elems + return + $e/ancestor::mei:part/string(@label)), '-') + let $graphic := $zones[1]/../mei:graphic[@type = 'facsimile'] let $imgWidth := number($graphic/@width) let $imgHeight := number($graphic/@height) - + let $digilibBaseParams := local:getImageAreaPath($imageBasePath, $graphic) let $rect := local:getBoundingZone($zones) - + let $digilibSizeParams := local:getImageAreaParams($rect, $imgWidth, $imgHeight) - + let $hiddenData := map { 'width': number($rect/@lrx) - number($rect/@ulx), 'height': number($rect/@lry) - number($rect/@uly), @@ -160,86 +157,103 @@ declare function local:getSourceParticipants($participants as xs:string*, $doc a 'origH': $imgHeight, 'origW': $imgWidth } - + let $linkUri := concat('xmldb:exist://', document-uri($graphic/root()), '#', local:getSourceLinkTarget($elems, $zones)) - - return map { - 'type': $type, - 'label': $label, - 'mdiv': $mdiv, - 'part': $part, - 'page': $page, - 'source': $sourceLabel, - 'siglum': $siglum, - 'digilibBaseParams': $digilibBaseParams, - 'digilibSizeParams': $digilibSizeParams, - 'hiddenData': $hiddenData, - 'content': '', - 'linkUri': $linkUri - } + + return + map { + 'type': $type, + 'label': $label, + 'mdiv': $mdiv, + 'part': $part, + 'page': $page, + 'source': $sourceLabel, + 'siglum': $siglum, + 'digilibBaseParams': $digilibBaseParams, + 'digilibSizeParams': $digilibSizeParams, + 'hiddenData': $hiddenData, + 'content': '', + 'linkUri': $linkUri + } }; declare function local:getSourceLinkTarget($elems as node()*, $zones as node()*) as xs:string { - if(local-name($elems[1]) eq 'zone') - then($elems[1]/string(@xml:id)) - else if(count($elems) > 1) - then( - let $elemsSorted := for $elem in $elems - order by count($elem/preceding::*) - return $elem - return concat($elemsSorted[1]/@xml:id, '?tstamp2=', (count($elems) -1), 'm+0') - ) - else($elems[1]/string(@xml:id)) - + if (local-name($elems[1]) eq 'zone') + then + ($elems[1]/string(@xml:id)) + else + if (count($elems) > 1) + then + ( + let $elemsSorted := for $elem in $elems + order by count($elem/preceding::*) + return + $elem + return + concat($elemsSorted[1]/@xml:id, '?tstamp2=', (count($elems) - 1), 'm+0') + ) + else + ($elems[1]/string(@xml:id)) + }; declare function local:groupParticipants($participants as xs:string*, $doc as xs:string) as xs:string* { let $elems := for $p in $participants - let $id := substring-after($p, '#') - return doc($doc)/id($id) - + let $id := substring-after($p, '#') + return + doc($doc)/id($id) + let $zones := for $elem in $elems - return local:getZone($elem) - + return + local:getZone($elem) + let $combs := for $p at $i in $participants - return - local:getCombinations($elems, $zones, $i, count($zones)) - + return + local:getCombinations($elems, $zones, $i, count($zones)) + return reverse( - for $comb at $i in reverse($combs) - let $contained := for $n in (1 to count($combs) - $i) - return - if(contains($combs[$n], $comb)) - then(1) - else(0) - return - if(exists(index-of($contained, 1))) - then() - else($comb) + for $comb at $i in reverse($combs) + let $contained := for $n in (1 to count($combs) - $i) + return + if (contains($combs[$n], $comb)) + then + (1) + else + (0) + return + if (exists(index-of($contained, 1))) + then + () + else + ($comb) ) }; declare function local:getCombinations($elems as element()*, $zones as element()*, $i as xs:int, $total as xs:int) as xs:string { - + let $currentZone := $zones[$i] let $currentElem := $elems[$i] return - if(local-name($currentElem) eq 'measure' or local-name($currentElem) eq 'staff') - then( + if (local-name($currentElem) eq 'measure' or local-name($currentElem) eq 'staff') + then + ( string-join(( - string($i), - for $n in ($i + 1 to $total) - return - if((local-name($elems[$n]) eq 'measure' or local-name($elems[$n]) eq 'staff') and local:compareZones($currentZone, $zones[$n])) - then(local:getCombinations($elems, $zones, $n, $total)) - else() - ),'-') - ) - else( + string($i), + for $n in ($i + 1 to $total) + return + if ((local-name($elems[$n]) eq 'measure' or local-name($elems[$n]) eq 'staff') and local:compareZones($currentZone, $zones[$n])) + then + (local:getCombinations($elems, $zones, $n, $total)) + else + () + ), '-') + ) + else + ( string($i) - ) + ) }; declare function local:compareZones($zone1 as element(), $zone2 as element()) as xs:boolean { @@ -253,85 +267,105 @@ declare function local:compareZones($zone1 as element(), $zone2 as element()) as declare function local:getElement($uri as xs:string) as element()? { let $doc := substring-before($uri, '#') let $id := substring-after($uri, '#') - - return doc($doc)/id($id) + + return + doc($doc)/id($id) }; (: TODO: in Modul auslagern :) (:~ Gets the zone holding the graphical representation of an element - + @param $elem The element for which the graphical representation shall be found - + @return The zone element :) declare function local:getZone($elem as element()) as element()? { - if($elem/@facs) - then( + if ($elem/@facs) + then + ( let $zoneId := replace($elem/@facs, '^#', '') - return $elem/root()/id($zoneId) - ) - else( + return + $elem/root()/id($zoneId) + ) + else + ( $elem - ) + ) }; +(:~ + : Returns type of a zone + :) declare function local:getType($zones as element()*) as xs:string { $zones[1]/@type (: TODO: besser machen :) }; declare function local:getBoundingZone($zones as element()*) as element() { - + }; (: TODO: in Modul auslagern :) (:~ - + :) declare function local:getImageAreaPath($basePath as xs:string, $graphic as element()?) as xs:string { - + let $imagePath := string($graphic/@target) let $imgWidth := number($graphic/@width) let $imgHeight := number($graphic/@height) let $isAbsolute := starts-with($imagePath, 'http') - - let $fields := if($imageserver = 'leaflet')then(substring-before($imagePath, '.') )else() - + + let $fields := if ($imageserver = 'leaflet') then + (substring-before($imagePath, '.')) + else + () + return if ($isAbsolute) - then $imagePath + then + $imagePath else switch ($imageserver) - case 'leaflet' return concat($basePath,$fields) - case 'openseadragon' return concat($basePath,translate($imagePath, '/', '!')) - default return concat($basePath, $imagePath, '?') - + case 'leaflet' + return + concat($basePath, $fields) + case 'openseadragon' + return + concat($basePath, translate($imagePath, '/', '!')) + default return + concat($basePath, $imagePath, '?') + }; (: TODO: in Modul auslagern :) (:~ This function generates an image path for a specific zone on an image. Based on a path prefix and a width. - + @param $basePath The base path prefix for the image databse @param $zone The zone with coordiantes on the image @param $width The width the image should be loaded with - + @return A URL pointing to an image based as xs:string :) declare function local:getImageAreaParams($zone as element()?, $imgWidth as xs:int, $imgHeight as xs:int) as xs:string { let $graphic := $zone/../mei:graphic[@type = 'facsimile'] - + let $imgX := number($zone/@ulx) let $imgY := number($zone/@uly) let $w := number($zone/@lrx) - number($zone/@ulx) let $h := number($zone/@lry) - number($zone/@uly) - + let $wx := $imgX div $imgWidth let $wy := $imgY div $imgHeight let $ww := $w div $imgWidth let $wh := $h div $imgHeight - + return concat('&amp;wx=', $wx, '&amp;wy=', $wy, '&amp;ww=', $ww, '&amp;wh=', $wh, '&amp;mo=fit') }; @@ -339,50 +373,78 @@ declare function local:getImageAreaParams($zone as element()?, $imgWidth as xs:i declare function local:getItemLabel($elems as element()*) as xs:string { let $language := eutil:getLanguage($edition) return - string-join( - for $type in distinct-values(for $elem in $elems return local-name($elem)) - let $items := for $elem in $elems return if(local-name($elem) eq $type) then($elem) else() - let $itemLabelMultiRestSensitive := if($items[1]//mei:multiRest) - then ($items[1]/@n || '–' || number($items[1]/@n) + number($items[1]//mei:multiRest/@num) - 1) - else ($items[1]/@n) - return - if(local-name($items[1]) eq 'measure') - then( - if(count($items) gt 1) - then(eutil:getLanguageString('Bars_from_to', ($items[1]/@n, $items[last()]/@n), $language)) - else(eutil:getLanguageString('Bar_n', $itemLabelMultiRestSensitive, $language)) - ) - else if(local-name($items[1]) eq 'staff') - (: TODO: $itemLabelMultiRestSensitive also for staffs? :) - then( - if(count($items) gt 1) - then( - - let $measureNs := distinct-values($items/ancestor::mei:measure/@n) - - let $label := if ($lang = 'de') - then (if(count($measureNs) gt 1) then (concat('Takte ',$measureNs[1], '-', $measureNs[last()])) else (concat('Takt ', $measureNs[1]))) - else (if(count($measureNs) gt 1) then (concat('Bars ',$measureNs[1], '-', $measureNs[last()])) else (concat('Bar ', $measureNs[1]))) - - return - - concat($label, ' (', string-join($items/preceding::mei:staffDef[@n = $items[1]/@n][1]/@label.abbr,', '),')') - + string-join( + for $type in distinct-values(for $elem in $elems + return + local-name($elem)) + let $items := for $elem in $elems + return + if (local-name($elem) eq $type) then + ($elem) + else + () + let $itemLabelMultiRestSensitive := if ($items[1]//mei:multiRest) + then + ($items[1]/@n || '–' || number($items[1]/@n) + number($items[1]//mei:multiRest/@num) - 1) + else + ($items[1]/@n) + return + if (local-name($items[1]) eq 'measure') + then + ( + if (count($items) gt 1) + then + (eutil:getLanguageString('Bars_from_to', ($items[1]/@n, $items[last()]/@n), $language)) + else + (eutil:getLanguageString('Bar_n', $itemLabelMultiRestSensitive, $language)) ) - else(concat('Takt ',$items[1]/ancestor::mei:measure/@n, ' (', $items[1]/preceding::mei:staffDef[@n = $items[1]/@n][1]/@label.abbr,')')) - ) - else if(local-name($items[1]) eq 'zone') - then( - if(count($items) gt 1) - then((:Dieser Fall sollte nicht vorkommen, da freie zones nicht zusammengefasst werden dürfen:)) - else(concat('Ausschnitt (S. ',$items[1]/parent::mei:surface/@n,')')) - ) - else() - ,' ') - + else + if (local-name($items[1]) eq 'staff') + (: TODO: $itemLabelMultiRestSensitive also for staffs? :) + then + ( + if (count($items) gt 1) + then + ( + + let $measureNs := distinct-values($items/ancestor::mei:measure/@n) + + let $label := if ($lang = 'de') + then + (if (count($measureNs) gt 1) then + (concat('Takte ', $measureNs[1], '-', $measureNs[last()])) + else + (concat('Takt ', $measureNs[1]))) + else + (if (count($measureNs) gt 1) then + (concat('Bars ', $measureNs[1], '-', $measureNs[last()])) + else + (concat('Bar ', $measureNs[1]))) + + return + + concat($label, ' (', string-join($items/preceding::mei:staffDef[@n = $items[1]/@n][1]/@label.abbr, ', '), ')') + + ) + else + (concat('Takt ', $items[1]/ancestor::mei:measure/@n, ' (', $items[1]/preceding::mei:staffDef[@n = $items[1]/@n][1]/@label.abbr, ')')) + ) + else + if (local-name($items[1]) eq 'zone') + then + ( + if (count($items) gt 1) + then + ((:Dieser Fall sollte nicht vorkommen, da freie zones nicht zusammengefasst werden dürfen:) ) + else + (concat('Ausschnitt (S. ', $items[1]/parent::mei:surface/@n, ')')) + ) + else + () + , ' ') + }; -let $uri := request:get-parameter('uri', '') let $docUri := substring-before($uri, '#') let $internalId := substring-after($uri, '#') let $doc := doc($docUri) @@ -390,13 +452,8 @@ let $annot := $doc/id($internalId) let $map := map { 'success': true(), - 'participants': array { local:getParticipants($annot)} + 'participants': array {local:getParticipants($annot)} } -let $options := - map { - 'method': 'json', - 'media-type': 'text/plain' - } - -return serialize($map, $options) +return + $map diff --git a/add/data/xql/getAnnotationsInRendering.xql b/add/data/xql/getAnnotationsInRendering.xql index 75d9127af..78d744e85 100644 --- a/add/data/xql/getAnnotationsInRendering.xql +++ b/add/data/xql/getAnnotationsInRendering.xql @@ -26,7 +26,7 @@ xquery version "3.0"; @author Daniel Röwenstrunk :) -import module namespace functx = "http://www.functx.com" at "../xqm/functx-1.0-nodoc-2007-01.xq"; +import module namespace functx = "http://www.functx.com"; import module namespace eutil="http://www.edirom.de/xquery/util" at "../xqm/util.xqm"; diff --git a/add/data/xql/getAnnotationsOnPage.xql b/add/data/xql/getAnnotationsOnPage.xql index 18a4c2fe5..0dbba5837 100644 --- a/add/data/xql/getAnnotationsOnPage.xql +++ b/add/data/xql/getAnnotationsOnPage.xql @@ -27,7 +27,7 @@ xquery version "3.1"; : @author Benjamin W. Bohl :) -import module namespace functx = "http://www.functx.com" at "../xqm/functx-1.0-nodoc-2007-01.xq"; +import module namespace functx = "http://www.functx.com"; import module namespace eutil="http://www.edirom.de/xquery/util" at "../xqm/util.xqm"; diff --git a/add/data/xql/getInternalIdType.xql b/add/data/xql/getInternalIdType.xql index 64d185c0c..43cd7314b 100644 --- a/add/data/xql/getInternalIdType.xql +++ b/add/data/xql/getInternalIdType.xql @@ -23,7 +23,7 @@ xquery version "1.0"; declare namespace request="http://exist-db.org/xquery/request"; declare namespace mei="http://www.music-encoding.org/ns/mei"; -import module namespace functx = "http://www.functx.com" at "../xqm/functx-1.0-nodoc-2007-01.xq"; +import module namespace functx = "http://www.functx.com"; declare option exist:serialize "method=text media-type=text/plain omit-xml-declaration=yes"; diff --git a/add/data/xql/getLinkTarget.xql b/add/data/xql/getLinkTarget.xql index 84e516561..86dcbca9a 100644 --- a/add/data/xql/getLinkTarget.xql +++ b/add/data/xql/getLinkTarget.xql @@ -1,190 +1,266 @@ xquery version "3.1"; (: - Edirom Online - Copyright (C) 2011 The Edirom Project - http://www.edirom.de - - Edirom Online is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Edirom Online is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Edirom Online. If not, see . - - ID: $Id: getLinkTarget.xql 1334 2012-06-14 12:40:33Z daniel $ +For LICENSE-Details please refer to the LICENSE file in the root directory of this repository. :) -import module namespace source="http://www.edirom.de/xquery/source" at "../xqm/source.xqm"; -import module namespace work="http://www.edirom.de/xquery/work" at "../xqm/work.xqm"; -import module namespace teitext="http://www.edirom.de/xquery/teitext" at "../xqm/teitext.xqm"; -import module namespace eutil="http://www.edirom.de/xquery/util" at "../xqm/util.xqm"; - -declare namespace request="http://exist-db.org/xquery/request"; -declare namespace mei="http://www.music-encoding.org/ns/mei"; -declare namespace tei="http://www.tei-c.org/ns/1.0"; -declare namespace xmldb="http://exist-db.org/xquery/xmldb"; -declare namespace html="http://www.w3.org/1999/xhtml"; +declare namespace html = "http://www.w3.org/1999/xhtml"; +declare namespace map = "http://www.w3.org/2005/xpath-functions/map"; +declare namespace mei = "http://www.music-encoding.org/ns/mei"; declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization"; -declare namespace map="http://www.w3.org/2005/xpath-functions/map"; -declare namespace f="http://local.link"; +declare namespace tei = "http://www.tei-c.org/ns/1.0"; -import module namespace functx = "http://www.functx.com" at "../xqm/functx-1.0-nodoc-2007-01.xq"; +import module namespace functx = "http://www.functx.com"; +import module namespace request = "http://exist-db.org/xquery/request"; +import module namespace xmldb = "http://exist-db.org/xquery/xmldb"; -declare option output:method "text"; -declare option output:media-type "text/plain"; +import module namespace eutil = "http://www.edirom.de/xquery/util" at "../xqm/util.xqm"; +import module namespace source = "http://www.edirom.de/xquery/source" at "../xqm/source.xqm"; +import module namespace teitext = "http://www.edirom.de/xquery/teitext" at "../xqm/teitext.xqm"; +import module namespace work = "http://www.edirom.de/xquery/work" at "../xqm/work.xqm"; + +declare option output:method "json"; +declare option output:media-type "application/json"; declare variable $lang := request:get-parameter('lang', ''); +declare variable $uri := request:get-parameter('uri', ''); +(:~ + : Returns a view for an edirom object + :) declare function local:getView($type as xs:string, $docUri as xs:string, $doc as node()+) as map(*)? { let $baseMap := map { - 'type': substring-after($type,'_'), - 'uri': if($type = ('mei_textView', 'desc_xmlView')) then string(($doc//mei:annot[@type='descLink'])[1]/@plist) else $docUri + 'type': substring-after($type, '_'), + 'uri': if ($type = ('mei_textView', 'desc_xmlView')) then + string(($doc//mei:annot[@type = 'descLink'])[1]/@plist) + else + $docUri } (: optionally set label for some views:) let $labeled.map := - if($type = 'mei_textView') - then(map:put($baseMap, 'label', 'Quellenbeschreibung')) - else if($type = 'desc_xmlView') - then(map:put($baseMap, 'label', 'XML Quellenbeschreibung')) - else($baseMap) - - (: whether to set the view as default view:) - let $defaultViewed.map := - if($type = ('mei_sourceView', - 'mei_audioView', - 'tei_textView', - 'tei_facsimileView', - 'tei_textFacsimileSplitView', - 'mei_annotationView', - 'mei_verovioView')) - then(map:put($labeled.map, 'defaultView', true())) - else($labeled.map) + if ($type = 'mei_textView') + then + (map:put($baseMap, 'label', 'Quellenbeschreibung')) + else + if ($type = 'desc_xmlView') + then + (map:put($baseMap, 'label', 'XML Quellenbeschreibung')) + else + ($baseMap) + + (: whether to set the view as default view:) + let $defaultViewed.map := + if ($type = ('mei_sourceView', + 'mei_audioView', + 'tei_textView', + 'tei_facsimileView', + 'tei_textFacsimileSplitView', + 'mei_annotationView', + 'mei_verovioView')) + then + (map:put($labeled.map, 'defaultView', true())) + else + ($labeled.map) - (: xpath check whether any given view is supported :) + (: xpath check whether any given view is supported :) let $hasView := - if($type = 'desc_summaryView') - then(true()) - - else if($type = 'desc_headerView') - then(exists($doc//mei:meiHead or $doc//tei:teiHeader)) - - else if($type = 'mei_textView') - then(exists($doc//mei:annot[@type='descLink'])) - - else if($type = 'mei_sourceView') - then(exists($doc//mei:facsimile//mei:graphic[@type='facsimile'])) - - else if($type = 'mei_audioView') - then(exists($doc//mei:recording)) - - else if($type = 'mei_verovioView') - then(exists($doc//mei:body//mei:measure) and exists($doc//mei:body//mei:note)) - - else if($type = 'tei_textView') - then(exists($doc//tei:body[matches(.//text(), '[^\s]+')])) - - else if($type = 'tei_facsimileView') - then(exists($doc//tei:facsimile//tei:graphic)) - - else if($type = 'tei_textFacsimileSplitView') - then(exists($doc//tei:facsimile//tei:graphic) and exists($doc//tei:pb[@facs])) - - else if($type = 'mei_annotationView') - then(exists($doc//mei:annot[@type='editorialComment'])) - - else if($type = 'xml_xmlView') - then(true()) - - else if($type = 'desc_xmlView') - then(exists($doc//mei:annot[@type='descLink'])) + if ($type = 'desc_summaryView') + then + (true()) + + else + if ($type = 'desc_headerView') + then + (exists($doc//mei:meiHead or $doc//tei:teiHeader)) - else(false()) + else + if ($type = 'mei_textView') + then + (exists($doc//mei:annot[@type = 'descLink'])) + + else + if ($type = 'mei_sourceView') + then + (exists($doc//mei:facsimile//mei:graphic[@type = 'facsimile'])) + + else + if ($type = 'mei_audioView') + then + (exists($doc//mei:recording)) + + else + if ($type = 'mei_verovioView') + then + (exists($doc//mei:body//mei:measure) and exists($doc//mei:body//mei:note)) + + else + if ($type = 'tei_textView') + then + (exists($doc//tei:body[matches(.//text(), '[^\s]+')])) + + else + if ($type = 'tei_facsimileView') + then + (exists($doc//tei:facsimile//tei:graphic)) + + else + if ($type = 'tei_textFacsimileSplitView') + then + (exists($doc//tei:facsimile//tei:graphic) and exists($doc//tei:pb[@facs])) + + else + if ($type = 'mei_annotationView') + then + (exists($doc//mei:annot[@type = 'editorialComment'])) + + else + if ($type = 'xml_xmlView') + then + (true()) + + else + if ($type = 'desc_xmlView') + then + (exists($doc//mei:annot[@type = 'descLink'])) + + else + (false()) return - if($hasView) - then($defaultViewed.map) - else() + if ($hasView) + then + ($defaultViewed.map) + else + () }; +(:~ + : Returns the views for an edirom object + :) declare function local:getViews($type as xs:string, $docUri as xs:string, $doc as node()+) as map(*)* { let $views := ( - (:'desc_summaryView',:) - (:'desc_headerView',:) - 'mei_textView', - 'mei_sourceView', - 'mei_audioView', - 'mei_verovioView', - 'tei_textView', - 'tei_facsimileView', - 'tei_textFacsimileSplitView', - 'mei_annotationView', - 'xml_xmlView', - 'desc_xmlView' + (:'desc_summaryView',:) + (:'desc_headerView',:) + 'mei_textView', + 'mei_sourceView', + 'mei_audioView', + 'mei_verovioView', + 'tei_textView', + 'tei_facsimileView', + 'tei_textFacsimileSplitView', + 'mei_annotationView', + 'xml_xmlView', + 'desc_xmlView' ) let $maps := - for $view in $views - return local:getView($view, $docUri, $doc) - - return $maps + for $view in $views + return + local:getView($view, $docUri, $doc) + + return + $maps }; +(:~ + : Returns the window title for an edirom-object + :) declare function local:getWindowTitle($doc as node()+, $type as xs:string) as xs:string { - (: Work :) - if(exists($doc//mei:mei) and exists($doc//mei:workDesc/mei:work) and not(exists($doc//mei:perfMedium))) - then(eutil:getLocalizedTitle(($doc//mei:work)[1]/mei:titleStmt[1], $lang)) - - (: Recording :) - else if(exists($doc//mei:mei) and exists($doc//mei:recording)) - then(eutil:getLocalizedTitle($doc//mei:fileDesc/mei:titleStmt[1], $lang)) - - (: Source / Score :) - else if($type = 'source' and exists($doc//mei:manifestation/mei:titleStmt)) - then(string-join((eutil:getLocalizedTitle(($doc//mei:manifestation)[1]/mei:titleStmt[1], $lang), - ($doc//mei:manifestation)[1]//mei:identifier[lower-case(@type)='shelfmark'][1]), ' | ') - => normalize-space()) - else if($type = 'source' and exists($doc//mei:source/mei:titleStmt)) - then(string-join((eutil:getLocalizedTitle(($doc//mei:source)[1]/mei:titleStmt[1], $lang), - ($doc//mei:source)[1]//mei:identifier[lower-case(@type)='shelfmark'][1]), ' | ') - => normalize-space()) - - (: MEI fallback if no title is found :) - else if(exists($doc//mei:mei) and exists(($doc//mei:titleStmt)[1])) - then(eutil:getLocalizedTitle(($doc//mei:titleStmt)[1], $lang)) - - (: Text :) - else if(exists($doc/tei:TEI)) - then(eutil:getLocalizedTitle($doc//tei:fileDesc/tei:titleStmt[1], $lang)) - - (: HTML :) - else if($type = 'html') - then($doc//head/data(title)) - - else(string('unknown')) + (: Work :) + if (exists($doc//mei:mei) and exists($doc//mei:workDesc/mei:work) and not(exists($doc//mei:perfMedium))) + then + (eutil:getLocalizedTitle(($doc//mei:work)[1]/mei:titleStmt[1], $lang)) + else + if (exists($doc/root()/mei:work)) + then + (eutil:getLocalizedTitle($doc/root()/mei:work, $lang)) + + (: Recording :) + else + if (exists($doc//mei:mei) and exists($doc//mei:recording)) + then + (eutil:getLocalizedTitle($doc//mei:fileDesc/mei:titleStmt[1], $lang)) + + (: Source / Score :) + else + if ($type = 'source' and exists($doc//mei:manifestation/mei:titleStmt)) + then + (string-join((eutil:getLocalizedTitle(($doc//mei:manifestation)[1]/mei:titleStmt[1], $lang), + ($doc//mei:manifestation)[1]//mei:identifier[lower-case(@type) = 'shelfmark'][1]), ' | ') + => normalize-space()) + else + if ($type = 'source' and exists($doc//mei:source/mei:titleStmt)) + then + (string-join((eutil:getLocalizedTitle(($doc//mei:source)[1]/mei:titleStmt[1], $lang), + ($doc//mei:source)[1]//mei:identifier[lower-case(@type) = 'shelfmark'][1]), ' | ') + => normalize-space()) + + (: MEI fallback if no title is found :) + else + if (exists($doc//mei:mei) and exists(($doc//mei:titleStmt)[1])) + then + (eutil:getLocalizedTitle(($doc//mei:titleStmt)[1], $lang)) + + (: Text :) + else + if (exists($doc/tei:TEI)) + then + (eutil:getLocalizedTitle($doc//tei:fileDesc/tei:titleStmt[1], $lang)) + + (: HTML :) + else + if ($type = 'html') + then + ($doc//head/data(title)) + + else + (string('unknown')) }; -let $uri := request:get-parameter('uri', '') -let $uriParams := if(contains($uri, '?')) then(substring-after($uri, '?')) else('') -let $uri := if(contains($uri, '?')) then(replace($uri, '[?&](term|path)=[^&]*', '')) else($uri) -let $docUri := if(contains($uri, '#')) then(substring-before($uri, '#')) else($uri) -let $internalId := if(contains($uri, '#')) then(substring-after($uri, '#')) else() -let $internalIdParam := if(contains($internalId, '?')) then(concat('?', substring-after($internalId, '?'))) else('') -let $internalId := if(contains($internalId, '?')) then(substring-before($internalId, '?')) else($internalId) +let $uriParams := if (contains($uri, '?')) then + (substring-after($uri, '?')) +else + ('') +let $uri := if (contains($uri, '?')) then + (replace($uri, '[?&](term|path)=[^&]*', '')) +else + ($uri) +let $docUri := if (contains($uri, '#')) then + (substring-before($uri, '#')) +else + ($uri) +let $internalId := if (contains($uri, '#')) then + (substring-after($uri, '#')) +else + () +let $internalIdParam := if (contains($internalId, '?')) then + (concat('?', substring-after($internalId, '?'))) +else + ('') +let $internalId := if (contains($internalId, '?')) then + (substring-before($internalId, '?')) +else + ($internalId) -let $term := if(contains($uriParams, 'term='))then(substring-after($uriParams, 'term='))else() -let $term := if(contains($term, '&'))then(substring-before($term, '&'))else($term) +let $term := if (contains($uriParams, 'term=')) then + (substring-after($uriParams, 'term=')) +else + () +let $term := if (contains($term, '&')) then + (substring-before($term, '&')) +else + ($term) -let $path := if(contains($uriParams, 'path='))then(substring-after($uriParams, 'path='))else() -let $path := if(contains($path, '&'))then(substring-before($path, '&'))else($path) +let $path := if (contains($uriParams, 'path=')) then + (substring-after($uriParams, 'path=')) +else + () +let $path := if (contains($path, '&')) then + (substring-before($path, '&')) +else + ($path) let $doc := eutil:getDoc($docUri) let $internal := $doc/id($internalId) @@ -193,65 +269,78 @@ let $edition := request:get-parameter('edition', '') (: Specific handling of virtual measure IDs for parts in OPERA project :) let $internal := - if(exists($internal)) - then($internal) - else( - if(starts-with($internalId, 'measure_') and $doc//mei:parts) - then( - - let $mdivId := functx:substring-before-last(substring-after($internalId, 'measure_'), '_') - let $measureN := functx:substring-after-last($internalId, '_') - return - ($doc/id($mdivId)//mei:measure[@n eq $measureN])[1] +if (exists($internal)) +then + ($internal) +else + ( + if (starts-with($internalId, 'measure_') and $doc//mei:parts) + then + ( + + let $mdivId := functx:substring-before-last(substring-after($internalId, 'measure_'), '_') + let $measureN := functx:substring-after-last($internalId, '_') + return + ($doc/id($mdivId)//mei:measure[@n eq $measureN])[1] ) - else($internal) + else + ($internal) ) let $type := (: Work :) - if(exists($doc//mei:mei) and exists($doc//mei:work) and not(exists($doc//mei:perfMedium))) - then(string('work')) - - (: Recording :) - else if(exists($doc//mei:mei) and exists($doc//mei:recording)) - then(string('recording')) - - (: Source / Score :) - else if(source:isSource($docUri)) - then(string('source')) - - (: Text :) - else if(exists($doc/tei:TEI)) - then(string('text')) - - (: HTML :) - else if(exists($doc/html) or exists($doc/html:html)) - then(string('html')) - - else if(contains($docUri, '.html')) - then(string('html')) - - else(string('unknown')) - -let $internalIdType := if(exists($internal)) - then(local-name($internal)) - else('unknown') +if (exists($doc//mei:mei) and exists($doc//mei:work) and not(exists($doc//mei:perfMedium))) +then + (string('work')) + + (: Recording :) +else + if (exists($doc//mei:mei) and exists($doc//mei:recording)) + then + (string('recording')) + + (: Source / Score :) + else + if (source:isSource($docUri)) + then + (string('source')) + + (: Text :) + else + if (exists($doc/tei:TEI)) + then + (string('text')) + + (: HTML :) + else + if (exists($doc/html) or exists($doc/html:html)) + then + (string('html')) + + else + if (contains($docUri, '.html')) + then + (string('html')) + + else + (string('unknown')) -let $map := - map { - 'type': $type, - 'title': local:getWindowTitle($doc, $type), - 'doc': $docUri, - 'views': array {local:getViews($type, $docUri, $doc)}, - 'internalId': $internalId || $internalIdParam, - 'term': $term, - 'path': $path, - 'internalIdType': $internalIdType - } +let $internalIdType := if (exists($internal)) +then + (local-name($internal)) +else + ('unknown') -let $options := - map { - 'method': 'json', - 'media-type': 'text/plain' - } +let $map := +map { + 'type': $type, + 'title': local:getWindowTitle($doc, $type), + 'doc': $docUri, + 'views': array {local:getViews($type, $docUri, $doc)}, + 'internalId': $internalId || $internalIdParam, + 'term': $term, + 'path': $path, + 'internalIdType': $internalIdType +} -return serialize($map, $options) +return + $map diff --git a/add/data/xql/getMeasure.xql b/add/data/xql/getMeasure.xql index ffca1c8e6..99e592b6f 100644 --- a/add/data/xql/getMeasure.xql +++ b/add/data/xql/getMeasure.xql @@ -26,7 +26,7 @@ declare namespace xlink="http://www.w3.org/1999/xlink"; declare namespace xmldb="http://exist-db.org/xquery/xmldb"; -import module namespace functx = "http://www.functx.com" at "../xqm/functx-1.0-nodoc-2007-01.xq"; +import module namespace functx = "http://www.functx.com"; declare option exist:serialize "method=text media-type=text/plain omit-xml-declaration=yes"; diff --git a/add/data/xql/getMeasures.xql b/add/data/xql/getMeasures.xql index 8abb4c462..ce0af33b3 100644 --- a/add/data/xql/getMeasures.xql +++ b/add/data/xql/getMeasures.xql @@ -60,19 +60,17 @@ declare function local:getMeasures($mei as node(), $mdivID as xs:string) as xs:s let $measures := if ($mdiv//mei:measure/@label) then ($mdiv//mei:measure[.//mei:multiRest][number(substring-before(@label, '–')) <= $measureNNumber][.//mei:multiRest/number(@num) gt ($measureNNumber - number(substring-before(@label, '–')))]) else ($mdiv//mei:measure[.//mei:multiRest][number(@n) lt $measureNNumber][.//mei:multiRest/number(@num) gt ($measureNNumber - number(@n))]) - let $measures := if ($mdiv//mei:measure/@label) - then ( - for $part in $mdiv//mei:part - for $measure in $part//mei:measure[@label = $measureN][1] | $measures[ancestor::mei:part = $part] - return - concat('{id:"', $measure/@xml:id, '", voice: "', $part//mei:staffDef/@decls, '"}') - ) - else ( - for $part in $mdiv//mei:part - for $measure in $part//mei:measure[@n = $measureN][1] | $measures[ancestor::mei:part = $part] - return - concat('{id:"', $measure/@xml:id, '", voice: "', $part//mei:staffDef/@decls, '"}') - ) + let $measures := for $part in $mdiv//mei:part + let $partMeasures := if($part//mei:measure/@label) + then($part//mei:measure[@label = $measureN][1]) + else($part//mei:measure[@n = $measureN][1]) + for $measure in $partMeasures | $measures[ancestor::mei:part = $part] + let $voiceRef := $part//mei:staffDef/@decls + return + concat('{id:"', $measure/@xml:id, '", + voice: "', $voiceRef, + '", partLabel: "', eutil:getPartLabel($measure, 'measure'), + '"}') return concat('{', 'id: "measure_', $mdiv/@xml:id, '_', $measureN, '", ', diff --git a/add/data/xql/getParts.xql b/add/data/xql/getParts.xql index 6cf9572b1..4b041881f 100644 --- a/add/data/xql/getParts.xql +++ b/add/data/xql/getParts.xql @@ -1,4 +1,4 @@ -xquery version "1.0"; +xquery version "3.1"; (: Edirom Online Copyright (C) 2011 The Edirom Project @@ -21,15 +21,23 @@ xquery version "1.0"; declare namespace request="http://exist-db.org/xquery/request"; declare namespace mei="http://www.music-encoding.org/ns/mei"; - declare namespace xmldb="http://exist-db.org/xquery/xmldb"; +import module namespace eutil="http://www.edirom.de/xquery/util" at "../xqm/util.xqm"; + declare option exist:serialize "method=text media-type=text/plain omit-xml-declaration=yes"; let $uri := request:get-parameter('uri', '') let $mei := doc($uri)/root() let $ret := for $part in ($mei//mei:instrumentation/mei:instrVoice | $mei//mei:perfMedium//mei:perfRes) - return concat('{label: "', $part/@label, '", id:"', $part/@xml:id, '", selectedByDefault:true, selected:true}') + let $hasNoAttrSameas := not(exists($part/@sameas)) + return + concat( + '{label: "', eutil:getPartLabel($part, 'perfRes'), + '", id:"', $part/@xml:id, + '", selectedByDefault:', $hasNoAttrSameas, + ', selected:', $hasNoAttrSameas, '}' + ) return concat('[', string-join($ret, ','), ']') \ No newline at end of file diff --git a/add/data/xql/getText.xql b/add/data/xql/getText.xql index b8be575e7..781b5d382 100644 --- a/add/data/xql/getText.xql +++ b/add/data/xql/getText.xql @@ -92,5 +92,5 @@ let $body := $doc//xhtml:body return element div { for $attribute in $body/@* return $attribute, - for $node in $body/node() return $node - } \ No newline at end of file + for $node in $body/node() return $node + } diff --git a/add/data/xqm/annotation.xqm b/add/data/xqm/annotation.xqm index 4123ceb50..7d70812f5 100644 --- a/add/data/xqm/annotation.xqm +++ b/add/data/xqm/annotation.xqm @@ -80,26 +80,28 @@ declare function annotation:toJSON($anno as element(), $edition as xs:string) as let $id := $anno/string(@xml:id) let $lang := request:get-parameter('lang', '') let $genericTitle := eutil:getLocalizedTitle($anno, $lang) - let $title := + let $title := if(exists($genericTitle) and string-length($genericTitle) gt 0) then($genericTitle) else(annotation:generateTitle($anno)) let $doc := $anno/root() let $prio := annotation:getPriorityLabel($anno) let $pList.raw := distinct-values(tokenize(normalize-space($anno/@plist), ' ')) - let $pList := for $p in $pList.raw + let $pList := for $p in $pList.raw return if ( contains($p, '#')) then (substring-before($p, '#')) else $p - let $sigla := + let $sigla := for $p in distinct-values($pList) - let $pDoc := + let $pDoc := if(doc-available($p)) then(doc($p)) else(collection(eutil:getPreference('edition_path', $edition))//id($p)/root()) - return + return if ($pDoc//mei:sourceDesc/mei:source/mei:identifier[@type = 'siglum']) - then $pDoc//mei:sourceDesc/mei:source/mei:identifier[@type = 'siglum']/text() + then ($pDoc//mei:sourceDesc/mei:source/mei:identifier[@type = 'siglum']/text()) + else if ($pDoc//mei:manifestationList/mei:manifestation/mei:identifier[@type = 'siglum']) + then ($pDoc//mei:manifestationList/mei:manifestation/mei:identifier[@type = 'siglum']/text()) else ($pDoc//mei:title[@type = 'siglum']/text()) let $classes := tokenize(replace(normalize-space($anno/@class),'#',''),' ') @@ -107,7 +109,7 @@ declare function annotation:toJSON($anno as element(), $edition as xs:string) as let $cats := string-join( for $u in $catURIs - return annotation:category_getName($doc/id($u), eutil:getLanguage($edition)) + return annotation:category_getName($doc/id($u), eutil:getLanguage($edition)) , ', ') let $count := count($anno/preceding::mei:annot[@type = 'editorialComment']) + 1 @@ -156,7 +158,7 @@ declare function annotation:getContent($anno as element(), $idPrefix as xs:strin let $p := $anno/mei:p[not(@xml:lang) or @xml:lang = $language] let $html := transform:transform($p,concat($xsltBase,'meiP2html.xsl'),) - return + return $html }; @@ -216,7 +218,7 @@ declare function annotation:getPriorityLabel($anno) as xs:string* { let $labels := for $uri in $classBasedUri - let $doc := + let $doc := if(starts-with($uri,'#')) then($anno/root()) else(doc(substring-before($uri,'#'))) @@ -253,14 +255,14 @@ declare function annotation:getCategoriesAsArray($anno as element()) as xs:strin let $classes := tokenize(replace(normalize-space($anno/@class),'#',''),' ') let $catURIs := distinct-values((tokenize(replace($anno/mei:ptr[@type = 'categories']/@target,'#',''),' '), $classes[contains(.,'annotation.category.')])) - let $cats := + let $cats := for $u in $catURIs - return annotation:category_getName($doc/id($u),'') + return annotation:category_getName($doc/id($u),'') (:let $uris := tokenize($anno/mei:ptr[@type eq 'categories']/string(@target),' ') - let $string := for $uri in $uris + let $string := for $uri in $uris let $doc := if(starts-with($uri,'#')) then($anno/root()) else(doc(substring-before($uri,'#'))) @@ -301,4 +303,4 @@ declare function annotation:category_getName($category as element(), $language a switch (count($names[@xml:lang = $language])) case 1 return $names[@xml:lang = $language] default return $names[1]:) -}; \ No newline at end of file +}; diff --git a/add/data/xqm/edition.xqm b/add/data/xqm/edition.xqm index 88f41900f..0e9b3bc27 100644 --- a/add/data/xqm/edition.xqm +++ b/add/data/xqm/edition.xqm @@ -1,4 +1,4 @@ -xquery version "3.0"; +xquery version "3.1"; (: Edirom Online Copyright (C) 2011 The Edirom Project @@ -28,10 +28,10 @@ xquery version "3.0"; :) module namespace edition = "http://www.edirom.de/xquery/edition"; -declare namespace edirom="http://www.edirom.de/ns/1.3"; -declare namespace xlink="http://www.w3.org/1999/xlink"; +declare namespace edirom = "http://www.edirom.de/ns/1.3"; +declare namespace xlink = "http://www.w3.org/1999/xlink"; -import module namespace functx="http://www.functx.com"; +import module namespace functx = "http://www.functx.com"; (:~ : Returns a JSON representation of an Edition : @@ -44,10 +44,10 @@ declare function edition:toJSON($uri as xs:string) as xs:string { return concat(' {', - 'id: "', $edition/string(@xml:id), '", ', - 'doc: "', $uri, '", ', - 'name: "', $edition/edirom:editionName, '"', - '}') + 'id: "', $edition/string(@xml:id), '", ', + 'doc: "', $uri, '", ', + 'name: "', $edition/edirom:editionName, '"', + '}') }; (:~ @@ -58,7 +58,8 @@ declare function edition:toJSON($uri as xs:string) as xs:string { declare function edition:getUris() as xs:string* { for $edition in collection('/db/apps')//edirom:edition - return 'xmldb:exist://' || document-uri($edition/root()) + return + 'xmldb:exist://' || document-uri($edition/root()) }; (:~ @@ -69,7 +70,7 @@ declare function edition:getUris() as xs:string* { :) declare function edition:getWorkUris($uri as xs:string) as xs:string* { - doc($uri)//edirom:work/string(@xlink:href) + doc($uri)//edirom:work/@xlink:href ! string(.) }; (:~ @@ -80,37 +81,85 @@ declare function edition:getWorkUris($uri as xs:string) as xs:string* { : @return The URI :) declare function edition:getLanguageFileURI($uri as xs:string, $lang as xs:string) as xs:string { + + let $doc := ( + if(doc-available($uri)) + then + doc($uri) + else + doc(edition:findEdition($uri)) + ) + return + if ($doc//edirom:language[@xml:lang eq $lang]/@xlink:href => string() != "") + then + $doc//edirom:language[@xml:lang eq $lang]/@xlink:href => string() + else + "" +}; + +(:~ +: Returns the URI for a specific language file +: +: @param $uri The URI of the Edition's document to process +: @return the edition's languages as defined in the edition file sorted as +: complete languages in document-order followed by incomplete langauges in document-order +:) +declare function edition:getLanguageCodesSorted($uri as xs:string) as xs:string { - doc($uri)//edirom:language[@xml:lang eq $lang]/string(@xlink:href) + let $editionDoc := doc($uri) + let $languagesComplete := ( + for $lang in $editionDoc//edirom:language + let $langCode := $lang/@xml:lang + let $langComplete := xs:boolean($lang/@complete) + where $langComplete = true() + return + $langCode + ) + let $languagesIncomplete := ( + for $lang in $editionDoc//edirom:language + let $langCode := $lang/@xml:lang + let $langComplete := xs:boolean($lang/@complete) + where $langComplete = false() + return + $langCode + ) + return + ($languagesComplete, $languagesIncomplete) }; (:~ : Returns the URI for the preferences file : : @param $uri The URI of the Edition's document to process -: @return The URI +: @return The URI of the preference file :) declare function edition:getPreferencesURI($uri as xs:string) as xs:string { - doc($uri)//edirom:preferences/string(@xlink:href) + doc($uri)//edirom:preferences/@xlink:href => string() }; (:~ -: Returns the URI of the first found Edition +: Returns the URI of the edition specified by the submitted $editionID parameter. +: If $editionID is the empty string, returns the URI of the first edition found in '/db/apps'. +: If the submitted $editionID already qualifies to read a document, return $editionID unaltered. : -: @param $uri The URI of the Edition's document to process -: @return The URI +: @param $editionID The '@xml:id' of the edirom:edition document to process +: @return The URI of the Edition file :) -declare function edition:findEdition($uri as xs:string) as xs:string { - if($uri eq '') +declare function edition:findEdition($editionID as xs:string?) as xs:string { + if(not($editionID) or $editionID eq '') then( let $edition := (collection('/db/apps')//edirom:edition)[1] return 'xmldb:exist://' || document-uri($edition/root()) ) + else if(doc-available($editionID)) (:already a qualified URI :) + then + $editionID else ( - let $edition := collection('/db/apps')//edirom:edition[@xml:id eq $uri] - return 'xmldb:exist://' || document-uri($edition/root()) - ) + let $edition := collection('/db/apps')//edirom:edition/id($editionID) + return + 'xmldb:exist://' || document-uri($edition/root()) + ) }; (:~ @@ -120,7 +169,7 @@ declare function edition:findEdition($uri as xs:string) as xs:string { : @return the text contents of edirom:edition/edirom:editionName :) declare function edition:getName($uri as xs:string) as xs:string { - doc($uri)/edirom:edition/edirom:editionName/text() + doc($uri)/edirom:edition/edirom:editionName => fn:normalize-space() }; (:~ diff --git a/add/data/xqm/functx-1.0-nodoc-2007-01.xq b/add/data/xqm/functx-1.0-nodoc-2007-01.xq deleted file mode 100644 index dd8ca2a68..000000000 --- a/add/data/xqm/functx-1.0-nodoc-2007-01.xq +++ /dev/null @@ -1,1410 +0,0 @@ - -(:~ - - : -------------------------------- - : The FunctX XQuery Function Library - : -------------------------------- - - : Copyright (C) 2007 Datypic - - : This library is free software; you can redistribute it and/or - : modify it under the terms of the GNU Lesser General Public - : License as published by the Free Software Foundation; either - : version 2.1 of the License. - - : This library is distributed in the hope that it will be useful, - : but WITHOUT ANY WARRANTY; without even the implied warranty of - : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - : Lesser General Public License for more details. - - : You should have received a copy of the GNU Lesser General Public - : License along with this library; if not, write to the Free Software - : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - : For more information on the FunctX XQuery library, contact contrib@functx.com. - - : @version 1.0 - : @see http://www.xqueryfunctions.com - :) -module namespace functx = "http://www.functx.com" ; - -declare function functx:add-attributes - ( $elements as element()* , - $attrNames as xs:QName* , - $attrValues as xs:anyAtomicType* ) as element()? { - - for $element in $elements - return element { node-name($element)} - { for $attrName at $seq in $attrNames - return if ($element/@*[node-name(.) = $attrName]) - then () - else attribute {$attrName} - {$attrValues[$seq]}, - $element/@*, - $element/node() } - } ; - -declare function functx:add-months - ( $date as xs:anyAtomicType? , - $months as xs:integer ) as xs:date? { - - xs:date($date) + functx:yearMonthDuration(0,$months) - } ; - -declare function functx:add-or-update-attributes - ( $elements as element()* , - $attrNames as xs:QName* , - $attrValues as xs:anyAtomicType* ) as element()? { - - for $element in $elements - return element { node-name($element)} - { for $attrName at $seq in $attrNames - return attribute {$attrName} - {$attrValues[$seq]}, - $element/@*[not(node-name(.) = $attrNames)], - $element/node() } - } ; - -declare function functx:all-whitespace - ( $arg as xs:string? ) as xs:boolean { - - normalize-space($arg) = '' - } ; - -declare function functx:are-distinct-values - ( $seq as xs:anyAtomicType* ) as xs:boolean { - - count(distinct-values($seq)) = count($seq) - } ; - -declare function functx:atomic-type - ( $values as xs:anyAtomicType* ) as xs:string* { - - for $val in $values - return - (if ($val instance of xs:untypedAtomic) then 'xs:untypedAtomic' - else if ($val instance of xs:anyURI) then 'xs:anyURI' - else if ($val instance of xs:ENTITY) then 'xs:ENTITY' - else if ($val instance of xs:ID) then 'xs:ID' - else if ($val instance of xs:NMTOKEN) then 'xs:NMTOKEN' - else if ($val instance of xs:language) then 'xs:language' - else if ($val instance of xs:NCName) then 'xs:NCName' - else if ($val instance of xs:Name) then 'xs:Name' - else if ($val instance of xs:token) then 'xs:token' - else if ($val instance of xs:normalizedString) - then 'xs:normalizedString' - else if ($val instance of xs:string) then 'xs:string' - else if ($val instance of xs:QName) then 'xs:QName' - else if ($val instance of xs:boolean) then 'xs:boolean' - else if ($val instance of xs:base64Binary) then 'xs:base64Binary' - else if ($val instance of xs:hexBinary) then 'xs:hexBinary' - else if ($val instance of xs:byte) then 'xs:byte' - else if ($val instance of xs:short) then 'xs:short' - else if ($val instance of xs:int) then 'xs:int' - else if ($val instance of xs:long) then 'xs:long' - else if ($val instance of xs:unsignedByte) then 'xs:unsignedByte' - else if ($val instance of xs:unsignedShort) then 'xs:unsignedShort' - else if ($val instance of xs:unsignedInt) then 'xs:unsignedInt' - else if ($val instance of xs:unsignedLong) then 'xs:unsignedLong' - else if ($val instance of xs:positiveInteger) - then 'xs:positiveInteger' - else if ($val instance of xs:nonNegativeInteger) - then 'xs:nonNegativeInteger' - else if ($val instance of xs:negativeInteger) - then 'xs:negativeInteger' - else if ($val instance of xs:nonPositiveInteger) - then 'xs:nonPositiveInteger' - else if ($val instance of xs:integer) then 'xs:integer' - else if ($val instance of xs:decimal) then 'xs:decimal' - else if ($val instance of xs:float) then 'xs:float' - else if ($val instance of xs:double) then 'xs:double' - else if ($val instance of xs:date) then 'xs:date' - else if ($val instance of xs:time) then 'xs:time' - else if ($val instance of xs:dateTime) then 'xs:dateTime' - else if ($val instance of xs:dayTimeDuration) - then 'xs:dayTimeDuration' - else if ($val instance of xs:yearMonthDuration) - then 'xs:yearMonthDuration' - else if ($val instance of xs:duration) then 'xs:duration' - else if ($val instance of xs:gMonth) then 'xs:gMonth' - else if ($val instance of xs:gYear) then 'xs:gYear' - else if ($val instance of xs:gYearMonth) then 'xs:gYearMonth' - else if ($val instance of xs:gDay) then 'xs:gDay' - else if ($val instance of xs:gMonthDay) then 'xs:gMonthDay' - else 'unknown') - } ; - -declare function functx:avg-empty-is-zero - ( $values as xs:anyAtomicType* , - $allNodes as node()* ) as xs:double { - - if (empty($allNodes)) - then 0 - else sum($values[string(.) != '']) div count($allNodes) - } ; - -declare function functx:between-exclusive - ( $value as xs:anyAtomicType? , - $minValue as xs:anyAtomicType , - $maxValue as xs:anyAtomicType ) as xs:boolean { - - $value > $minValue and $value < $maxValue - } ; - -declare function functx:between-inclusive - ( $value as xs:anyAtomicType? , - $minValue as xs:anyAtomicType , - $maxValue as xs:anyAtomicType ) as xs:boolean { - - $value >= $minValue and $value <= $maxValue - } ; - -declare function functx:camel-case-to-words - ( $arg as xs:string? , - $delim as xs:string ) as xs:string { - - concat(substring($arg,1,1), - replace(substring($arg,2),'(\p{Lu})', - concat($delim, '$1'))) - } ; - -declare function functx:capitalize-first - ( $arg as xs:string? ) as xs:string? { - - concat(upper-case(substring($arg,1,1)), - substring($arg,2)) - } ; - -declare function functx:change-element-names-deep - ( $nodes as node()* , - $oldNames as xs:QName* , - $newNames as xs:QName* ) as node()* { - - if (count($oldNames) != count($newNames)) - then error(xs:QName('functx:Different_number_of_names')) - else - for $node in $nodes - return if ($node instance of element()) - then element - {functx:if-empty - ($newNames[index-of($oldNames, - node-name($node))], - node-name($node)) } - {$node/@*, - functx:change-element-names-deep($node/node(), - $oldNames, $newNames)} - else if ($node instance of document-node()) - then functx:change-element-names-deep($node/node(), - $oldNames, $newNames) - else $node - } ; - -declare function functx:change-element-ns-deep - ( $nodes as node()* , - $newns as xs:string , - $prefix as xs:string ) as node()* { - - for $node in $nodes - return if ($node instance of element()) - then (element - {QName ($newns, - concat($prefix, - if ($prefix = '') - then '' - else ':', - local-name($node)))} - {$node/@*, - functx:change-element-ns-deep($node/node(), - $newns, $prefix)}) - else if ($node instance of document-node()) - then functx:change-element-ns-deep($node/node(), - $newns, $prefix) - else $node - } ; - -declare function functx:change-element-ns - ( $elements as element()* , - $newns as xs:string , - $prefix as xs:string ) as element()? { - - for $element in $elements - return - element {QName ($newns, - concat($prefix, - if ($prefix = '') - then '' - else ':', - local-name($element)))} - {$element/@*, $element/node()} - } ; - -declare function functx:chars - ( $arg as xs:string? ) as xs:string* { - - for $ch in string-to-codepoints($arg) - return codepoints-to-string($ch) - } ; - -declare function functx:contains-any-of - ( $arg as xs:string? , - $searchStrings as xs:string* ) as xs:boolean { - - some $searchString in $searchStrings - satisfies contains($arg,$searchString) - } ; - -declare function functx:contains-case-insensitive - ( $arg as xs:string? , - $substring as xs:string ) as xs:boolean? { - - contains(upper-case($arg), upper-case($substring)) - } ; - -declare function functx:contains-word - ( $arg as xs:string? , - $word as xs:string ) as xs:boolean { - - matches(upper-case($arg), - concat('^(.*\W)?', - upper-case(functx:escape-for-regex($word)), - '(\W.*)?$')) - } ; - -declare function functx:copy-attributes - ( $copyTo as element() , - $copyFrom as element() ) as element() { - - element { node-name($copyTo)} - { $copyTo/@*[not(node-name(.) = $copyFrom/@*/node-name(.))], - $copyFrom/@*, - $copyTo/node() } - - } ; - -declare function functx:date - ( $year as xs:anyAtomicType , - $month as xs:anyAtomicType , - $day as xs:anyAtomicType ) as xs:date { - - xs:date( - concat( - functx:pad-integer-to-length(xs:integer($year),4),'-', - functx:pad-integer-to-length(xs:integer($month),2),'-', - functx:pad-integer-to-length(xs:integer($day),2))) - } ; - -declare function functx:dateTime - ( $year as xs:anyAtomicType , - $month as xs:anyAtomicType , - $day as xs:anyAtomicType , - $hour as xs:anyAtomicType , - $minute as xs:anyAtomicType , - $second as xs:anyAtomicType ) as xs:dateTime { - - xs:dateTime( - concat(functx:date($year,$month,$day),'T', - functx:time($hour,$minute,$second))) - } ; - -declare function functx:day-in-year - ( $date as xs:anyAtomicType? ) as xs:integer? { - - days-from-duration( - xs:date($date) - functx:first-day-of-year($date)) + 1 - } ; - -declare function functx:day-of-week-abbrev-en - ( $date as xs:anyAtomicType? ) as xs:string? { - - ('Sun', 'Mon', 'Tues', 'Wed', 'Thurs', 'Fri', 'Sat') - [functx:day-of-week($date) + 1] - } ; - -declare function functx:day-of-week-name-en - ( $date as xs:anyAtomicType? ) as xs:string? { - - ('Sunday', 'Monday', 'Tuesday', 'Wednesday', - 'Thursday', 'Friday', 'Saturday') - [functx:day-of-week($date) + 1] - } ; - -declare function functx:day-of-week - ( $date as xs:anyAtomicType? ) as xs:integer? { - - if (empty($date)) - then () - else xs:integer((xs:date($date) - xs:date('1901-01-06')) - div xs:dayTimeDuration('P1D')) mod 7 - } ; - -declare function functx:dayTimeDuration - ( $days as xs:decimal? , - $hours as xs:decimal? , - $minutes as xs:decimal? , - $seconds as xs:decimal? ) as xs:dayTimeDuration { - - (xs:dayTimeDuration('P1D') * functx:if-empty($days,0)) + - (xs:dayTimeDuration('PT1H') * functx:if-empty($hours,0)) + - (xs:dayTimeDuration('PT1M') * functx:if-empty($minutes,0)) + - (xs:dayTimeDuration('PT1S') * functx:if-empty($seconds,0)) - } ; - -declare function functx:days-in-month - ( $date as xs:anyAtomicType? ) as xs:integer? { - - if (month-from-date(xs:date($date)) = 2 and - functx:is-leap-year($date)) - then 29 - else - (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31) - [month-from-date(xs:date($date))] - } ; - -declare function functx:depth-of-node - ( $node as node()? ) as xs:integer { - - count($node/ancestor-or-self::node()) - } ; - -declare function functx:distinct-attribute-names - ( $nodes as node()* ) as xs:string* { - - distinct-values($nodes//@*/name(.)) - } ; - -declare function functx:distinct-deep - ( $nodes as node()* ) as node()* { - - for $seq in (1 to count($nodes)) - return $nodes[$seq][not(functx:is-node-in-sequence-deep-equal( - .,$nodes[position() < $seq]))] - } ; - -declare function functx:distinct-element-names - ( $nodes as node()* ) as xs:string* { - - distinct-values($nodes/descendant-or-self::*/name(.)) - } ; - -declare function functx:distinct-element-paths - ( $nodes as node()* ) as xs:string* { - - distinct-values(functx:path-to-node($nodes/descendant-or-self::*)) - } ; - -declare function functx:distinct-nodes - ( $nodes as node()* ) as node()* { - - for $seq in (1 to count($nodes)) - return $nodes[$seq][not(functx:is-node-in-sequence( - .,$nodes[position() < $seq]))] - } ; - -declare function functx:duration-from-timezone - ( $timezone as xs:string ) as xs:dayTimeDuration { - - xs:dayTimeDuration( - if (not(matches($timezone,'Z|[\+\-]\d{2}:\d{2}'))) - then error(xs:QName('functx:Invalid_Timezone_Value')) - else if ($timezone = 'Z') - then 'PT0S' - else replace($timezone,'\+?(\d{2}):\d{2}','PT$1H') - ) - } ; - -declare function functx:dynamic-path - ( $parent as node() , - $path as xs:string ) as item()* { - - let $nextStep := functx:substring-before-if-contains($path,'/') - let $restOfSteps := substring-after($path,'/') - for $child in - ($parent/*[functx:name-test(name(),$nextStep)], - $parent/@*[functx:name-test(name(), - substring-after($nextStep,'@'))]) - return if ($restOfSteps) - then functx:dynamic-path($child, $restOfSteps) - else $child - } ; - -declare function functx:escape-for-regex - ( $arg as xs:string? ) as xs:string { - - replace($arg, - '(\.|\[|\]|\\|\||\-|\^|\$|\?|\*|\+|\{|\}|\(|\))','\\$1') - } ; - -declare function functx:exclusive-or - ( $arg1 as xs:boolean? , - $arg2 as xs:boolean? ) as xs:boolean? { - - $arg1 != $arg2 - } ; - -declare function functx:first-day-of-month - ( $date as xs:anyAtomicType? ) as xs:date? { - - functx:date(year-from-date(xs:date($date)), - month-from-date(xs:date($date)), - 1) - } ; - -declare function functx:first-day-of-year - ( $date as xs:anyAtomicType? ) as xs:date? { - - functx:date(year-from-date(xs:date($date)), 1, 1) - } ; - -declare function functx:first-node - ( $nodes as node()* ) as node()? { - - ($nodes/.)[1] - } ; - -declare function functx:follows-not-descendant - ( $a as node()? , - $b as node()? ) as xs:boolean { - - $a >> $b and empty($b intersect $a/ancestor::node()) - } ; - -declare function functx:format-as-title-en - ( $titles as xs:string* ) as xs:string* { - - let $wordsToMoveToEnd := ('A', 'An', 'The') - for $title in $titles - let $firstWord := functx:substring-before-match($title,'\W') - return if ($firstWord = $wordsToMoveToEnd) - then replace($title,'(.*?)\W(.*)', '$2, $1') - else $title - } ; - -declare function functx:fragment-from-uri - ( $uri as xs:string? ) as xs:string? { - - substring-after($uri,'#') - } ; - -declare function functx:get-matches-and-non-matches - ( $string as xs:string? , - $regex as xs:string ) as element()* { - - let $iomf := functx:index-of-match-first($string, $regex) - return - if (empty($iomf)) - then {$string} - else - if ($iomf > 1) - then ({substring($string,1,$iomf - 1)}, - functx:get-matches-and-non-matches( - substring($string,$iomf),$regex)) - else - let $length := - string-length($string) - - string-length(functx:replace-first($string, $regex,'')) - return ({substring($string,1,$length)}, - if (string-length($string) > $length) - then functx:get-matches-and-non-matches( - substring($string,$length + 1),$regex) - else ()) - } ; - -declare function functx:get-matches - ( $string as xs:string? , - $regex as xs:string ) as xs:string* { - - functx:get-matches-and-non-matches($string,$regex)/ - string(self::match) - } ; - -declare function functx:has-element-only-content - ( $element as element() ) as xs:boolean { - - not($element/text()[normalize-space(.) != '']) and $element/* - } ; - -declare function functx:has-empty-content - ( $element as element() ) as xs:boolean { - - not($element/node()) - } ; - -declare function functx:has-mixed-content - ( $element as element() ) as xs:boolean { - - $element/text()[normalize-space(.) != ''] and $element/* - } ; - -declare function functx:has-simple-content - ( $element as element() ) as xs:boolean { - - $element/text() and not($element/*) - } ; - -declare function functx:id-from-element - ( $element as element()? ) as xs:string? { - - data(($element/@*[id(.) is ..])[1]) - } ; - -declare function functx:id-untyped - ( $node as node()* , - $id as xs:anyAtomicType ) as element()* { - - $node//*[@* = $id] - } ; - -declare function functx:if-absent - ( $arg as item()* , - $value as item()* ) as item()* { - - if (exists($arg)) - then $arg - else $value - } ; - -declare function functx:if-empty - ( $arg as item()? , - $value as item()* ) as item()* { - - if (string($arg) != '') - then data($arg) - else $value - } ; - -declare function functx:index-of-deep-equal-node - ( $nodes as node()* , - $nodeToFind as node() ) as xs:integer* { - - for $seq in (1 to count($nodes)) - return $seq[deep-equal($nodes[$seq],$nodeToFind)] - } ; - -declare function functx:index-of-match-first - ( $arg as xs:string? , - $pattern as xs:string ) as xs:integer? { - - if (matches($arg,$pattern)) - then string-length(tokenize($arg, $pattern)[1]) + 1 - else () - } ; - -declare function functx:index-of-node - ( $nodes as node()* , - $nodeToFind as node() ) as xs:integer* { - - for $seq in (1 to count($nodes)) - return $seq[$nodes[$seq] is $nodeToFind] - } ; - -declare function functx:index-of-string-first - ( $arg as xs:string? , - $substring as xs:string ) as xs:integer? { - - if (contains($arg, $substring)) - then string-length(substring-before($arg, $substring))+1 - else () - } ; - -declare function functx:index-of-string-last - ( $arg as xs:string? , - $substring as xs:string ) as xs:integer? { - - functx:index-of-string($arg, $substring)[last()] - } ; - -declare function functx:index-of-string - ( $arg as xs:string? , - $substring as xs:string ) as xs:integer* { - - if (contains($arg, $substring)) - then (string-length(substring-before($arg, $substring))+1, - for $other in - functx:index-of-string(substring-after($arg, $substring), - $substring) - return - $other + - string-length(substring-before($arg, $substring)) + - string-length($substring)) - else () - } ; - -declare function functx:insert-string - ( $originalString as xs:string? , - $stringToInsert as xs:string? , - $pos as xs:integer ) as xs:string { - - concat(substring($originalString,1,$pos - 1), - $stringToInsert, - substring($originalString,$pos)) - } ; - -declare function functx:is-a-number - ( $value as xs:anyAtomicType? ) as xs:boolean { - - string(number($value)) != 'NaN' - } ; - -declare function functx:is-absolute-uri - ( $uri as xs:string? ) as xs:boolean { - - matches($uri,'^[a-z]+:') - } ; - -declare function functx:is-ancestor - ( $node1 as node() , - $node2 as node() ) as xs:boolean { - - exists($node1 intersect $node2/ancestor::node()) - } ; - -declare function functx:is-descendant - ( $node1 as node() , - $node2 as node() ) as xs:boolean { - - boolean($node2 intersect $node1/ancestor::node()) - } ; - -declare function functx:is-leap-year - ( $date as xs:anyAtomicType? ) as xs:boolean { - - for $year in xs:integer(substring(string($date),1,4)) - return ($year mod 4 = 0 and - $year mod 100 != 0) or - $year mod 400 = 0 - } ; - -declare function functx:is-node-among-descendants-deep-equal - ( $node as node()? , - $seq as node()* ) as xs:boolean { - - some $nodeInSeq in $seq/descendant-or-self::*/(.|@*) - satisfies deep-equal($nodeInSeq,$node) - } ; - -declare function functx:is-node-among-descendants - ( $node as node()? , - $seq as node()* ) as xs:boolean { - - some $nodeInSeq in $seq/descendant-or-self::*/(.|@*) - satisfies $nodeInSeq is $node - } ; - -declare function functx:is-node-in-sequence-deep-equal - ( $node as node()? , - $seq as node()* ) as xs:boolean { - - some $nodeInSeq in $seq satisfies deep-equal($nodeInSeq,$node) - } ; - -declare function functx:is-node-in-sequence - ( $node as node()? , - $seq as node()* ) as xs:boolean { - - some $nodeInSeq in $seq satisfies $nodeInSeq is $node - } ; - -declare function functx:is-value-in-sequence - ( $value as xs:anyAtomicType? , - $seq as xs:anyAtomicType* ) as xs:boolean { - - $value = $seq - } ; - -declare function functx:last-day-of-month - ( $date as xs:anyAtomicType? ) as xs:date? { - - functx:date(year-from-date(xs:date($date)), - month-from-date(xs:date($date)), - functx:days-in-month($date)) - } ; - -declare function functx:last-day-of-year - ( $date as xs:anyAtomicType? ) as xs:date? { - - functx:date(year-from-date(xs:date($date)), 12, 31) - } ; - -declare function functx:last-node - ( $nodes as node()* ) as node()? { - - ($nodes/.)[last()] - } ; - -declare function functx:leaf-elements - ( $root as node()? ) as element()* { - - $root/descendant-or-self::*[not(*)] - } ; - -declare function functx:left-trim - ( $arg as xs:string? ) as xs:string { - - replace($arg,'^\s+','') - } ; - -declare function functx:line-count - ( $arg as xs:string? ) as xs:integer { - - count(functx:lines($arg)) - } ; - -declare function functx:lines - ( $arg as xs:string? ) as xs:string* { - - tokenize($arg, '(\r\n?|\n\r?)') - } ; - -declare function functx:max-depth - ( $root as node()? ) as xs:integer? { - - if ($root/*) - then max($root/*/functx:max-depth(.)) + 1 - else 1 - } ; - -declare function functx:max-determine-type - ( $seq as xs:anyAtomicType* ) as xs:anyAtomicType? { - - if (every $value in $seq satisfies ($value castable as xs:double)) - then max(for $value in $seq return xs:double($value)) - else max(for $value in $seq return xs:string($value)) - } ; - -declare function functx:max-line-length - ( $arg as xs:string? ) as xs:integer { - - max( - for $line in functx:lines($arg) - return string-length($line)) - } ; - -declare function functx:max-node - ( $nodes as node()* ) as node()* { - - $nodes[. = max($nodes)] - } ; - -declare function functx:max-string - ( $strings as xs:anyAtomicType* ) as xs:string? { - - max(for $string in $strings return string($string)) - } ; - -declare function functx:min-determine-type - ( $seq as xs:anyAtomicType* ) as xs:anyAtomicType? { - - if (every $value in $seq satisfies ($value castable as xs:double)) - then min(for $value in $seq return xs:double($value)) - else min(for $value in $seq return xs:string($value)) - } ; - -declare function functx:min-node - ( $nodes as node()* ) as node()* { - - $nodes[. = min($nodes)] - } ; - -declare function functx:min-non-empty-string - ( $strings as xs:string* ) as xs:string? { - - min($strings[. != '']) - } ; - -declare function functx:min-string - ( $strings as xs:anyAtomicType* ) as xs:string? { - - min(for $string in $strings return string($string)) - } ; - -declare function functx:mmddyyyy-to-date - ( $dateString as xs:string? ) as xs:date? { - - if (empty($dateString)) - then () - else if (not(matches($dateString, - '^\D*(\d{2})\D*(\d{2})\D*(\d{4})\D*$'))) - then error(xs:QName('functx:Invalid_Date_Format')) - else xs:date(replace($dateString, - '^\D*(\d{2})\D*(\d{2})\D*(\d{4})\D*$', - '$3-$1-$2')) - } ; - -declare function functx:month-abbrev-en - ( $date as xs:anyAtomicType? ) as xs:string? { - - ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', - 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec') - [month-from-date(xs:date($date))] - } ; - -declare function functx:month-name-en - ( $date as xs:anyAtomicType? ) as xs:string? { - - ('January', 'February', 'March', 'April', 'May', 'June', - 'July', 'August', 'September', 'October', 'November', 'December') - [month-from-date(xs:date($date))] - } ; - -declare function functx:name-test - ( $testname as xs:string? , - $names as xs:string* ) as xs:boolean { - -$testname = $names -or -$names = '*' -or -functx:substring-after-if-contains($testname,':') = - (for $name in $names - return substring-after($name,'*:')) -or -substring-before($testname,':') = - (for $name in $names[contains(.,':*')] - return substring-before($name,':*')) - } ; - -declare function functx:namespaces-in-use - ( $root as node()? ) as xs:anyURI* { - - distinct-values( - $root/descendant-or-self::*/(.|@*)/namespace-uri(.)) - } ; - -declare function functx:next-day - ( $date as xs:anyAtomicType? ) as xs:date? { - - xs:date($date) + xs:dayTimeDuration('P1D') - } ; - -declare function functx:node-kind - ( $nodes as node()* ) as xs:string* { - - for $node in $nodes - return - if ($node instance of element()) then 'element' - else if ($node instance of attribute()) then 'attribute' - else if ($node instance of text()) then 'text' - else if ($node instance of document-node()) then 'document-node' - else if ($node instance of comment()) then 'comment' - else if ($node instance of processing-instruction()) - then 'processing-instruction' - else 'unknown' - } ; - -declare function functx:non-distinct-values - ( $seq as xs:anyAtomicType* ) as xs:anyAtomicType* { - - for $val in distinct-values($seq) - return $val[count($seq[. = $val]) > 1] - } ; - -declare function functx:number-of-matches - ( $arg as xs:string? , - $pattern as xs:string ) as xs:integer { - - count(tokenize($arg,$pattern)) - 1 - } ; - -declare function functx:open-ref-document - ( $refNode as node() ) as document-node() { - - if (base-uri($refNode)) - then doc(resolve-uri($refNode, base-uri($refNode))) - else doc(resolve-uri($refNode)) - } ; - -declare function functx:ordinal-number-en - ( $num as xs:integer? ) as xs:string { - - concat(xs:string($num), - if (matches(xs:string($num),'[04-9]$|1[1-3]$')) then 'th' - else if (ends-with(xs:string($num),'1')) then 'st' - else if (ends-with(xs:string($num),'2')) then 'nd' - else if (ends-with(xs:string($num),'3')) then 'rd' - else '') - } ; - -declare function functx:pad-integer-to-length - ( $integerToPad as xs:anyAtomicType? , - $length as xs:integer ) as xs:string { - - if ($length < string-length(string($integerToPad))) - then error(xs:QName('functx:Integer_Longer_Than_Length')) - else concat - (functx:repeat-string( - '0',$length - string-length(string($integerToPad))), - string($integerToPad)) - } ; - -declare function functx:pad-string-to-length - ( $stringToPad as xs:string? , - $padChar as xs:string , - $length as xs:integer ) as xs:string { - - substring( - string-join ( - ($stringToPad, for $i in (1 to $length) return $padChar) - ,'') - ,1,$length) - } ; - -declare function functx:path-to-node-with-pos - ( $node as node()? ) as xs:string { - -string-join( - for $ancestor in $node/ancestor-or-self::* - let $sibsOfSameName := $ancestor/../*[name() = name($ancestor)] - return concat(name($ancestor), - if (count($sibsOfSameName) <= 1) - then '' - else concat( - '[',functx:index-of-node($sibsOfSameName,$ancestor),']')) - , '/') - } ; - -declare function functx:path-to-node - ( $nodes as node()* ) as xs:string* { - -$nodes/string-join(ancestor-or-self::*/name(.), '/') - } ; - -declare function functx:precedes-not-ancestor - ( $a as node()? , - $b as node()? ) as xs:boolean { - - $a << $b and empty($a intersect $b/ancestor::node()) - } ; - -declare function functx:previous-day - ( $date as xs:anyAtomicType? ) as xs:date? { - - xs:date($date) - xs:dayTimeDuration('P1D') - } ; - -declare function functx:remove-attributes-deep - ( $nodes as node()* , - $names as xs:string* ) as node()* { - - for $node in $nodes - return if ($node instance of element()) - then element { node-name($node)} - { $node/@*[not(functx:name-test(name(),$names))], - functx:remove-attributes-deep($node/node(), $names)} - else if ($node instance of document-node()) - then functx:remove-attributes-deep($node/node(), $names) - else $node - } ; - -declare function functx:remove-attributes - ( $elements as element()* , - $names as xs:string* ) as element() { - - for $element in $elements - return element - {node-name($element)} - {$element/@*[not(functx:name-test(name(),$names))], - $element/node() } - } ; - -declare function functx:remove-elements-deep - ( $nodes as node()* , - $names as xs:string* ) as node()* { - - for $node in $nodes - return - if ($node instance of element()) - then if (functx:name-test(name($node),$names)) - then () - else element { node-name($node)} - { $node/@*, - functx:remove-elements-deep($node/node(), $names)} - else if ($node instance of document-node()) - then functx:remove-elements-deep($node/node(), $names) - else $node - } ; - -declare function functx:remove-elements-not-contents - ( $nodes as node()* , - $names as xs:string* ) as node()* { - - for $node in $nodes - return - if ($node instance of element()) - then if (functx:name-test(name($node),$names)) - then functx:remove-elements-not-contents($node/node(), $names) - else element {node-name($node)} - {$node/@*, - functx:remove-elements-not-contents($node/node(),$names)} - else if ($node instance of document-node()) - then functx:remove-elements-not-contents($node/node(), $names) - else $node - } ; - -declare function functx:remove-elements - ( $elements as element()* , - $names as xs:string* ) as element()* { - - for $element in $elements - return element - {node-name($element)} - {$element/@*, - $element/node()[not(functx:name-test(name(),$names))] } - } ; - -declare function functx:repeat-string - ( $stringToRepeat as xs:string? , - $count as xs:integer ) as xs:string { - - string-join((for $i in 1 to $count return $stringToRepeat), - '') - } ; - -declare function functx:replace-beginning - ( $arg as xs:string? , - $pattern as xs:string , - $replacement as xs:string ) as xs:string { - - replace($arg, concat('^.*?', $pattern), $replacement) - } ; - -declare function functx:replace-element-values - ( $elements as element()* , - $values as xs:anyAtomicType* ) as element()* { - - for $element at $seq in $elements - return element { node-name($element)} - { $element/@*, - $values[$seq] } - } ; - -declare function functx:replace-first - ( $arg as xs:string? , - $pattern as xs:string , - $replacement as xs:string ) as xs:string { - - replace($arg, concat('(^.*?)', $pattern), - concat('$1',$replacement)) - } ; - -declare function functx:replace-multi - ( $arg as xs:string? , - $changeFrom as xs:string* , - $changeTo as xs:string* ) as xs:string? { - - if (count($changeFrom) > 0) - then functx:replace-multi( - replace($arg, $changeFrom[1], - functx:if-absent($changeTo[1],'')), - $changeFrom[position() > 1], - $changeTo[position() > 1]) - else $arg - } ; - -declare function functx:reverse-string - ( $arg as xs:string? ) as xs:string { - - codepoints-to-string(reverse(string-to-codepoints($arg))) - } ; - -declare function functx:right-trim - ( $arg as xs:string? ) as xs:string { - - replace($arg,'\s+$','') - } ; - -declare function functx:scheme-from-uri - ( $uri as xs:string? ) as xs:string? { - - substring-before($uri,':') - } ; - -declare function functx:sequence-deep-equal - ( $seq1 as item()* , - $seq2 as item()* ) as xs:boolean { - - every $i in 1 to max((count($seq1),count($seq2))) - satisfies deep-equal($seq1[$i],$seq2[$i]) - } ; - -declare function functx:sequence-node-equal-any-order - ( $seq1 as node()* , - $seq2 as node()* ) as xs:boolean { - - not( ($seq1 except $seq2, $seq2 except $seq1)) - } ; - -declare function functx:sequence-node-equal - ( $seq1 as node()* , - $seq2 as node()* ) as xs:boolean { - - every $i in 1 to max((count($seq1),count($seq2))) - satisfies $seq1[$i] is $seq2[$i] - } ; - -declare function functx:sequence-type - ( $items as item()* ) as xs:string { - -concat( - if (empty($items)) - then 'empty-sequence()' - else if (every $val in $items - satisfies $val instance of xs:anyAtomicType) - then if (count(distinct-values(functx:atomic-type($items))) - > 1) - then 'xs:anyAtomicType' - else functx:atomic-type($items[1]) - else if (some $val in $items - satisfies $val instance of xs:anyAtomicType) - then 'item()' - else if (count(distinct-values(functx:node-kind($items))) > 1) - then 'node()' - else concat(functx:node-kind($items[1]),'()') - , - if (count($items) > 1) - then '+' else '') - } ; - -declare function functx:siblings-same-name - ( $element as element()? ) as element()* { - - $element/../*[node-name(.) = node-name($element)] - except $element - } ; - -declare function functx:siblings - ( $node as node()? ) as node()* { - - $node/../node() except $node - } ; - -declare function functx:sort-as-numeric - ( $seq as item()* ) as item()* { - - for $item in $seq - order by number($item) - return $item - } ; - -declare function functx:sort-case-insensitive - ( $seq as item()* ) as item()* { - - for $item in $seq - order by upper-case(string($item)) - return $item - } ; - -declare function functx:sort-document-order - ( $seq as node()* ) as node()* { - - $seq/. - } ; - -declare function functx:sort - ( $seq as item()* ) as item()* { - - for $item in $seq - order by $item - return $item - } ; - -declare function functx:substring-after-if-contains - ( $arg as xs:string? , - $delim as xs:string ) as xs:string? { - - if (contains($arg,$delim)) - then substring-after($arg,$delim) - else $arg - } ; - -declare function functx:substring-after-last-match - ( $arg as xs:string? , - $regex as xs:string ) as xs:string { - - replace($arg,concat('^.*',$regex),'') - } ; - -declare function functx:substring-after-last - ( $arg as xs:string? , - $delim as xs:string ) as xs:string { - - replace ($arg,concat('^.*',functx:escape-for-regex($delim)),'') - } ; - -declare function functx:substring-after-match - ( $arg as xs:string? , - $regex as xs:string ) as xs:string? { - - replace($arg,concat('^.*?',$regex),'') - } ; - -declare function functx:substring-before-if-contains - ( $arg as xs:string? , - $delim as xs:string ) as xs:string? { - - if (contains($arg,$delim)) - then substring-before($arg,$delim) - else $arg - } ; - -declare function functx:substring-before-last-match - ( $arg as xs:string? , - $regex as xs:string ) as xs:string? { - - replace($arg,concat('^(.*)',$regex,'.*'),'$1') - } ; - -declare function functx:substring-before-last - ( $arg as xs:string? , - $delim as xs:string ) as xs:string { - - if (matches($arg, functx:escape-for-regex($delim))) - then replace($arg, - concat('^(.*)', functx:escape-for-regex($delim),'.*'), - '$1') - else '' - } ; - -declare function functx:substring-before-match - ( $arg as xs:string? , - $regex as xs:string ) as xs:string { - - tokenize($arg,$regex)[1] - } ; - -declare function functx:time - ( $hour as xs:anyAtomicType , - $minute as xs:anyAtomicType , - $second as xs:anyAtomicType ) as xs:time { - - xs:time( - concat( - functx:pad-integer-to-length(xs:integer($hour),2),':', - functx:pad-integer-to-length(xs:integer($minute),2),':', - functx:pad-integer-to-length(xs:integer($second),2))) - } ; - -declare function functx:timezone-from-duration - ( $duration as xs:dayTimeDuration ) as xs:string { - - if (string($duration) = ('PT0S','-PT0S')) - then 'Z' - else if (matches(string($duration),'-PT[1-9]H')) - then replace(string($duration),'PT([1-9])H','0$1:00') - else if (matches(string($duration),'PT[1-9]H')) - then replace(string($duration),'PT([1-9])H','+0$1:00') - else if (matches(string($duration),'-PT1[0-4]H')) - then replace(string($duration),'PT(1[0-4])H','$1:00') - else if (matches(string($duration),'PT1[0-4]H')) - then replace(string($duration),'PT(1[0-4])H','+$1:00') - else error(xs:QName('functx:Invalid_Duration_Value')) - } ; - -declare function functx:total-days-from-duration - ( $duration as xs:dayTimeDuration? ) as xs:decimal? { - - $duration div xs:dayTimeDuration('P1D') - } ; - -declare function functx:total-hours-from-duration - ( $duration as xs:dayTimeDuration? ) as xs:decimal? { - - $duration div xs:dayTimeDuration('PT1H') - } ; - -declare function functx:total-minutes-from-duration - ( $duration as xs:dayTimeDuration? ) as xs:decimal? { - - $duration div xs:dayTimeDuration('PT1M') - } ; - -declare function functx:total-months-from-duration - ( $duration as xs:yearMonthDuration? ) as xs:decimal? { - - $duration div xs:yearMonthDuration('P1M') - } ; - -declare function functx:total-seconds-from-duration - ( $duration as xs:dayTimeDuration? ) as xs:decimal? { - - $duration div xs:dayTimeDuration('PT1S') - } ; - -declare function functx:total-years-from-duration - ( $duration as xs:yearMonthDuration? ) as xs:decimal? { - - $duration div xs:yearMonthDuration('P1Y') - } ; - -declare function functx:trim - ( $arg as xs:string? ) as xs:string { - - replace(replace($arg,'\s+$',''),'^\s+','') - } ; - -declare function functx:update-attributes - ( $elements as element()* , - $attrNames as xs:QName* , - $attrValues as xs:anyAtomicType* ) as element()? { - - for $element in $elements - return element { node-name($element)} - { for $attrName at $seq in $attrNames - return if ($element/@*[node-name(.) = $attrName]) - then attribute {$attrName} - {$attrValues[$seq]} - else (), - $element/@*[not(node-name(.) = $attrNames)], - $element/node() } - } ; - -declare function functx:value-except - ( $arg1 as xs:anyAtomicType* , - $arg2 as xs:anyAtomicType* ) as xs:anyAtomicType* { - - distinct-values($arg1[not(.=$arg2)]) - } ; - -declare function functx:value-intersect - ( $arg1 as xs:anyAtomicType* , - $arg2 as xs:anyAtomicType* ) as xs:anyAtomicType* { - - distinct-values($arg1[.=$arg2]) - } ; - -declare function functx:value-union - ( $arg1 as xs:anyAtomicType* , - $arg2 as xs:anyAtomicType* ) as xs:anyAtomicType* { - - distinct-values(($arg1, $arg2)) - } ; - -declare function functx:word-count - ( $arg as xs:string? ) as xs:integer { - - count(tokenize($arg, '\W+')[. != '']) - } ; - -declare function functx:words-to-camel-case - ( $arg as xs:string? ) as xs:string { - - string-join((tokenize($arg,'\s+')[1], - for $word in tokenize($arg,'\s+')[position() > 1] - return functx:capitalize-first($word)) - ,'') - } ; - -declare function functx:wrap-values-in-elements - ( $values as xs:anyAtomicType* , - $elementName as xs:QName ) as element()* { - - for $value in $values - return element {$elementName} {$value} - } ; - -declare function functx:yearMonthDuration - ( $years as xs:decimal? , - $months as xs:integer? ) as xs:yearMonthDuration { - - (xs:yearMonthDuration('P1M') * functx:if-empty($months,0)) + - (xs:yearMonthDuration('P1Y') * functx:if-empty($years,0)) - } ; diff --git a/add/data/xqm/source.xqm b/add/data/xqm/source.xqm index 08c8ccd78..001ab77cb 100644 --- a/add/data/xqm/source.xqm +++ b/add/data/xqm/source.xqm @@ -41,9 +41,13 @@ import module namespace eutil="http://www.edirom.de/xquery/util" at "../xqm/util :) declare function source:isSource($uri as xs:string) as xs:boolean { let $doc := eutil:getDoc($uri) + let $meiVersionRegex := '(([4-9])|(\d+[0-9]))\.\d+\.\d+(-dev)?' return - exists($doc//mei:mei) and exists($doc//mei:source) (:mei2 and ?3 :) - or ($doc//mei:mei/@meiversion = ("4.0.0", "4.0.1") and exists($doc//mei:manifestation[@singleton='true'])) (:mei4 :) + (exists($doc//mei:mei) and exists($doc//mei:source)) (:mei2 and ?3 :) + or + (matches($doc//mei:mei/@meiversion, $meiVersionRegex) and exists($doc//mei:manifestation[@singleton='true'])) (:mei4+ for manuscripts:) + or + (matches($doc//mei:mei/@meiversion, $meiVersionRegex) and exists($doc//mei:manifestation//mei:item)) (: mei4+ for prints :) }; (:~ diff --git a/add/data/xqm/util.xqm b/add/data/xqm/util.xqm index b8eab38fb..d05b1a962 100644 --- a/add/data/xqm/util.xqm +++ b/add/data/xqm/util.xqm @@ -34,7 +34,7 @@ import module namespace work="http://www.edirom.de/xquery/work" at "work.xqm"; import module namespace source="http://www.edirom.de/xquery/source" at "source.xqm"; import module namespace teitext="http://www.edirom.de/xquery/teitext" at "teitext.xqm"; import module namespace edition="http://www.edirom.de/xquery/edition" at "../xqm/edition.xqm"; -import module namespace functx = "http://www.functx.com" at "../xqm/functx-1.0-nodoc-2007-01.xq"; +import module namespace functx = "http://www.functx.com"; import module namespace annotation="http://www.edirom.de/xquery/annotation" at "../xqm/annotation.xqm"; declare namespace request="http://exist-db.org/xquery/request"; @@ -66,7 +66,7 @@ declare function eutil:getNamespace($node as node()) as xs:string { : @return The string :) -declare function eutil:getLocalizedName($node, $lang) as xs:string { +declare function eutil:getLocalizedName($node, $lang) { let $name := if ($node/mei:title) @@ -91,7 +91,9 @@ let $name := then(annotation:generateTitle($node)) else (normalize-space($node)) return - $name => string-join(' ') + if($node/edirom:names) + then($name) + else($name => string-join(' ') => normalize-space()) }; (:~ @@ -106,8 +108,10 @@ declare function eutil:getLocalizedTitle($node as node(), $lang as xs:string?) a let $namespace := eutil:getNamespace($node) - let $titleMEI := if ($lang != '' and $lang = $node/mei:title/@xml:lang) + let $titleMEI := if ($lang != '' and $lang = $node/mei:title/@xml:lang and not($node/mei:title/mei:titlePart)) then ($node/mei:title[@xml:lang = $lang]//text() => string-join() => normalize-space()) + else if ($lang != '' and $lang = $node/mei:title/@xml:lang and $node/mei:title/mei:titlePart) + then ($node/mei:title[@xml:lang = $lang]/mei:titlePart[1]//text() => string-join() => normalize-space()) else (($node//mei:title)[1]//text() => string-join() => normalize-space()) let $titleTEI := if ($lang != '' and $lang = $node/tei:title/@xml:lang) @@ -187,6 +191,37 @@ declare function eutil:getDocumentLabel($doc as xs:string, $edition as xs:string else('') }; +(:~ +: Returns a part's label (translated if available) +: +: @author Dennis Ried +: @param $partID The xml:id of the Part's node() to process +: @return The label (translated if available) +:) +declare function eutil:getPartLabel($measureOrPerfRes as node(), $type as xs:string) as xs:string { + (: request:get-parameter('lang', '') doesn't work?? [DeRi]:) +let $lang := if(request:get-parameter('lang', '') = '') + then('de') + else(request:get-parameter('lang', '')) +let $part := $measureOrPerfRes/ancestor::mei:part +let $voiceRef := $part//mei:staffDef/@decls +let $voiceID := substring-after($voiceRef, '#') + +let $perfResLabel := if($type eq 'measure') + then($measureOrPerfRes/ancestor::mei:mei/id($voiceID)/@label) + else($measureOrPerfRes/@label) +let $dictKey := 'perfMedium.perfRes.' || functx:substring-before-if-contains($perfResLabel,'.') +let $label := if(eutil:getLanguageString($dictKey, (), $lang)) + then(eutil:getLanguageString($dictKey, (), $lang)) + else($perfResLabel) +let $numbering := for $i in subsequence(tokenize($perfResLabel,'\.'),2) + where matches($i, '([0-9])|([ivxIVX])') + return + upper-case($i) +return + normalize-space(string-join(($label, $numbering),' ')) +}; + (:~ : Returns a language specific string : @@ -204,7 +239,7 @@ declare function eutil:getLanguageString($key as xs:string, $values as xs:string : : @param $key The key to search for : @param $values The values to include into the string -: @param $lang The language +: @param $lang The language : @return The string :) declare function eutil:getLanguageString($key as xs:string, $values as xs:string*, $lang as xs:string) as xs:string { @@ -220,7 +255,7 @@ declare function eutil:getLanguageString($key as xs:string, $values as xs:string }; (:~ -: Return a value of preference to key +: Return a value of preference to key : : @param $key The key to search for : @return The string @@ -230,26 +265,24 @@ declare function eutil:getPreference($key as xs:string, $edition as xs:string?) let $file := doc('../prefs/edirom-prefs.xml') let $projectFile := doc(edition:getPreferencesURI($edition)) - return + return if($projectFile != 'null' and $projectFile//entry[@key = $key]) then ($projectFile//entry[@key = $key]/string(@value)) else ($file//entry[@key = $key]/string(@value)) }; (:~ -: Return the application and content language +: Return the application and content language : : @param $edition The edition's path : @return The language key :) declare function eutil:getLanguage($edition as xs:string?) as xs:string { - if(request:get-cookie-names() = 'edirom-language') - then( - request:get-cookie-value('edirom-language') - ) - else( - eutil:getPreference('application_language', $edition) - ) + if (request:get-parameter("lang", "") != "") + then request:get-parameter("lang", "") + else if(request:get-cookie-names() = 'edirom-language') + then request:get-cookie-value('edirom-language') + else eutil:getPreference('application_language', edition:findEdition($edition)) }; (:~ @@ -257,10 +290,10 @@ declare function eutil:getLanguage($edition as xs:string?) as xs:string { : : NB, this is a relative path on the server, missing the scheme, : as well as the server address and port. - : This function simply concats the current context path with the - : eXist variables `$exist:prefix` and `$exist:controller` + : This function simply concats the current context path with the + : eXist variables `$exist:prefix` and `$exist:controller` : (see https://exist-db.org/exist/apps/doc/urlrewrite) - : + : : @return a relative path on the server :) declare function eutil:get-app-base-url() as xs:string? { @@ -279,9 +312,51 @@ declare function eutil:get-app-base-url() as xs:string? { :) declare function eutil:sort-as-numeric-alpha($seq as item()* ) as item()* { for $item in $seq - let $itemPart1 := functx:get-matches($item, '\d+') + let $itemPart1 := (functx:get-matches($item, '\d+'))[1] let $itemPart2 := substring-after($item, $itemPart1) order by number($itemPart1), $itemPart2 return $item } ; + +(:~ + : Extracts an ISO 639 language code from a given ISO 3166-1 language code + : + : @author Benjamin W. Bohl + : @param $iso3166-1 xs:string the given ISO 3166-1 language code, e.g., en-US + : @return xs:string ISO 639 language code, e.g., en + :) +declare function eutil:iso3166-1-to-iso639($iso3166-1 as xs:string) as xs:string { + tokenize($iso3166-1, "-")[1] +}; + +(:~ + : Returns the ISO 639 language code with the highest 'quality' (none cosidered as 1) from + : the HTTP-request Accept-Language header + : + : @author Benjamin W. Bohl + : @return xs:string ISO 639 language code + :) +declare function eutil:request-lang-preferred-iso639() as xs:string { +let $request.accept-language := request:get-header("Accept-Language") +return +if($request.accept-language) +then + let $tokens := tokenize($request.accept-language, ";") + let $tokens.qless.ordered := ( + for $token in $tokens + let $q := substring-after(string-join((analyze-string($token, "(q=\d(\.\d)?)")//fn:match)[1], ""), "q=") + let $q.decimal := if($q = "") then xs:decimal(1) else xs:decimal($q) + let $token.qless := replace($token,",?q=\d(\.\d)?,?", "") + order by $q.decimal descending + return + $token.qless + ) + let $tokens.qmax := $tokens.qless.ordered[1] + let $tokens.qmax.first := tokenize($tokens.qmax, ",")[1] + return + eutil:iso3166-1-to-iso639($tokens.qmax.first) + +else + "en" +}; diff --git a/add/data/xqm/work.xqm b/add/data/xqm/work.xqm index 7e384ec8a..d167c8468 100644 --- a/add/data/xqm/work.xqm +++ b/add/data/xqm/work.xqm @@ -41,14 +41,14 @@ declare namespace edirom="http://www.edirom.de/ns/1.3"; :) declare function work:toJSON($uri as xs:string, $edition as xs:string) as xs:string { - let $work := doc($uri)/mei:mei + let $work := doc($uri)/mei:mei | doc($uri)/mei:work let $lang := request:get-parameter('lang', '') return concat(' {', 'id: "', $work/string(@xml:id), '", ', 'doc: "', $uri, '", ', - 'title: "', replace(eutil:getLocalizedTitle($work//mei:work, $lang), '"', '\\"'), '"', + 'title: "', replace(eutil:getLocalizedTitle((($work/descendant-or-self::mei:work)[1]), $lang), '"', '\\"'), '"', '}') }; @@ -60,7 +60,7 @@ declare function work:toJSON($uri as xs:string, $edition as xs:string) as xs:str :) declare function work:isWork($uri as xs:string) as xs:boolean { - exists(doc($uri)//mei:mei) and exists(doc($uri)//mei:work) and not(doc($uri)//mei:source) + (exists(doc($uri)//mei:mei) and exists(doc($uri)//mei:work) and not(doc($uri)//mei:source)) or exists(doc($uri)/mei:work) }; (:~ @@ -72,7 +72,7 @@ declare function work:isWork($uri as xs:string) as xs:boolean { :) declare function work:getLabel($work as xs:string, $edition as xs:string) as xs:string { - eutil:getLocalizedTitle(doc($work)//mei:work, request:get-parameter('lang', '')) + eutil:getLocalizedTitle(doc($work)/root()//mei:work, request:get-parameter('lang', '')) }; (:~ diff --git a/add/data/xslt/ediromOnline_functions.xsl b/add/data/xslt/ediromOnline_functions.xsl index 961d59306..1f4b00481 100644 --- a/add/data/xslt/ediromOnline_functions.xsl +++ b/add/data/xslt/ediromOnline_functions.xsl @@ -14,7 +14,7 @@ - + diff --git a/add/data/xslt/functx-1.0-nodoc-2007-01.xsl b/add/data/xslt/functx-1.0-nodoc-2007-01.xsl deleted file mode 100644 index c5048f89a..000000000 --- a/add/data/xslt/functx-1.0-nodoc-2007-01.xsl +++ /dev/null @@ -1,1488 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/add/data/xslt/meiP2html.xsl b/add/data/xslt/meiP2html.xsl index 250451425..a6ea54863 100644 --- a/add/data/xslt/meiP2html.xsl +++ b/add/data/xslt/meiP2html.xsl @@ -1,8 +1,5 @@ - + @@ -15,8 +12,45 @@ + + + + + + + + + + + + + +
+ + + +
+ +
+
+
+
+ + + + + + + + +
+ +

@@ -26,6 +60,12 @@

+ + + + + + diff --git a/add/data/xslt/teiBody2HTML.xsl b/add/data/xslt/teiBody2HTML.xsl index a01b527c3..7088b1507 100644 --- a/add/data/xslt/teiBody2HTML.xsl +++ b/add/data/xslt/teiBody2HTML.xsl @@ -3,7 +3,7 @@ xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:exist="http://exist.sourceforge.net/NS/exist" xmlns:functx="http://www.functx.com" exclude-result-prefixes="#default xs tei xhtml" version="2.0"> - + @@ -199,7 +199,7 @@ - + @@ -1085,7 +1085,7 @@ ', {useExisting:true}); return false; - + @@ -1291,4 +1291,4 @@ -
\ No newline at end of file +
diff --git a/add/expath-pkg.xml b/add/expath-pkg.xml index 266f4fd42..c6e477f8d 100755 --- a/add/expath-pkg.xml +++ b/add/expath-pkg.xml @@ -5,4 +5,5 @@ version="@project.version@" spec="1.0"> @project.title@ + \ No newline at end of file diff --git a/add/index.xql b/add/index.xql index 8f8902b62..ddcbf00e9 100755 --- a/add/index.xql +++ b/add/index.xql @@ -126,12 +126,19 @@ let $eoEditionFileMulti :=
    { for $eoEditionFile in $eoEditionFiles + let $editionUri := document-uri($eoEditionFile/root()) let $editionID := $eoEditionFile/string(@xml:id) let $editionName := $eoEditionFile/edirom:editionName/text() => normalize-space() - return + let $editionLanguages := edition:getLanguageCodesSorted($editionUri) + return ( + ) }
diff --git a/add/modules/config.xqm b/add/modules/config.xqm deleted file mode 100755 index 2b14f4213..000000000 --- a/add/modules/config.xqm +++ /dev/null @@ -1,64 +0,0 @@ -(:~ - : A set of helper functions to access the application context from - : within a module. - :) -module namespace config="http://exist-db.org/xquery/apps/config"; - -declare namespace repo="http://exist-db.org/xquery/repo"; -declare namespace expath="http://expath.org/ns/pkg"; - -(: - Determine the application root collection from the current module load path. -:) -declare variable $config:app-root := - let $rawPath := system:get-module-load-path() - let $modulePath := - (: strip the xmldb: part :) - if (starts-with($rawPath, "xmldb:exist://")) then - if (starts-with($rawPath, "xmldb:exist://embedded-eXist-server")) then - substring($rawPath, 36) - else - substring($rawPath, 15) - else - $rawPath - return - substring-before($modulePath, "/modules") -; - -(:~ - : Returns the repo.xml descriptor for the current application. - :) -declare function config:repo-descriptor() as element(repo:meta) { - doc(concat($config:app-root, "/repo.xml"))/repo:meta -}; - -(:~ - : Returns the expath-pkg.xml descriptor for the current application. - :) -declare function config:expath-descriptor() as element(expath:package) { - doc(concat($config:app-root, "/expath-pkg.xml"))/expath:package -}; - -(:~ - : For debugging: generates a table showing all properties defined - : in the application descriptors. - :) -declare function config:app-info($node) { - let $expath := config:expath-descriptor() - let $repo := config:repo-descriptor() - return - - - - - - { - for $attr in ($expath/@*, $expath/*, $repo/*) - return - - - - - } -
app collection:{$config:app-root}
{node-name($attr)}:{$attr/string()}
-}; \ No newline at end of file diff --git a/app/Application.js b/app/Application.js index 2d340823f..f28a016e4 100644 --- a/app/Application.js +++ b/app/Application.js @@ -75,34 +75,34 @@ Ext.define('EdiromOnline.Application', { if(editionParam !== null) me.activeEdition = editionParam; - Ext.Ajax.request({ - url: 'data/xql/getEditionURI.xql', - async: false, - method: 'GET', - params: { + window.doAJAXRequest('data/xql/getEditionURI.xql', + 'GET', + { uri: me.activeEdition - },success: function(response){ - this.activeEdition = response.responseText; }, - scope: this - }); - + Ext.bind(function(response){ + this.activeEdition = response.responseText; + }, this), + 2, // retries + false // async + ); + var workParam = me.getURLParameter('work'); if(workParam !== null) me.activeWork = workParam; - Ext.Ajax.request({ - url: 'data/xql/getWorkID.xql', - async: false, - method: 'GET', - params: { + window.doAJAXRequest('data/xql/getWorkID.xql', + 'GET', + { uri: me.activeEdition, workId: me.activeWork - },success: function(response){ - this.activeWork = response.responseText; }, - scope: this - }); + Ext.bind(function(response){ + this.activeWork = response.responseText; + }, this), + 2, // retries + false // async + ); me.getController('PreferenceController').initPreferences(me.activeEdition); me.getController('LanguageController').initLangFile(me.activeEdition, 'de'); diff --git a/app/controller/AJAXController.js b/app/controller/AJAXController.js index 6db90970b..94573d820 100644 --- a/app/controller/AJAXController.js +++ b/app/controller/AJAXController.js @@ -27,19 +27,45 @@ Ext.define('EdiromOnline.controller.AJAXController', { window.doAJAXRequest = Ext.bind(this.doAJAXRequest, this); }, - doAJAXRequest: function(url, method, params, successFn, retryNo) { + /** + * Performs an AJAX request. + * + * @param {String} url The URL of the requestet site or end point. + * @param {String} method The HTTP method like 'PUT', 'GET', 'POST'. + * @param {Object} params An object containing key-value-pairs of parameters for the request. + * @param {Function} successFn A callback function which is called when the AJAX request was successfull. + * @param {Number} retryNo The number of retries, if the requests fails. Standard is 2 retries. + * @param {Boolean} async Defines the async parameter for AJAX calls. Default is 'true'. + */ + doAJAXRequest: function(url, method, params, successFn, retryNo, async) { var me = this; var editionId = this.application.activeEdition; params = Ext.applyIf(params, {edition: editionId}); - var override = window.getPreference(url, true); + var lang = window.getLanguage(); + params = Ext.applyIf(params, {lang: lang}); + + // define some requests that will make Edirom Online fail if it looks for an override + var doNotOverride = [ + 'data/xql/getEditionURI.xql', + 'data/xql/getPreferences.xql', + 'data/xql/getWorkID.xql', + ]; + + var override = null; + + if(doNotOverride.indexOf(url) == -1) + override = window.getPreference(url, true); if(override != null) url = override; - if(typeof(retryNo) === 'undefined') + if(typeof retryNo === 'undefined') retryNo = 2; + + if(typeof async === 'undefined') + async = true; var fn = Ext.bind(function(response, options, retryNoInt) { @@ -58,7 +84,8 @@ Ext.define('EdiromOnline.controller.AJAXController', { url: url, method: method, params: params, - success: fn + success: fn, + async: async }); } }); \ No newline at end of file diff --git a/app/controller/LanguageController.js b/app/controller/LanguageController.js index 14741d0ae..6df3c0039 100644 --- a/app/controller/LanguageController.js +++ b/app/controller/LanguageController.js @@ -35,20 +35,19 @@ Ext.define('EdiromOnline.controller.LanguageController', { initLangFile: function(editionURI, lang) { - Ext.Ajax.request({ - url: 'data/xql/getLanguageFile.xql', - async: false, - method: 'GET', - params: { + window.doAJAXRequest('data/xql/getLanguageFile.xql', + 'GET', + { lang: lang, mode: 'json', edition: editionURI - },success: function(response){ - - this.langFiles.add(lang, Ext.JSON.decode(response.responseText)); }, - scope: this - }); + Ext.bind(function(response){ + this.langFiles.add(lang, Ext.JSON.decode(response.responseText)); + }, this), + 2, // retries + false // async + ); }, getLanguageString: function(key) { diff --git a/app/controller/LinkController.js b/app/controller/LinkController.js index 23cbc0d53..794818d98 100644 --- a/app/controller/LinkController.js +++ b/app/controller/LinkController.js @@ -156,18 +156,16 @@ Ext.define('EdiromOnline.controller.LinkController', { if(singleUri.indexOf('#') != -1) { - Ext.Ajax.request({ - url: 'data/xql/getInternalIdType.xql', - method: 'GET', - params: { + window.doAJAXRequest('data/xql/getInternalIdType.xql', + 'GET', + { uri: singleUri }, - success: function(response){ + Ext.bind(function(response){ win.loadInternalId(singleUri.split('#')[1], response.responseText.trim()); win.show(); - }, - scope: this - }); + }, this) + ); }else win.showView('summaryView'); diff --git a/app/controller/PreferenceController.js b/app/controller/PreferenceController.js index 5669b75e7..c4e5d86a9 100644 --- a/app/controller/PreferenceController.js +++ b/app/controller/PreferenceController.js @@ -30,18 +30,18 @@ Ext.define('EdiromOnline.controller.PreferenceController', { initPreferences: function(editionURI) { - Ext.Ajax.request({ - url: 'data/xql/getPreferences.xql', - async: false, - method: 'GET', - params: { + window.doAJAXRequest('data/xql/getPreferences.xql', + 'GET', + { mode: 'json', edition: editionURI - },success: function(response){ - this.setPreferences(Ext.JSON.decode(response.responseText)); }, - scope: this - }); + Ext.bind(function(response){ + this.setPreferences(Ext.JSON.decode(response.responseText)); + }, this), + 2, // retries + false // async + ); }, setPreferences: function(preferences) { @@ -50,14 +50,14 @@ Ext.define('EdiromOnline.controller.PreferenceController', { for(var key in me.preferences) { if(key.indexOf('plugin_') == 0) - Ext.Ajax.request({ - url: me.preferences[key], - method: 'GET', - success: function(response){ + + window.doAJAXRequest(me.preferences[key], + 'GET', + {}, + Ext.bind(function(response){ eval(response.responseText); - }, - scope: this - }); + }, this) + ); } }, diff --git a/app/controller/navigator/Navigator.js b/app/controller/navigator/Navigator.js index 784f86de0..52e645973 100644 --- a/app/controller/navigator/Navigator.js +++ b/app/controller/navigator/Navigator.js @@ -47,24 +47,22 @@ Ext.define('EdiromOnline.controller.navigator.Navigator', { var editionId = this.application.activeEdition; var lang = window.getLanguage('application_language'); - Ext.Ajax.request({ - url: 'data/xql/getNavigatorConfig.xql', - params: { + window.doAJAXRequest('data/xql/getNavigatorConfig.xql', + 'GET', + { editionId: editionId, workId: workId, lang: lang }, - success: function(response){ - + Ext.bind(function(response){ this.navigatorContents.add(workId, response.responseText); Ext.Array.each(this.navigators, function(navigator) { navigator.body.update(this.getNavigatorContent(workId)); navigator.setLoading(false); }, this); - }, - scope: this - }); + }, this) + ); }, getNavigatorContent: function(workId) { diff --git a/app/controller/window/HeaderView.js b/app/controller/window/HeaderView.js index e08ee87f6..e48adac7f 100644 --- a/app/controller/window/HeaderView.js +++ b/app/controller/window/HeaderView.js @@ -42,17 +42,15 @@ Ext.define('EdiromOnline.controller.window.HeaderView', { var uri = view.uri; var type = view.type; - Ext.Ajax.request({ - url: 'data/xql/getHeader.xql', - method: 'GET', - params: { + window.doAJAXRequest('data/xql/getHeader.xql', + 'GET', + { uri: uri, type: type }, - success: function(response){ + Ext.bind(function(response){ view.setContent(response.responseText); - }, - scope: this - }); + }, this) + ); } }); diff --git a/app/controller/window/SummaryView.js b/app/controller/window/SummaryView.js index e60519c8b..e7c911e27 100644 --- a/app/controller/window/SummaryView.js +++ b/app/controller/window/SummaryView.js @@ -43,20 +43,18 @@ Ext.define('EdiromOnline.controller.window.SummaryView', { var app = EdiromOnline.getApplication(); var activeEdition = app.activeEdition - Ext.Ajax.request({ - url: 'data/xql/getSummary.xql', - method: 'GET', - params: { - uri: uri, + window.doAJAXRequest('data/xql/getSummary.xql', + 'GET', + { + uri: uri, type: type, edition: activeEdition - }, - success: function (response) { - var data = response.responseText; + }, + Ext.bind(function(response){ + var data = response.responseText; view.setContent(data); - }, - scope: this - }); + }, this) + ); } }); \ No newline at end of file diff --git a/app/controller/window/XmlView.js b/app/controller/window/XmlView.js index f8d4b03f3..c1bf4bd4a 100644 --- a/app/controller/window/XmlView.js +++ b/app/controller/window/XmlView.js @@ -47,18 +47,16 @@ Ext.define('EdiromOnline.controller.window.XmlView', { var uri = xmlview.uri; var internalId = xmlview.internalId; - Ext.Ajax.request({ - url: 'data/xql/getXml.xql', - method: 'GET', - params: { + window.doAJAXRequest('data/xql/getXml.xql', + 'GET', + { uri: uri, internalId: internalId }, - success: function(response){ + Ext.bind(function(response){ xmlview.setXmlContent(response.responseText); - }, - scope: this - }); + }, this) + ); }, resize: function(xmlview, width, height){ diff --git a/app/controller/window/iFrameView.js b/app/controller/window/iFrameView.js index a8bba086f..b0c4a0e85 100644 --- a/app/controller/window/iFrameView.js +++ b/app/controller/window/iFrameView.js @@ -41,16 +41,14 @@ Ext.define('EdiromOnline.controller.window.iFrameView', { var uri = view.uri; - Ext.Ajax.request({ - url: 'data/xql/getiFrameURL.xql', - method: 'GET', - params: { + window.doAJAXRequest('data/xql/getiFrameURL.xql', + 'GET', + { uri: uri }, - success: function(response){ + Ext.bind(function(response){ view.setContent(response.responseText); - }, - scope: this - }); + }, this) + ); } }); diff --git a/app/controller/window/source/MeasureBasedView.js b/app/controller/window/source/MeasureBasedView.js index d9f69fb8d..dd051b7e9 100644 --- a/app/controller/window/source/MeasureBasedView.js +++ b/app/controller/window/source/MeasureBasedView.js @@ -68,14 +68,13 @@ Ext.define('EdiromOnline.controller.window.source.MeasureBasedView', { onMdivSelected: function(mdiv, view) { var me = this; - Ext.Ajax.request({ - url: 'data/xql/getMeasures.xql', - method: 'GET', - params: { + window.doAJAXRequest('data/xql/getMeasures.xql', + 'GET', + { uri: view.owner.uri, mdiv: mdiv }, - success: function(response){ + Ext.bind(function(response){ var data = response.responseText; var measures = Ext.create('Ext.data.Store', { @@ -83,8 +82,8 @@ Ext.define('EdiromOnline.controller.window.source.MeasureBasedView', { data: Ext.JSON.decode(data) }); me.measuresLoaded(measures, view); - } - }); + }, this) + ); }, measuresLoaded: function(measures, view) { @@ -98,19 +97,18 @@ Ext.define('EdiromOnline.controller.window.source.MeasureBasedView', { onShowMeasure: function(view, uri, measureId, count) { var me = this; - Ext.Ajax.request({ - url: 'data/xql/getMeasurePage.xql', - method: 'GET', - params: { + window.doAJAXRequest('data/xql/getMeasurePage.xql', + 'GET', + { id: uri, measure: measureId, measureCount: count }, - success: Ext.bind(function(response){ + Ext.bind(function(response){ var data = response.responseText; this.showMeasure(view, uri, measureId, Ext.JSON.decode(data)); }, me) - }); + ); }, showMeasure: function(view, uri, measureId, data) { @@ -128,14 +126,13 @@ Ext.define('EdiromOnline.controller.window.source.MeasureBasedView', { }, fetchMeasures: function(uri, pageId, fn) { - Ext.Ajax.request({ - url: 'data/xql/getMeasuresOnPage.xql', - method: 'GET', - params: { + window.doAJAXRequest('data/xql/getMeasuresOnPage.xql', + 'GET', + { uri: uri, pageId: pageId }, - success: function(response){ + Ext.bind(function(response){ var data = response.responseText; var measures = Ext.create('Ext.data.Store', { @@ -145,8 +142,8 @@ Ext.define('EdiromOnline.controller.window.source.MeasureBasedView', { if(typeof fn == 'function') fn(measures); - } - }); + }, this) + ); }, measuresOnPageLoaded: function(measures, viewer, pageId) { @@ -198,16 +195,15 @@ Ext.define('EdiromOnline.controller.window.source.MeasureBasedView', { if(overlays[overlayId]) { - Ext.Ajax.request({ - url: 'data/xql/getOverlayOnPage.xql', - method: 'GET', - params: { - uri: uri, - pageId: pageId, - overlayId: overlayId - }, - success: function (response) { - var data = response.responseText; + window.doAJAXRequest('data/xql/getOverlayOnPage.xql', + 'GET', + { + uri: uri, + pageId: pageId, + overlayId: overlayId + }, + Ext.bind(function(response){ + var data = response.responseText; if (data.trim() == '') return; @@ -218,8 +214,8 @@ Ext.define('EdiromOnline.controller.window.source.MeasureBasedView', { me.overlayLoaded(viewer, pageId, overlayId, overlay, sourceView); - } - }); + }, this) + ); }else { viewer.removeSVGOverlay(overlayId); } diff --git a/app/controller/window/source/PageBasedView.js b/app/controller/window/source/PageBasedView.js index 0101cd168..7835cf120 100644 --- a/app/controller/window/source/PageBasedView.js +++ b/app/controller/window/source/PageBasedView.js @@ -40,14 +40,13 @@ Ext.define('EdiromOnline.controller.window.source.PageBasedView', { if (view.initialized) return; view.initialized = true; - Ext.Ajax.request({ - url: 'data/xql/getPages.xql', - method: 'GET', - params: { - uri: view.owner.uri - }, - success: function (response) { - var data = response.responseText; + window.doAJAXRequest('data/xql/getPages.xql', + 'GET', + { + uri: view.owner.uri + }, + Ext.bind(function(response){ + var data = response.responseText; var pages = Ext.create('Ext.data.Store', { fields:[ 'id', 'name', 'path', 'width', 'height', 'measures', 'annotations'], @@ -55,8 +54,8 @@ Ext.define('EdiromOnline.controller.window.source.PageBasedView', { }); me.pagesLoaded(pages, view); - } - }); + }, this) + ); }, pagesLoaded: function (pages, view) { @@ -70,16 +69,15 @@ Ext.define('EdiromOnline.controller.window.source.PageBasedView', { if(overlays[overlayId]) { // if visible - Ext.Ajax.request({ - url: 'data/xql/getOverlayOnPage.xql', - method: 'GET', - params: { - uri: uri, - pageId: pageId, - overlayId: overlayId - }, - success: function (response) { - var data = response.responseText; + window.doAJAXRequest('data/xql/getOverlayOnPage.xql', + 'GET', + { + uri: uri, + pageId: pageId, + overlayId: overlayId + }, + Ext.bind(function(response){ + var data = response.responseText; if (data.trim() == '') return; @@ -89,8 +87,8 @@ Ext.define('EdiromOnline.controller.window.source.PageBasedView', { }); me.overlayLoaded(viewer, pageId, overlayId, overlay, sourceView); - } - }); + }, this) + ); }else { viewer.imageViewer.removeSVGOverlay(overlayId); } diff --git a/app/controller/window/source/SourceView.js b/app/controller/window/source/SourceView.js index 6d6281169..a5a7b1606 100644 --- a/app/controller/window/source/SourceView.js +++ b/app/controller/window/source/SourceView.js @@ -53,14 +53,12 @@ Ext.define('EdiromOnline.controller.window.source.SourceView', { ToolsController.addAnnotationVisibilityListener(view.id, Ext.bind(view.checkGlobalAnnotationVisibility, view)); view.checkGlobalAnnotationVisibility(ToolsController.areAnnotationsVisible()); - - Ext.Ajax.request({ - url: 'data/xql/getMovements.xql', - method: 'GET', - params: { + window.doAJAXRequest('data/xql/getMovements.xql', + 'GET', + { uri: view.uri }, - success: function(response){ + Ext.bind(function(response){ var data = response.responseText; var movements = Ext.create('Ext.data.Store', { @@ -69,8 +67,8 @@ Ext.define('EdiromOnline.controller.window.source.SourceView', { }); me.movementsLoaded(movements, view); - } - }); + }, this) + ); window.doAJAXRequest('data/xql/getAnnotationInfos.xql', 'GET', @@ -97,13 +95,12 @@ Ext.define('EdiromOnline.controller.window.source.SourceView', { }, this) ); - Ext.Ajax.request({ - url: 'data/xql/getOverlays.xql', - method: 'GET', - params: { + window.doAJAXRequest('data/xql/getOverlays.xql', + 'GET', + { uri: view.uri }, - success: function(response){ + Ext.bind(function(response){ var data = response.responseText; var overlays = Ext.create('Ext.data.Store', { @@ -112,8 +109,8 @@ Ext.define('EdiromOnline.controller.window.source.SourceView', { }); me.overlaysLoaded(overlays, view); - } - }); + }, this) + ); }, movementsLoaded: function(movements, view) { @@ -131,18 +128,17 @@ Ext.define('EdiromOnline.controller.window.source.SourceView', { onGotoMovement: function(view, movementId) { var me = this; - Ext.Ajax.request({ - url: 'data/xql/getMovementsFirstPage.xql', - method: 'GET', - params: { + window.doAJAXRequest('data/xql/getMovementsFirstPage.xql', + 'GET', + { uri: view.uri, movementId: movementId }, - success: function(response){ + Ext.bind(function(response){ var data = response.responseText; me.gotoMovement(Ext.String.trim(data), view); - } - }); + }, this) + ); }, gotoMovement: function(pageId, view) { @@ -167,14 +163,13 @@ Ext.define('EdiromOnline.controller.window.source.SourceView', { }, fetchMeasures: function(uri, pageId, fn) { - Ext.Ajax.request({ - url: 'data/xql/getMeasuresOnPage.xql', - method: 'GET', - params: { + window.doAJAXRequest('data/xql/getMeasuresOnPage.xql', + 'GET', + { uri: uri, pageId: pageId }, - success: function(response){ + Ext.bind(function(response){ var data = response.responseText; var measures = Ext.create('Ext.data.Store', { @@ -184,8 +179,8 @@ Ext.define('EdiromOnline.controller.window.source.SourceView', { if(typeof fn == 'function') fn(measures); - } - }); + }, this) + ); }, measuresOnPageLoaded: function(measures, view, pageId) { @@ -242,39 +237,35 @@ Ext.define('EdiromOnline.controller.window.source.SourceView', { onGotoMeasureByName: function (view, measure, movementId) { var me = this; - Ext.Ajax.request({ - url: 'data/xql/getMeasurePage.xql', - method: 'GET', - params: { - id: view.uri, + window.doAJAXRequest('data/xql/getMeasurePage.xql', + 'GET', + { + id: view.uri, measure: measure, movementId: movementId - }, - success: Ext.bind(function (response) { - var data = response.responseText; + }, + Ext.bind(function(response){ + var data = response.responseText; this.gotoMeasure(Ext.JSON.decode(data)[0], view); - }, - me) - }); + }, me) + ); }, onGotoMeasure: function (view, measureId) { var me = this; - Ext.Ajax.request({ - url: 'data/xql/getMeasure.xql', - method: 'GET', - params: { - id: view.uri, + window.doAJAXRequest('data/xql/getMeasure.xql', + 'GET', + { + id: view.uri, measureId: measureId - }, - success: Ext.bind(function (response) { - var data = response.responseText; + }, + Ext.bind(function(response){ + var data = response.responseText; this.gotoMeasure(Ext.JSON.decode(data), view); - }, - me) - }); + }, me) + ); }, gotoMeasure: function (result, view) { @@ -293,19 +284,17 @@ Ext.define('EdiromOnline.controller.window.source.SourceView', { var me = this; - Ext.Ajax.request({ - url: 'data/xql/getZone.xql', - method: 'GET', - params: { - uri: view.uri, + window.doAJAXRequest('data/xql/getZone.xql', + 'GET', + { + uri: view.uri, zoneId: zoneId - }, - success: Ext.bind(function (response) { - var data = response.responseText; + }, + Ext.bind(function(response){ + var data = response.responseText; this.gotoZone(Ext.JSON.decode(data), view); - }, - me) - }); + }, this) + ); }, gotoZone: function (result, view) { diff --git a/app/controller/window/source/VerovioView.js b/app/controller/window/source/VerovioView.js index e0fd376c7..fb79c506d 100644 --- a/app/controller/window/source/VerovioView.js +++ b/app/controller/window/source/VerovioView.js @@ -44,14 +44,13 @@ Ext.define('EdiromOnline.controller.window.source.VerovioView', { view.on('gotoMeasureByName', me.onGotoMeasureByName, me); view.on('gotoMeasure', me.onGotoMeasure, me); - Ext.Ajax.request({ - url: 'data/xql/getMovements.xql', - method: 'GET', - params: { - uri: view.uri - }, - success: function (response) { - var data = response.responseText; + window.doAJAXRequest('data/xql/getMovements.xql', + 'GET', + { + uri: view.uri + }, + Ext.bind(function(response){ + var data = response.responseText; var movements = Ext.create('Ext.data.Store', { fields:[ 'id', 'name'], @@ -59,8 +58,8 @@ Ext.define('EdiromOnline.controller.window.source.VerovioView', { }); me.movementsLoaded(movements, view); - } - }); + }, this) + ); }, movementsLoaded: function (movements, view) { @@ -70,39 +69,35 @@ Ext.define('EdiromOnline.controller.window.source.VerovioView', { onGotoMeasureByName: function (view, measure, movementId) { var me = this; - Ext.Ajax.request({ - url: 'data/xql/getMeasurePage.xql', - method: 'GET', - params: { - id: view.uri, + window.doAJAXRequest('data/xql/getMeasurePage.xql', + 'GET', + { + id: view.uri, measure: measure, movementId: movementId - }, - success: Ext.bind(function (response) { - var data = response.responseText; + }, + Ext.bind(function(response){ + var data = response.responseText; this.gotoMeasure(Ext.JSON.decode(data)[0], view); - }, - me) - }); + }, me) + ); }, onGotoMeasure: function (view, measureId) { var me = this; - Ext.Ajax.request({ - url: 'data/xql/getMeasure.xql', - method: 'GET', - params: { - id: view.uri, + window.doAJAXRequest('data/xql/getMeasure.xql', + 'GET', + { + id: view.uri, measureId: measureId - }, - success: Ext.bind(function (response) { - var data = response.responseText; + }, + Ext.bind(function(response){ + var data = response.responseText; this.gotoMeasure(Ext.JSON.decode(data), view); - }, - me) - }); + }, me) + ); }, gotoMeasure: function (result, view) { diff --git a/app/controller/window/text/FacsimileView.js b/app/controller/window/text/FacsimileView.js index b15bb7a47..642fc00d3 100644 --- a/app/controller/window/text/FacsimileView.js +++ b/app/controller/window/text/FacsimileView.js @@ -44,13 +44,12 @@ Ext.define('EdiromOnline.controller.window.text.FacsimileView', { var uri = view.uri; - Ext.Ajax.request({ - url: 'data/xql/getPages.xql', - method: 'GET', - params: { + window.doAJAXRequest('data/xql/getPages.xql', + 'GET', + { uri: uri }, - success: function(response){ + Ext.bind(function(response){ var data = response.responseText; var pages = Ext.create('Ext.data.Store', { @@ -59,17 +58,16 @@ Ext.define('EdiromOnline.controller.window.text.FacsimileView', { }); view.setImageSet(pages); - } - }); + }, this) + ); - Ext.Ajax.request({ - url: 'data/xql/getChapters.xql', - method: 'GET', - params: { + window.doAJAXRequest('data/xql/getChapters.xql', + 'GET', + { uri: view.uri, mode: 'pageMode' }, - success: function(response){ + Ext.bind(function(response){ var data = response.responseText; var chapters = Ext.create('Ext.data.Store', { @@ -78,8 +76,8 @@ Ext.define('EdiromOnline.controller.window.text.FacsimileView', { }); me.chaptersLoaded(chapters, view); - } - }); + }, this) + ); }, chaptersLoaded: function(chapters, view) { diff --git a/app/controller/window/text/TextFacsimileSplitView.js b/app/controller/window/text/TextFacsimileSplitView.js index 1d47b36d4..e05b08aae 100644 --- a/app/controller/window/text/TextFacsimileSplitView.js +++ b/app/controller/window/text/TextFacsimileSplitView.js @@ -50,13 +50,12 @@ Ext.define('EdiromOnline.controller.window.text.TextFacsimileSplitView', { var uri = view.uri; - Ext.Ajax.request({ - url: 'data/xql/getPages.xql', - method: 'GET', - params: { + window.doAJAXRequest('data/xql/getPages.xql', + 'GET', + { uri: uri }, - success: function(response){ + Ext.bind(function(response){ var data = response.responseText; var pages = Ext.create('Ext.data.Store', { @@ -65,17 +64,16 @@ Ext.define('EdiromOnline.controller.window.text.TextFacsimileSplitView', { }); view.setImageSet(pages); - } - }); + }, this) + ); - Ext.Ajax.request({ - url: 'data/xql/getChapters.xql', - method: 'GET', - params: { + window.doAJAXRequest('data/xql/getChapters.xql', + 'GET', + { uri: view.uri, mode: 'pageMode' }, - success: function(response){ + Ext.bind(function(response){ var data = response.responseText; var chapters = Ext.create('Ext.data.Store', { @@ -84,8 +82,8 @@ Ext.define('EdiromOnline.controller.window.text.TextFacsimileSplitView', { }); me.chaptersLoaded(chapters, view); - } - }); + }, this) + ); }, onAfterImageChanged: function(view) { @@ -148,14 +146,13 @@ Ext.define('EdiromOnline.controller.window.text.TextFacsimileSplitView', { var me = this; if(visible) - Ext.Ajax.request({ - url: 'data/xql/getAnnotationsInText.xql', - method: 'GET', - params: { + window.doAJAXRequest('data/xql/getAnnotationsInText.xql', + 'GET', + { uri: view.uri, page: view.getActivePage() }, - success: function(response){ + Ext.bind(function(response){ var data = response.responseText; var annotations = Ext.create('Ext.data.Store', { @@ -164,9 +161,8 @@ Ext.define('EdiromOnline.controller.window.text.TextFacsimileSplitView', { }); me.annotationsLoaded(annotations, view); - } - }); - + }, this) + ); else view.hideAnnotations(); }, diff --git a/app/controller/window/text/TextView.js b/app/controller/window/text/TextView.js index f780d1851..d40bae8e5 100644 --- a/app/controller/window/text/TextView.js +++ b/app/controller/window/text/TextView.js @@ -69,13 +69,12 @@ Ext.define('EdiromOnline.controller.window.text.TextView', { view.setContent(content); - Ext.Ajax.request({ - url: 'data/xql/getChapters.xql', - method: 'GET', - params: { + window.doAJAXRequest('data/xql/getChapters.xql', + 'GET', + { uri: view.uri }, - success: function(response){ + Ext.bind(function(response){ var data = response.responseText; var chapters = Ext.create('Ext.data.Store', { @@ -84,8 +83,8 @@ Ext.define('EdiromOnline.controller.window.text.TextView', { }); me.chaptersLoaded(chapters, view); - } - }); + }, this) + ); window.doAJAXRequest('data/xql/getAnnotationInfos.xql', 'GET', @@ -121,13 +120,12 @@ Ext.define('EdiromOnline.controller.window.text.TextView', { var me = this; if(visible) - Ext.Ajax.request({ - url: 'data/xql/getAnnotationsInText.xql', - method: 'GET', - params: { + window.doAJAXRequest('data/xql/getAnnotationsInText.xql', + 'GET', + { uri: view.uri }, - success: function(response){ + Ext.bind(function(response){ var data = response.responseText; var annotations = Ext.create('Ext.data.Store', { @@ -136,9 +134,8 @@ Ext.define('EdiromOnline.controller.window.text.TextView', { }); me.annotationsLoaded(annotations, view); - } - }); - + }, this) + ); else view.hideAnnotations(); }, diff --git a/app/view/window/AnnotationView.js b/app/view/window/AnnotationView.js index 97f18033a..74d95e4c0 100644 --- a/app/view/window/AnnotationView.js +++ b/app/view/window/AnnotationView.js @@ -753,17 +753,17 @@ Ext.define('EdiromOnline.view.window.AnnotationView', { var uri = txtData.match(/uri:(.*)__\$\$__/)[1]; var id = txtData.match(/__\$\$__participantId:(.*)/)[1]; - Ext.Ajax.request({ - url: 'data/xql/getReducedDocument.xql?uri=' + uri + '&selectionId=' + id + '&subtreeRoot=div&idPrefix=' + me.id + '_', - success: function(response){ + window.doAJAXRequest('data/xql/getReducedDocument.xql?uri=' + uri + '&selectionId=' + id + '&subtreeRoot=div&idPrefix=' + me.id + '_', + 'GET', + {}, + Ext.bind(function(response){ var contEl = this.el.getById(me.id + '_annotationParticipantsSingle'); var txtBox = new Ext.Element(contEl.query('div.txtBox')[0]); txtBox.update(response.responseText); contEl.query('#' + this.id + '_' + id)[0].scrollIntoView(txtBox); - }, - scope: me - }); + }, me) + ); }, previousParticipantSingle: function() { diff --git a/app/view/window/image/ImageViewer.js b/app/view/window/image/ImageViewer.js index 82d22254e..f4bf27ac1 100644 --- a/app/view/window/image/ImageViewer.js +++ b/app/view/window/image/ImageViewer.js @@ -46,6 +46,7 @@ Ext.define('EdiromOnline.view.window.image.ImageViewer', { shapes: null, shapesHidden: false, + partLabel: null, svgOverlays: null, annotSVGOverlays: null, @@ -65,10 +66,30 @@ Ext.define('EdiromOnline.view.window.image.ImageViewer', { me.addEvents('zoomChanged', 'imageChanged'); - - me.html = '
' + - '
'; - + +/* from OPERA*/ + var facsContEvents; + + if (me.partLabel != null) { + facsContEvents = '
' + + '
' + + '' + + me.partLabel + '' + + '
' + + '
'; + } + else { + facsContEvents = '
'; + }; + + me.html = '
' + facsContEvents; + +/* from OPERA END*/ + +/* */ +/* me.html = '
' +*/ +/* '
';*/ +/* */ me.imageLoader = new EdiromOnline.view.window.image.ImageLoader({ viewer: me }); diff --git a/app/view/window/image/LeafletFacsimile.js b/app/view/window/image/LeafletFacsimile.js index ffb198a72..ed933f676 100644 --- a/app/view/window/image/LeafletFacsimile.js +++ b/app/view/window/image/LeafletFacsimile.js @@ -303,32 +303,28 @@ Ext.define('EdiromOnline.view.window.image.LeafletFacsimile', { var me = this; rectangleCenter.on('mouseover', function (e) { - Ext.Ajax.request({ - url: 'data/xql/getAnnotation.xql', - method: 'GET', - params: { - uri: annotURI, - target: 'tip', - edition: EdiromOnline.getApplication().activeEdition - }, - success: function(response){ - //this.update(response.responseText); - me.facsimileTile.disableRectangle(); - me.facsimileTile.enableRectangle(ulx, uly, lrx, lry, true); - //rect_tmp = me.facsimileTile.createPupup(ulx, uly, lrx, lry, rectangleCenter , response.responseText); - var overview = response.responseText; - var test = $(overview).html(); - tooltip.setHtml(test); + window.doAJAXRequest('data/xql/getAnnotation.xql', + 'GET', + { + uri: annotURI, + target: 'tip', + edition: EdiromOnline.getApplication().activeEdition + }, + Ext.bind(function(response){ + //this.update(response.responseText); + me.facsimileTile.disableRectangle(); + me.facsimileTile.enableRectangle(ulx, uly, lrx, lry, true); + //rect_tmp = me.facsimileTile.createPupup(ulx, uly, lrx, lry, rectangleCenter , response.responseText); + var overview = response.responseText; + var test = $(overview).html(); + tooltip.setHtml(test); /*var tooltip = L.tooltip({ target: rectangleCenter, map: me.getMap(), html: response.responseText });*/ - - - } - // scope: this - }); + }, this) + ); }); diff --git a/app/view/window/image/OpenSeaDragonViewer.js b/app/view/window/image/OpenSeaDragonViewer.js index 7bb6d4594..0c6fa75f0 100644 --- a/app/view/window/image/OpenSeaDragonViewer.js +++ b/app/view/window/image/OpenSeaDragonViewer.js @@ -35,6 +35,7 @@ Ext.define('EdiromOnline.view.window.image.OpenSeaDragonViewer', { imagePrefix: null, shapes: null, + partLabel: null, annotTipWidth: 220, annotTipMaxWidth: 300, @@ -49,11 +50,25 @@ Ext.define('EdiromOnline.view.window.image.OpenSeaDragonViewer', { me.addEvents('zoomChanged', 'imageChanged'); - - me.html = '
'; + + var openseadragonEvents; + + if (me.partLabel != null) { + openseadragonEvents = '
' + + '
' + + '' + + me.partLabel + '' + + '
' + + '
'; + } + else { + openseadragonEvents = '
'; + }; + + me.html = '
' + openseadragonEvents; me.shapes = new Ext.util.MixedCollection(); - + me.callParent(); me.on('afterrender', me.initSurface, me, {single: true}); diff --git a/app/view/window/image/VerovioImage.js b/app/view/window/image/VerovioImage.js index f61c262ca..d22b01b91 100644 --- a/app/view/window/image/VerovioImage.js +++ b/app/view/window/image/VerovioImage.js @@ -18,32 +18,43 @@ */ Ext.define('EdiromOnline.view.window.image.VerovioImage', { extend: 'Ext.panel.Panel', - + layout: 'fit', - + initComponent: function () { - + var me = this; - + me.html = '
'; - + '_rendContIFrame">'; + me.callParent(); }, - + setIFrameURL: function (url) { var me = this; var contEl = me.el.getById(me.id + '_rendContIFrame'); contEl.set({ 'src': url }); - + }, - + showMovement: function (movementId) { var me = this; - + var iframe = Ext.fly(me.id + '_rendContIFrame').dom.contentWindow; iframe.showMovement(movementId); + }, + + /* + * Call showMeasure of corresponding iframe. + * @param {string} movementId - The XML-ID of the selected movement. + * @param {string} measureId - The XML-ID of the selected measure. + */ + showMeasure: function (movementId, measureId) { + var me = this; + var iframe = Ext.fly(me.id + '_rendContIFrame').dom.contentWindow; + iframe.showMeasure(movementId, measureId); } }); diff --git a/app/view/window/source/MeasureBasedView.js b/app/view/window/source/MeasureBasedView.js index 00cf9d4d2..3cc15da77 100644 --- a/app/view/window/source/MeasureBasedView.js +++ b/app/view/window/source/MeasureBasedView.js @@ -225,6 +225,7 @@ Ext.define('EdiromOnline.view.window.source.MeasureBasedView', { Ext.Array.each(me.measures.get('measures'), function(m) { var voice = m['voice']; + var partLabel = m['partLabel']; if(voice == 'score' || me.parts.getById(voice.substr(1)).get('selected')) { @@ -232,7 +233,8 @@ Ext.define('EdiromOnline.view.window.source.MeasureBasedView', { if(typeof viewer == 'undefined') { viewer = Ext.create('EdiromOnline.view.window.source.HorizontalMeasureViewer', { - owner: me + owner: me, + partLabel: partLabel }); me.viewers.add(voice, viewer); @@ -391,6 +393,8 @@ Ext.define('EdiromOnline.view.window.source.HorizontalMeasureViewer', { border: false, + partLabel: '', + style: { borderColor: 'black', borderStyle: 'solid', @@ -417,12 +421,12 @@ Ext.define('EdiromOnline.view.window.source.HorizontalMeasureViewer', { var image_server = getPreference('image_server'); var viewer = null; if(image_server === 'leaflet'){ - viewer = Ext.create('EdiromOnline.view.window.image.LeafletFacsimile', {flex: 1, width: '100%'}); + viewer = Ext.create('EdiromOnline.view.window.image.LeafletFacsimile', {flex: 1, width: '100%', partLabel: me.partLabel}); } else if(image_server === 'openseadragon'){ - viewer = Ext.create('EdiromOnline.view.window.image.OpenSeaDragonViewer', {flex: 1, width: '100%'}); + viewer = Ext.create('EdiromOnline.view.window.image.OpenSeaDragonViewer', {flex: 1, width: '100%', partLabel: me.partLabel}); }else { - viewer = Ext.create('EdiromOnline.view.window.image.ImageViewer', {flex: 1}); + viewer = Ext.create('EdiromOnline.view.window.image.ImageViewer', {flex: 1, partLabel: me.partLabel}); } viewer.on('imageChanged', me.onViewerImageChange, me); diff --git a/app/view/window/source/VerovioView.js b/app/view/window/source/VerovioView.js index d2404b211..86bc6d2a1 100644 --- a/app/view/window/source/VerovioView.js +++ b/app/view/window/source/VerovioView.js @@ -17,110 +17,119 @@ * along with Edirom Online. If not, see . */ Ext.define('EdiromOnline.view.window.source.VerovioView', { - extend: 'EdiromOnline.view.window.View', - - requires:[ - 'EdiromOnline.view.window.image.VerovioImage'], - - alias: 'widget.verovioView', - - layout: 'border', - - border: 0, - bottomBar: null, - - verovioImageView: null, - - cls: 'verovioView', - - initComponent: function () { - - var me = this; - - me.addEvents( - 'gotoMeasure', - 'gotoMeasureByName' - ); - - me.verovioImageView = Ext.create('EdiromOnline.view.window.image.VerovioImage'); - me.viewerContainer = Ext.create('Ext.panel.Panel', { - region: 'center', - border: 0, - layout: 'card', - items: [me.verovioImageView] - }); - - me.items = [ - me.viewerContainer ]; - - me.callParent(); - - me.on('afterrender', me.createMenuEntries, me, {single: true}); - }, - - setIFrameURL: function (url) { - var me = this; - me.verovioImageView.setIFrameURL(url); - }, - - createMenuEntries: function() { + extend: 'EdiromOnline.view.window.View', + + requires:[ + 'EdiromOnline.view.window.image.VerovioImage'], + + alias: 'widget.verovioView', + + layout: 'border', + + border: 0, + bottomBar: null, + + verovioImageView: null, + + cls: 'verovioView', + + initComponent: function () { + + var me = this; + + me.addEvents( + 'gotoMeasure', + 'gotoMeasureByName'); + + me.verovioImageView = Ext.create('EdiromOnline.view.window.image.VerovioImage'); + me.viewerContainer = Ext.create('Ext.panel.Panel', { + region: 'center', + border: 0, + layout: 'card', + items:[me.verovioImageView] + }); + + me.items =[ + me.viewerContainer]; + + me.callParent(); + + me.on('afterrender', me.createMenuEntries, me, { + single: true + }); + }, + + setIFrameURL: function (url) { + var me = this; + me.verovioImageView.setIFrameURL(url); + }, + + createMenuEntries: function () { + + var me = this; + + me.gotoMenu = Ext.create('Ext.button.Button', { + text: getLangString('view.window.source.SourceView_gotoMenu'), + indent: false, + cls: 'menuButton', + menu: { + items:[ { + id: me.id + '_gotoMeasure', + text: getLangString('view.window.source.SourceView_gotoMeasure'), + handler: Ext.bind(me.gotoMeasureDialog, me) + }] + } + }); + me.window.getTopbar().addViewSpecificItem(me.gotoMenu, me.id); + }, + + setMovements: function (movements) { + var me = this; + + me.movements = movements; + + var movementItems =[]; + movements.each(function (movement) { + movementItems.push({ + text: movement. get ('name'), + handler: Ext.bind(me.showMovement, me, movement. get ('id'), true) + }); + }); + + me.gotoMenu.menu.add({ + id: me.id + '_gotoMovement', + text: getLangString('view.window.source.SourceView_gotoMovement'), + menu: { + items: movementItems + } + }); + }, + + showMovement: function (menuItem, event, movementId) { + var me = this; + me.verovioImageView.showMovement(movementId); + }, + + gotoMeasureDialog: function () { + var me = this; + + Ext.create('EdiromOnline.view.window.source.GotoMsg', { + movements: me.movements, + callback: Ext.bind(function (measure, movementId) { + this.fireEvent('gotoMeasureByName', this, measure, movementId); + }, + me) + }).show(); + }, - var me = this; - - me.gotoMenu = Ext.create('Ext.button.Button', { - text: getLangString('view.window.source.SourceView_gotoMenu'), - indent: false, - cls: 'menuButton', - menu : { - items: [ - { - id: me.id + '_gotoMeasure', - text: getLangString('view.window.source.SourceView_gotoMeasure'), - handler: Ext.bind(me.gotoMeasureDialog, me) - } - ] - } - }); - me.window.getTopbar().addViewSpecificItem(me.gotoMenu, me.id); - }, - - setMovements: function(movements) { - var me = this; - - me.movements = movements; - - var movementItems = []; - movements.each(function(movement) { - movementItems.push({ - text: movement.get('name'), - handler: Ext.bind(me.showMovement, me, movement.get('id'), true) - }); - }); - - me.gotoMenu.menu.add({ - id: me.id + '_gotoMovement', - text: getLangString('view.window.source.SourceView_gotoMovement'), - menu: { - items: movementItems - } - }); - }, - - showMovement: function(menuItem, event, movementId) { - var me = this; - me.verovioImageView.showMovement(movementId); - }, - - gotoMeasureDialog: function() { - var me = this; - - Ext.create('EdiromOnline.view.window.source.GotoMsg', { - movements: me.movements, - callback: Ext.bind(function(measure, movementId) { - this.fireEvent('gotoMeasureByName', this, measure, movementId); - }, - me) - }).show(); - }, - -}); + /* + * Call showMeasure of corresponding VerovioImageView. + * @param {string} movementId - The XML-ID of the selected movement. + * @param {string} measureId - The XML-ID of the selected measure. + * @param {number} measureCount - The number of measures to be displayed [currently ignored in VerovioView]. + */ + showMeasure: function(movementId, measureId, measureCount){ + var me = this; + me.verovioImageView.showMeasure(movementId, measureId); + } +}); \ No newline at end of file diff --git a/app/view/window/text/TextFacsimileSplitView.js b/app/view/window/text/TextFacsimileSplitView.js index 325e3ca09..d0605307c 100644 --- a/app/view/window/text/TextFacsimileSplitView.js +++ b/app/view/window/text/TextFacsimileSplitView.js @@ -205,18 +205,16 @@ Ext.define('EdiromOnline.view.window.text.TextFacsimileSplitView', { }); tip.on('afterrender', function() { - Ext.Ajax.request({ - url: 'data/xql/getAnnotation.xql', - method: 'GET', - params: { + window.doAJAXRequest('data/xql/getAnnotation.xql', + 'GET', + { uri: uri, target: 'tip' }, - success: function(response){ + Ext.bind(function(response){ this.update(response.responseText); - }, - scope: this - }); + }, this) + ); }, tip); }, me); diff --git a/app/view/window/text/TextView.js b/app/view/window/text/TextView.js index 7221b9b12..08c6a5364 100644 --- a/app/view/window/text/TextView.js +++ b/app/view/window/text/TextView.js @@ -170,18 +170,16 @@ Ext.define('EdiromOnline.view.window.text.TextView', { }); tip.on('afterrender', function() { - Ext.Ajax.request({ - url: 'data/xql/getAnnotation.xql', - method: 'GET', - params: { + window.doAJAXRequest('data/xql/getAnnotation.xql', + 'GET', + { uri: uri, target: 'tip' }, - success: function(response){ + Ext.bind(function(response){ this.update(response.responseText); - }, - scope: this - }); + }, this) + ); }, tip); }, me); diff --git a/build.xml b/build.xml index 59dd87f9e..80fbf7e27 100755 --- a/build.xml +++ b/build.xml @@ -3,7 +3,7 @@ - + diff --git a/packages/eoTheme/resources/fonts/euryanthe b/packages/eoTheme/resources/fonts/euryanthe new file mode 160000 index 000000000..e7bf03bf4 --- /dev/null +++ b/packages/eoTheme/resources/fonts/euryanthe @@ -0,0 +1 @@ +Subproject commit e7bf03bf4eb304676c411f04028e2a94260fa7bf diff --git a/packages/eoTheme/sass/etc/all.scss b/packages/eoTheme/sass/etc/all.scss index afcb277a4..50a944a2b 100644 --- a/packages/eoTheme/sass/etc/all.scss +++ b/packages/eoTheme/sass/etc/all.scss @@ -1,11 +1,11 @@ -@import 'webfonts.scss'; +@import 'webfonts.scss'; @import 'mixins.scss'; /*Edirom*/ @import 'facsimile.scss'; @import 'xml.scss'; @import 'toolbar.scss'; - + //@import 'textViewContent.scss'; @import 'textView.scss'; @import 'headerView.scss'; @@ -16,4 +16,7 @@ @import 'freidi.scss'; /*Annotations*/ -@import 'annotation.scss'; \ No newline at end of file +@import 'annotation.scss'; + +/*renderingView (Verovio)*/ +@import 'renderingViewContent.scss' diff --git a/packages/eoTheme/sass/etc/annotation.scss b/packages/eoTheme/sass/etc/annotation.scss index 5b55fc5ae..9d4a39f29 100755 --- a/packages/eoTheme/sass/etc/annotation.scss +++ b/packages/eoTheme/sass/etc/annotation.scss @@ -80,6 +80,11 @@ $content_baseFont_size: 14px; font-size: 1.1em; } + .superscript{ + vertical-align: top; + font-size: 0.7em; + } + } .previewArea { diff --git a/packages/eoTheme/sass/etc/renderingViewContent.scss b/packages/eoTheme/sass/etc/renderingViewContent.scss new file mode 100644 index 000000000..a9ef7c70a --- /dev/null +++ b/packages/eoTheme/sass/etc/renderingViewContent.scss @@ -0,0 +1,7 @@ +/* make verovio iFrame fit Edirom window */ +.renderingViewContent, .renderingViewContent iframe { + width: 100%; + height: 100%; + border: none; + overflow: hidden; +} diff --git a/packages/eoTheme/sass/etc/webfonts.scss b/packages/eoTheme/sass/etc/webfonts.scss index 677724129..7588785ad 100644 --- a/packages/eoTheme/sass/etc/webfonts.scss +++ b/packages/eoTheme/sass/etc/webfonts.scss @@ -165,3 +165,24 @@ font-style: normal; } + +@font-face { + font-family: 'euryanthe'; + src: url('fonts/euryanthe/EuryantheRegular.ttf') format('truetype'); + font-weight: normal; + font-style: normal; +} + +@font-face { + font-family: 'euryanthe'; + src: url('fonts/euryanthe/EuryantheBold.ttf') format('truetype'); + font-weight: bold; + font-style: normal; +} + +@font-face { + font-family: 'euryanthe'; + src: url('fonts/euryanthe/EuryantheItalic.ttf') format('truetype'); + font-weight: normal; + font-style: italic; +} diff --git a/resources/css/todo.css b/resources/css/todo.css index d787a79fb..b94fb4654 100644 --- a/resources/css/todo.css +++ b/resources/css/todo.css @@ -223,6 +223,25 @@ span.italic { display: none; } +/* part label in horizontalMeasureViewer */ + +.part { +z-index: 1; +} + +.partInner { +font-size: 13px; +font-weight: bold; +background-image: -moz-linear-gradient(top, rgba(255, 255, 255,0.9),rgba(255, 255, 255,0.8)) !important; +background-image: -webkit-linear-gradient(top, rgba(255, 255, 255,0.9),rgba(255, 255, 255,0.8)) !important; +box-shadow: 3px 3px 5px rgba(0,0,0,0.7); +padding: 2px 5px; +border-radius: 5px; +color: rgba(0,0,0,0.75); +position: absolute; +top: 5px; +left: 10px; + .annotTip { width: 100% !important; } @@ -381,10 +400,4 @@ span#workSwitch-btnInnerEl:before { .x-menu-item-active { background-color: rgb(36, 145, 235) !important; color: rgb(161, 209, 247) !important; -} - -/* Verovio view */ - -.renderingViewContent { - height: 100%; -} +} \ No newline at end of file diff --git a/resources/css/verovio-view.css b/resources/css/verovio-view.css index 333f23ba2..1ba61c69d 100644 --- a/resources/css/verovio-view.css +++ b/resources/css/verovio-view.css @@ -17,7 +17,7 @@ body { left: 0; right: 0; bottom: 0; - background-color: #cccccc; + background-color: rgba(0, 0, 0, 10%); text-align: center; line-height: 2em; } diff --git a/resources/js/verovio-view.js b/resources/js/verovio-view.js index b3397bd6c..6cdb11ef7 100644 --- a/resources/js/verovio-view.js +++ b/resources/js/verovio-view.js @@ -1,6 +1,12 @@ window.vrvToolkit = new verovio.toolkit(); showMovement(movementId); +/* add event as constant */ +const vrvToolkitDataInitialized = new Event("vrvToolkitDataInitialized"); + +/* add event listener to window */ +window.addEventListener('vrvToolkitDataInitialized', (e) => {on_vrvToolkitDataInitialized()}, false); + function showMovement(movementId) { showLoader(); @@ -34,6 +40,8 @@ function initData() { pageCount = vrvToolkit.getPageCount(); updatePageData(); + //dispatch vrvToolkitDataInitialized event + window.dispatchEvent(vrvToolkitDataInitialized); } function updatePageData() { @@ -105,7 +113,46 @@ function nextPage() { updatePageData(); } +/** + * Switch to page as defined by global page variable. + */ +function showPage() { + if(page == 0) return; + var svg = vrvToolkit.renderToSVG(page); + $("#output").html(svg); + updatePageData(); +} + function showLoader() { $("#output").empty(); $(".lds-roller").clone().appendTo("#output"); -} \ No newline at end of file +} + +/** + * Show a measure in verovio if the goto measure function is called from the GUI. + * Calls showMovement() if call to measure doesn't match current movement. + * @param {string} movementId - The XML-ID of the selected movement. + * @param {string} measureId - The XML-ID of the selected measure. + */ +function showMeasure(movementId, measureId) { + + if (measureId == undefined) return; + window.measureId = measureId; + + if(vrvToolkit.getPageWithElement(measureId) == 0) { + showMovement(movementId); + } else if(window.movementId == movementId) { + if (page == vrvToolkit.getPageWithElement(measureId)) return; + page = vrvToolkit.getPageWithElement(measureId); + showPage(); + } +} + +/** + * Callback function on dispatch of vrvToolkitDataInitialized event + */ +function on_vrvToolkitDataInitialized(){ + console.log("event fired and catched"); + if (window.measureId == undefined ) return; + showMeasure(window.movementId, window.measureId); //? set window.measureId to undefined ? +}