From 46b9420ced139c9957f4367a838a60905f602657 Mon Sep 17 00:00:00 2001 From: Dennis Ried Date: Sat, 24 Dec 2022 14:26:16 +0100 Subject: [PATCH 01/51] auto join measure labels if point to same zone --- add/data/xql/getMeasuresOnPage.xql | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/add/data/xql/getMeasuresOnPage.xql b/add/data/xql/getMeasuresOnPage.xql index 4be580089..3a6f4388c 100644 --- a/add/data/xql/getMeasuresOnPage.xql +++ b/add/data/xql/getMeasuresOnPage.xql @@ -57,6 +57,12 @@ declare function local:getMeasures($mei as node(), $surface as node()) as map(*) let $measureLabel := if($measure//mei:multiRest) then ($measureLabel || '–' || number($measureLabel) + number($measure//mei:multiRest/@num) - 1) else ($measureLabel) + let $measureID := $measure/@xml:id + let $measureFacs := $measure/@facs + let $measureZoneRefCount := count($mei//mei:measure[@facs = $measureFacs]) + let $measureLabel := if($measureZoneRefCount gt 1) + then(string-join($mei//mei:measure[@facs = $measureFacs]/@label, '/')) + else($measureLabel) return map { 'zoneId': $zone/string(@xml:id), From 293159d647ca1324b322c4619539ec3b10037453 Mon Sep 17 00:00:00 2001 From: Dennis Ried Date: Sat, 24 Dec 2022 15:49:59 +0100 Subject: [PATCH 02/51] fix measure label join with multirests --- add/data/xql/getMeasuresOnPage.xql | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/add/data/xql/getMeasuresOnPage.xql b/add/data/xql/getMeasuresOnPage.xql index 3a6f4388c..6868edc68 100644 --- a/add/data/xql/getMeasuresOnPage.xql +++ b/add/data/xql/getMeasuresOnPage.xql @@ -59,9 +59,17 @@ declare function local:getMeasures($mei as node(), $surface as node()) as map(*) else ($measureLabel) let $measureID := $measure/@xml:id let $measureFacs := $measure/@facs - let $measureZoneRefCount := count($mei//mei:measure[@facs = $measureFacs]) - let $measureLabel := if($measureZoneRefCount gt 1) - then(string-join($mei//mei:measure[@facs = $measureFacs]/@label, '/')) + let $measuresZoneRef := $measure/ancestor::mei:mdiv//mei:measure[@facs = $measureFacs] + let $measureZoneRefCount := count($measuresZoneRef) + let $measureLabel := if(($measureZoneRefCount gt 1) and ($measure//mei:multiRest)) + then(for $measure in $measuresZoneRef + let $measureLabel := if ($measure/@label) then ($measure/string(@label)) else ($measure/string(@n)) + let $measureLabel := ($measureLabel || '–' || number($measureLabel) + number($measure//mei:multiRest/@num) - 1) + return + $measureLabel + ) + else if($measureZoneRefCount gt 1) + then($measuresZoneRef/@label) else($measureLabel) return map { @@ -71,7 +79,7 @@ declare function local:getMeasures($mei as node(), $surface as node()) as map(*) 'lrx': $zone/string(@lrx), 'lry': $zone/string(@lry), 'id': $measure/string(@xml:id), - 'name': $measureLabel, + 'name': string-join($measureLabel, '/'), 'type': $measure/string(@type), 'rest': local:getMRest($measure) } From b9623815fdebd5f809be0de47e5a803a3663a043 Mon Sep 17 00:00:00 2001 From: Dennis Ried Date: Tue, 27 Dec 2022 17:38:56 +0100 Subject: [PATCH 03/51] add diacrtical aspects to measure labels --- add/data/xql/getMeasuresOnPage.xql | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/add/data/xql/getMeasuresOnPage.xql b/add/data/xql/getMeasuresOnPage.xql index 6868edc68..e7cdc8ac3 100644 --- a/add/data/xql/getMeasuresOnPage.xql +++ b/add/data/xql/getMeasuresOnPage.xql @@ -35,6 +35,16 @@ declare namespace output="http://www.w3.org/2010/xslt-xquery-serialization"; declare option output:method "json"; declare option output:media-type "application/json"; +declare function local:makeMeasureLabelCritical($measure as node(), $measureLabel) { + let $measureParentElem := local-name($measure/parent::node()) + return + if($measureParentElem = 'supplied') + then({'[' || $measureLabel || ']'}) + else if($measureParentElem = 'del') + then({$measureLabel}) + else({$measureLabel}) +}; + (:~ Finds all measures on a page. @@ -63,14 +73,23 @@ declare function local:getMeasures($mei as node(), $surface as node()) as map(*) let $measureZoneRefCount := count($measuresZoneRef) let $measureLabel := if(($measureZoneRefCount gt 1) and ($measure//mei:multiRest)) then(for $measure in $measuresZoneRef - let $measureLabel := if ($measure/@label) then ($measure/string(@label)) else ($measure/string(@n)) + + let $measureLabel := if ($measure/@label) then ($measure/string(@label)) else ($measure/string(@n)) let $measureLabel := local:makeMeasureLabelCritical($measure, $measureLabel) let $measureLabel := ($measureLabel || '–' || number($measureLabel) + number($measure//mei:multiRest/@num) - 1) return $measureLabel ) else if($measureZoneRefCount gt 1) - then($measuresZoneRef/@label) - else($measureLabel) + then(for $label in $measuresZoneRef + return + local:makeMeasureLabelCritical($label, $label/string(@label))) + else(local:makeMeasureLabelCritical($measure, $measureLabel)) + let $measureLabel := {for $each at $i in $measureLabel + return + if(index-of($measureLabel, $each) != 1) + then('/',$each) + else($each) + } return map { 'zoneId': $zone/string(@xml:id), @@ -79,7 +98,7 @@ declare function local:getMeasures($mei as node(), $surface as node()) as map(*) 'lrx': $zone/string(@lrx), 'lry': $zone/string(@lry), 'id': $measure/string(@xml:id), - 'name': string-join($measureLabel, '/'), + 'name': $measureLabel, 'type': $measure/string(@type), 'rest': local:getMRest($measure) } From 58f67ce35e93b0fe3091301e356b2eaa56f7eccc Mon Sep 17 00:00:00 2001 From: Dennis Ried Date: Tue, 27 Dec 2022 17:46:33 +0100 Subject: [PATCH 04/51] add css for deleted measures --- packages/eoTheme/sass/etc/facsimile.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/eoTheme/sass/etc/facsimile.scss b/packages/eoTheme/sass/etc/facsimile.scss index d4e02e232..02a78d8fb 100644 --- a/packages/eoTheme/sass/etc/facsimile.scss +++ b/packages/eoTheme/sass/etc/facsimile.scss @@ -17,6 +17,10 @@ @include background-image(radial-gradient(center , rgba(100, 100, 100, 0.3), rgba(0, 0, 0, 0) 5px)); } + .del { + text-decoration: line-through; + } + .measure.highlighted { box-shadow: 0 0 4px rgba(0, 0, 0, 0.6) inset; } From 461e6319c12ad184adb76e310863ef391fcbb23a Mon Sep 17 00:00:00 2001 From: Dennis Ried Date: Tue, 27 Dec 2022 21:49:19 +0100 Subject: [PATCH 05/51] introduce module for measure actions # Conflicts: # add/data/xql/getMeasures.xql --- add/data/xql/getMeasures.xql | 102 ++++++-------------- add/data/xql/getMeasuresOnPage.xql | 50 +--------- add/data/xqm/measure.xqm | 143 +++++++++++++++++++++++++++++ 3 files changed, 175 insertions(+), 120 deletions(-) create mode 100644 add/data/xqm/measure.xqm diff --git a/add/data/xql/getMeasures.xql b/add/data/xql/getMeasures.xql index 0252ed5db..fa182263b 100644 --- a/add/data/xql/getMeasures.xql +++ b/add/data/xql/getMeasures.xql @@ -27,104 +27,55 @@ declare namespace xmldb="http://exist-db.org/xquery/xmldb"; import module namespace functx="http://www.functx.com"; import module namespace eutil = "http://www.edirom.de/xquery/util" at "/db/apps/Edirom-Online/data/xqm/util.xqm"; - -declare option exist:serialize "method=text media-type=text/plain omit-xml-declaration=yes"; +import module namespace measure = "http://www.edirom.de/xquery/measure" at "/db/apps/Edirom-Online/data/xqm/measure.xqm"; declare function local:getMeasures($mei as node(), $mdivID as xs:string) as xs:string* { if($mei//mei:parts) then( let $mdiv := $mei/id($mdivID) - let $measureNs := if ($mdiv//mei:measure/@label) - then ( - let $labels := $mdiv//mei:measure/@label/string() - for $label in $labels - let $labelsAnalyzed := if (contains($label, '–')) - then ((:substring-before($label, '–'):) - let $first := substring-before($label, '–') - let $last := substring-after($label, '–') - let $steps := xs:integer(number($last) - number($first) + number(1)) - for $i in 1 to $steps - return - string(number($first) + $i - 1) - ) - else ($label) - return - $labelsAnalyzed - ) - else ($mdiv//mei:measure/@n) + let $measureNs := for $measure in $mdiv//mei:measure + return measure:analyzeLabels($measure) + let $measureNsDistinct := distinct-values(eutil:sort-as-numeric-alpha($measureNs)) return for $measureN in $measureNsDistinct - let $measureNNumber := number($measureN) - 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] - let $voiceRef := $part//mei:staffDef/@decls - let $voiceID := substring-after($voiceRef, '#') - return - concat('{id:"', $measure/@xml:id, '", - voice: "', $voiceRef, - '", partLabel: "', $mei/id($voiceID)/@label, - '"}') - ) - else ( - for $part in $mdiv//mei:part -(: let $partMeasures := $part//mei:measure:) - for $measure in $part//mei:measure[@n = $measureN][1] | $measures[ancestor::mei:part = $part] - let $voiceRef := $part//mei:staffDef/@decls - let $voiceID := substring-after($voiceRef, '#') - return - concat('{id:"', - $measure/@xml:id, - '", voice: "', $voiceRef, - '", partLabel: "', $mei/id($voiceID)/@label, - '"}') - ) + let $measures := measure:resolveMultiMeasureRests($mdiv, $measureN) + 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, '", ', 'measures: [', string-join($measures, ','), '], ', - 'mdivs: ["', $mdiv/@xml:id, '"], ', (: TODO :) + 'mdivs: ["', $mdiv/@xml:id, '"], ', 'name: "', $measureN, '"', '}') ) else( - - if($mei/id($mdivID)//mei:measure[@label]) - then( - for $measureN in $mei/id($mdivID)//mei:measure/@label - let $measures := $mei/id($mdivID)//mei:measure[@label = $measureN] - let $measure := $measures[1] - (:let $measureLabel := if(exists($measure/@label) and not(contains($measure/@label,'/'))) then($measure/@label) else($measure/@n):) - return - concat('{', - 'id: "', $measure/@xml:id, '", ', - 'measures: [{id:"', $measure/@xml:id, '", voice: "score"}], ', - 'mdivs: ["', $measure/ancestor::mei:mdiv[1]/@xml:id, '"], ', (: TODO :) - 'name: "', $measureN, '"', (: Hier Unterscheiden wg. Auftakt. :) - '}') - ) - else( - - for $measureN in $mei/id($mdivID)//mei:measure/data(@n) - let $measures := $mei/id($mdivID)//mei:measure[@n = $measureN] - let $measure := $measures[1] - (:let $measureLabel := if(exists($measure/@label) and not(contains($measure/@label,'/'))) then($measure/@label) else($measure/@n):) + for $measure in $mei/id($mdivID)//mei:measure + let $hasLabel := exists($measure[@label]) + let $attr := if($hasLabel)then('label')else('n') + let $measures := $mei/id($mdivID)//mei:measure[@*[local-name() = $attr] = $measure/@*[local-name() = $attr]] + let $measure := $measures[1] + let $measureLabel := measure:getMeasureLabelAttr($measure) return concat('{', 'id: "', $measure/@xml:id, '", ', 'measures: [{id:"', $measure/@xml:id, '", voice: "score"}], ', - 'mdivs: ["', $measure/ancestor::mei:mdiv[1]/@xml:id, '"], ', (: TODO :) - 'name: "', $measureN, '"', (: Hier Unterscheiden wg. Auftakt. :) + 'mdivs: ["', $measure/ancestor::mei:mdiv[1]/@xml:id, '"], ', + 'name: "', $measureLabel, '"', '}') ) - ) }; let $uri := request:get-parameter('uri', '') @@ -133,4 +84,5 @@ let $mei := doc($uri)/root() let $ret := local:getMeasures($mei, $mdivID) -return concat('[', string-join($ret, ','), ']') \ No newline at end of file +return + '[' || string-join($ret, ',') || ']' \ No newline at end of file diff --git a/add/data/xql/getMeasuresOnPage.xql b/add/data/xql/getMeasuresOnPage.xql index e7cdc8ac3..4ee3f8ec7 100644 --- a/add/data/xql/getMeasuresOnPage.xql +++ b/add/data/xql/getMeasuresOnPage.xql @@ -35,15 +35,8 @@ declare namespace output="http://www.w3.org/2010/xslt-xquery-serialization"; declare option output:method "json"; declare option output:media-type "application/json"; -declare function local:makeMeasureLabelCritical($measure as node(), $measureLabel) { - let $measureParentElem := local-name($measure/parent::node()) - return - if($measureParentElem = 'supplied') - then({'[' || $measureLabel || ']'}) - else if($measureParentElem = 'del') - then({$measureLabel}) - else({$measureLabel}) -}; +import module namespace measure = "http://www.edirom.de/xquery/measure" at "/db/apps/Edirom-Online/data/xqm/measure.xqm"; +import module namespace eutil="http://www.edirom.de/xquery/util" at "/db/apps/Edirom-Online/data/xqm/util.xqm"; (:~ Finds all measures on a page. @@ -63,33 +56,8 @@ declare function local:getMeasures($mei as node(), $surface as node()) as map(*) let $measures := $mei//mei:measure[contains(@facs, $zoneRef)][$zoneRef = tokenize(@facs, '\s+')] return for $measure in $measures - let $measureLabel := if ($measure/@label) then ($measure/string(@label)) else ($measure/string(@n)) - let $measureLabel := if($measure//mei:multiRest) - then ($measureLabel || '–' || number($measureLabel) + number($measure//mei:multiRest/@num) - 1) - else ($measureLabel) - let $measureID := $measure/@xml:id - let $measureFacs := $measure/@facs - let $measuresZoneRef := $measure/ancestor::mei:mdiv//mei:measure[@facs = $measureFacs] - let $measureZoneRefCount := count($measuresZoneRef) - let $measureLabel := if(($measureZoneRefCount gt 1) and ($measure//mei:multiRest)) - then(for $measure in $measuresZoneRef - - let $measureLabel := if ($measure/@label) then ($measure/string(@label)) else ($measure/string(@n)) let $measureLabel := local:makeMeasureLabelCritical($measure, $measureLabel) - let $measureLabel := ($measureLabel || '–' || number($measureLabel) + number($measure//mei:multiRest/@num) - 1) - return - $measureLabel - ) - else if($measureZoneRefCount gt 1) - then(for $label in $measuresZoneRef - return - local:makeMeasureLabelCritical($label, $label/string(@label))) - else(local:makeMeasureLabelCritical($measure, $measureLabel)) - let $measureLabel := {for $each at $i in $measureLabel - return - if(index-of($measureLabel, $each) != 1) - then('/',$each) - else($each) - } + let $measureLabel := measure:getMeasureLabel($measure) + return map { 'zoneId': $zone/string(@xml:id), @@ -100,18 +68,10 @@ declare function local:getMeasures($mei as node(), $surface as node()) as map(*) 'id': $measure/string(@xml:id), 'name': $measureLabel, 'type': $measure/string(@type), - 'rest': local:getMRest($measure) + 'rest': measure:getMRest($measure) } }; -declare function local:getMRest($measure) { - if($measure//mei:mRest) - then(string('1')) - else if($measure//mei:multiRest) - then($measure//mei:multiRest/string(@num)) - else(string('0')) -}; - let $uri := request:get-parameter('uri', '') let $surfaceId := request:get-parameter('pageId', '') diff --git a/add/data/xqm/measure.xqm b/add/data/xqm/measure.xqm new file mode 100644 index 000000000..ad6d5286b --- /dev/null +++ b/add/data/xqm/measure.xqm @@ -0,0 +1,143 @@ +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 . + +:) + + +(:~ +: This module provides library functions for Sources +: +: @author Dennis Ried +:) +module namespace measure = "http://www.edirom.de/xquery/measure"; + +declare namespace mei="http://www.music-encoding.org/ns/mei"; + +import module namespace eutil="http://www.edirom.de/xquery/util" at "/db/apps/Edirom-Online/data/xqm/util.xqm"; + +(:~ +: Returns an attribute from a measure for labeling +: +: @param $measure The measure to be processed +: @return Attribute Label or N +:) +declare function measure:getMeasureLabelAttr($measure as node()){ + if(exists($measure[@label])) + then($measure/@label) + else($measure/@n) +}; + +(:~ +: Adds diacritical characters +: +: @param $measure The measure to be processed +: @param $measureLabel The label of the measure +: @return A span containing the label +:) +declare function measure:makeMeasureLabelCritical($measure as node(), $measureLabel) { + let $measureParentElem := local-name($measure/parent::node()) + return + if($measureParentElem = 'supplied') + then({'[' || $measureLabel || ']'}) + else if($measureParentElem = 'del') + then({$measureLabel}) + else({$measureLabel}) +}; + +(:~ +: Returns a label for a measure (range) +: +: @param $measure The measure to be processed +: @return A span containing the label +:) +declare function measure:getMeasureLabel($measure as node()) { + let $measureLabel := measure:getMeasureLabelAttr($measure) + let $measureLabel := if($measure//mei:multiRest) + then ($measureLabel || '–' || number($measureLabel) + number($measure//mei:multiRest/@num) - 1) + else ($measureLabel) + let $measureID := $measure/@xml:id + let $measureFacs := $measure/@facs + let $measuresZoneRef := $measure/ancestor::mei:mdiv//mei:measure[@facs = $measureFacs] + let $measureZoneRefCount := count($measuresZoneRef) + let $measureLabel := if(($measureZoneRefCount gt 1) and ($measure//mei:multiRest)) + then(for $measure in $measuresZoneRef + let $measureLabel := if ($measure/@label) then ($measure/string(@label)) else ($measure/string(@n)) + let $measureLabel := measure:makeMeasureLabelCritical($measure, $measureLabel) + let $measureLabel := ($measureLabel || '–' || number($measureLabel) + number($measure//mei:multiRest/@num) - 1) + return + $measureLabel + ) + else if($measureZoneRefCount gt 1) + then(for $label in $measuresZoneRef + return + measure:makeMeasureLabelCritical($label, $label/string(@label))) + else(measure:makeMeasureLabelCritical($measure, $measureLabel)) + let $measureLabel := {for $each at $i in $measureLabel + return + if(index-of($measureLabel, $each) != 1) + then('/',$each) + else($each) + } + return + $measureLabel +}; + +(:~ +: Returns the value of a (multi) measure rest +: +: @param $measure The measure to be processed +: @return The value of the rest as string +:) +declare function measure:getMRest($measure) { + if($measure//mei:mRest) + then(string('1')) + else if($measure//mei:multiRest) + then($measure//mei:multiRest/string(@num)) + else(string('0')) +}; + +(:~ +: Returns resolved labels +: +: @param $measure The measure to be processed +: @return An array of strings +:) +declare function measure:analyzeLabels($measure as node()) { + let $labels := $measure/@label + let $labelsAnalyzed := for $label in $labels + return + if (contains($label, '–')) + then (let $first := substring-before($label, '–') + let $last := substring-after($label, '–') + let $steps := xs:integer(number($last) - number($first) + number(1)) + for $i in 1 to $steps return string(number($first) + $i - 1)) + else ($label) + return + if($labels) + then($labelsAnalyzed) + else ($measure/@n) +}; + +declare function measure:resolveMultiMeasureRests($mdiv as node(), $measureN as xs:string) { + let $measureNNumber := number($measureN) + return + 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))]) +}; \ No newline at end of file From 271543cb604624b10c06bcee0e508bbcd1f1d53e Mon Sep 17 00:00:00 2001 From: Dennis Ried Date: Tue, 27 Dec 2022 21:54:29 +0100 Subject: [PATCH 06/51] fix default return type --- add/data/xqm/measure.xqm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/add/data/xqm/measure.xqm b/add/data/xqm/measure.xqm index ad6d5286b..425037dc7 100644 --- a/add/data/xqm/measure.xqm +++ b/add/data/xqm/measure.xqm @@ -57,7 +57,7 @@ declare function measure:makeMeasureLabelCritical($measure as node(), $measureLa then({'[' || $measureLabel || ']'}) else if($measureParentElem = 'del') then({$measureLabel}) - else({$measureLabel}) + else({string($measureLabel)}) }; (:~ From 47d5278fe4c195e520073c1458637835c53c3f13 Mon Sep 17 00:00:00 2001 From: Dennis Ried Date: Mon, 13 Mar 2023 08:28:17 +0100 Subject: [PATCH 07/51] add functx namespace --- add/data/xqm/measure.xqm | 1 + 1 file changed, 1 insertion(+) diff --git a/add/data/xqm/measure.xqm b/add/data/xqm/measure.xqm index 425037dc7..56348f4de 100644 --- a/add/data/xqm/measure.xqm +++ b/add/data/xqm/measure.xqm @@ -30,6 +30,7 @@ module namespace measure = "http://www.edirom.de/xquery/measure"; declare namespace mei="http://www.music-encoding.org/ns/mei"; import module namespace eutil="http://www.edirom.de/xquery/util" at "/db/apps/Edirom-Online/data/xqm/util.xqm"; +import module namespace functx="http://www.functx.com"; (:~ : Returns an attribute from a measure for labeling From e59e58241d6fd25973fe67abc9840abd7644e693 Mon Sep 17 00:00:00 2001 From: Dennis Ried Date: Mon, 13 Mar 2023 08:29:16 +0100 Subject: [PATCH 08/51] introduce handling for reg --- add/data/xqm/measure.xqm | 83 +++++++++++++++++++++++++++------------- 1 file changed, 57 insertions(+), 26 deletions(-) diff --git a/add/data/xqm/measure.xqm b/add/data/xqm/measure.xqm index 56348f4de..b3fabed89 100644 --- a/add/data/xqm/measure.xqm +++ b/add/data/xqm/measure.xqm @@ -51,14 +51,14 @@ declare function measure:getMeasureLabelAttr($measure as node()){ : @param $measureLabel The label of the measure : @return A span containing the label :) -declare function measure:makeMeasureLabelCritical($measure as node(), $measureLabel) { +declare function measure:makeMeasureLabelCritical($measure as node(), $measureLabel as xs:string) as node() { let $measureParentElem := local-name($measure/parent::node()) return if($measureParentElem = 'supplied') then({'[' || $measureLabel || ']'}) else if($measureParentElem = 'del') then({$measureLabel}) - else({string($measureLabel)}) + else({$measureLabel}) }; (:~ @@ -67,36 +67,67 @@ declare function measure:makeMeasureLabelCritical($measure as node(), $measureLa : @param $measure The measure to be processed : @return A span containing the label :) -declare function measure:getMeasureLabel($measure as node()) { +declare function measure:getMeasureLabel($measure as node()) as node() { let $measureLabel := measure:getMeasureLabelAttr($measure) - let $measureLabel := if($measure//mei:multiRest) - then ($measureLabel || '–' || number($measureLabel) + number($measure//mei:multiRest/@num) - 1) - else ($measureLabel) let $measureID := $measure/@xml:id let $measureFacs := $measure/@facs let $measuresZoneRef := $measure/ancestor::mei:mdiv//mei:measure[@facs = $measureFacs] let $measureZoneRefCount := count($measuresZoneRef) - let $measureLabel := if(($measureZoneRefCount gt 1) and ($measure//mei:multiRest)) - then(for $measure in $measuresZoneRef - let $measureLabel := if ($measure/@label) then ($measure/string(@label)) else ($measure/string(@n)) - let $measureLabel := measure:makeMeasureLabelCritical($measure, $measureLabel) - let $measureLabel := ($measureLabel || '–' || number($measureLabel) + number($measure//mei:multiRest/@num) - 1) - return - $measureLabel - ) - else if($measureZoneRefCount gt 1) - then(for $label in $measuresZoneRef - return - measure:makeMeasureLabelCritical($label, $label/string(@label))) - else(measure:makeMeasureLabelCritical($measure, $measureLabel)) - let $measureLabel := {for $each at $i in $measureLabel - return - if(index-of($measureLabel, $each) != 1) - then('/',$each) - else($each) - } + let $measureLabels := + if(not($measure/parent::mei:reg)) + then( + if(($measureZoneRefCount gt 1) and ($measure//mei:multiRest)) + then(for $measure in $measuresZoneRef + let $measureLabel := measure:getMeasureLabelAttr($measure) + let $measureLabel := measure:makeMeasureLabelCritical($measure, $measureLabel) + let $measureLabel := ($measureLabel || '–' || number($measureLabel) + number($measure//mei:multiRest/@num) - 1) + return + {$measureLabel} + ) + else if ($measureZoneRefCount gt 1) + then(for $label in $measuresZoneRef + return + measure:makeMeasureLabelCritical($label, $label/string(@label))) + else(measure:makeMeasureLabelCritical($measure, $measureLabel)) + ) + else if($measure/parent::mei:reg) + then(for $measure in $measuresZoneRef + return + measure:getRegMeasureLabel($measure/parent::mei:reg)) + else(noLabel) return - $measureLabel + measure:joinMeasureLabels($measureLabels) +}; + +(:~ +: Returns a label for a measure (range) +: +: @param $labels The measure to be processed +: @return A span containing the joined label +:) +declare function measure:joinMeasureLabels($labels as node()*) as node() { + {for $label at $pos in functx:distinct-deep($labels) + return + if($pos = 1) + then($label) + else('/',$label) + } +}; + +(:~ +: Returns a label for a regularized measure (range) +: +: @param $reg The reg element (containing measure) to be processed +: @return The label as string +:) +declare function measure:getRegMeasureLabel($reg as node()) as node() { + let $measures := $reg/mei:measure + let $measuresCount := count($measures) + let $measureStart := $measures[1] + let $measureStop := $measures[$measuresCount] + let $measureLabel := measure:getMeasureLabelAttr($measureStart) || '–' || measure:getMeasureLabelAttr($measureStop) + return + {$measureLabel} }; (:~ From 1a4d91dd38b19d6f9e9acd1a7c97f870a2e7ecbe Mon Sep 17 00:00:00 2001 From: Dennis Ried Date: Wed, 7 Feb 2024 08:25:18 +0100 Subject: [PATCH 09/51] measure: move local functions to module --- add/data/xql/getMeasures.xql | 51 +---------------- add/data/xql/getMeasuresOnPage.xql | 35 +----------- add/data/xqm/measure.xqm | 91 ++++++++++++++++++++++++++++++ 3 files changed, 93 insertions(+), 84 deletions(-) diff --git a/add/data/xql/getMeasures.xql b/add/data/xql/getMeasures.xql index fa182263b..a7202e192 100644 --- a/add/data/xql/getMeasures.xql +++ b/add/data/xql/getMeasures.xql @@ -29,60 +29,11 @@ import module namespace functx="http://www.functx.com"; import module namespace eutil = "http://www.edirom.de/xquery/util" at "/db/apps/Edirom-Online/data/xqm/util.xqm"; import module namespace measure = "http://www.edirom.de/xquery/measure" at "/db/apps/Edirom-Online/data/xqm/measure.xqm"; -declare function local:getMeasures($mei as node(), $mdivID as xs:string) as xs:string* { - - if($mei//mei:parts) - then( - let $mdiv := $mei/id($mdivID) - let $measureNs := for $measure in $mdiv//mei:measure - return measure:analyzeLabels($measure) - - let $measureNsDistinct := distinct-values(eutil:sort-as-numeric-alpha($measureNs)) - return - for $measureN in $measureNsDistinct - let $measures := measure:resolveMultiMeasureRests($mdiv, $measureN) - 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, '", ', - 'measures: [', string-join($measures, ','), '], ', - 'mdivs: ["', $mdiv/@xml:id, '"], ', - 'name: "', $measureN, '"', - '}') - ) - - else( - for $measure in $mei/id($mdivID)//mei:measure - let $hasLabel := exists($measure[@label]) - let $attr := if($hasLabel)then('label')else('n') - let $measures := $mei/id($mdivID)//mei:measure[@*[local-name() = $attr] = $measure/@*[local-name() = $attr]] - let $measure := $measures[1] - let $measureLabel := measure:getMeasureLabelAttr($measure) - return - concat('{', - 'id: "', $measure/@xml:id, '", ', - 'measures: [{id:"', $measure/@xml:id, '", voice: "score"}], ', - 'mdivs: ["', $measure/ancestor::mei:mdiv[1]/@xml:id, '"], ', - 'name: "', $measureLabel, '"', - '}') - ) -}; - let $uri := request:get-parameter('uri', '') let $mdivID := request:get-parameter('mdiv', '') let $mei := doc($uri)/root() -let $ret := local:getMeasures($mei, $mdivID) +let $ret := measure:getMeasures($mei, $mdivID) return '[' || string-join($ret, ',') || ']' \ No newline at end of file diff --git a/add/data/xql/getMeasuresOnPage.xql b/add/data/xql/getMeasuresOnPage.xql index 4ee3f8ec7..98afd2cd4 100644 --- a/add/data/xql/getMeasuresOnPage.xql +++ b/add/data/xql/getMeasuresOnPage.xql @@ -38,39 +38,6 @@ declare option output:media-type "application/json"; import module namespace measure = "http://www.edirom.de/xquery/measure" at "/db/apps/Edirom-Online/data/xqm/measure.xqm"; import module namespace eutil="http://www.edirom.de/xquery/util" at "/db/apps/Edirom-Online/data/xqm/util.xqm"; -(:~ - Finds all measures on a page. - - @param $mei The sourcefile - @param $surface The surface to look at - @returns A list of json objects with measure information -:) -declare function local:getMeasures($mei as node(), $surface as node()) as map(*)* { - - for $zone in $surface/mei:zone[@type='measure'] - let $zoneRef := concat('#', $zone/@xml:id) - (: - The first predicate with `contains` is just a rough estimate to narrow down the result set. - It uses the index and is fast while the second (exact) predicate is generally too slow - :) - let $measures := $mei//mei:measure[contains(@facs, $zoneRef)][$zoneRef = tokenize(@facs, '\s+')] - return - for $measure in $measures - let $measureLabel := measure:getMeasureLabel($measure) - - return - map { - 'zoneId': $zone/string(@xml:id), - 'ulx': $zone/string(@ulx), - 'uly': $zone/string(@uly), - 'lrx': $zone/string(@lrx), - 'lry': $zone/string(@lry), - 'id': $measure/string(@xml:id), - 'name': $measureLabel, - 'type': $measure/string(@type), - 'rest': measure:getMRest($measure) - } -}; let $uri := request:get-parameter('uri', '') let $surfaceId := request:get-parameter('pageId', '') @@ -81,6 +48,6 @@ let $surface := $mei/id($surfaceId) return ( array { (: TODO: überlegen, wie die Staff-spezifischen Ausschnitte angezeigt werden sollen :) - local:getMeasures($mei, $surface) + measure:getMeasuresOnPage($mei, $surface) } ) \ No newline at end of file diff --git a/add/data/xqm/measure.xqm b/add/data/xqm/measure.xqm index b3fabed89..0406cb3f7 100644 --- a/add/data/xqm/measure.xqm +++ b/add/data/xqm/measure.xqm @@ -32,6 +32,63 @@ declare namespace mei="http://www.music-encoding.org/ns/mei"; import module namespace eutil="http://www.edirom.de/xquery/util" at "/db/apps/Edirom-Online/data/xqm/util.xqm"; import module namespace functx="http://www.functx.com"; +(:~ +: Returns maps for each measure containing measure ID, measures (if multiRest), mdiv ID and a label +: +: @param $mei the mei file +: @param $mdivID the ID of the mdiv +: @return Maps (as strings) +:) +declare function measure:getMeasures($mei as node(), $mdivID as xs:string) as xs:string* { + + if($mei//mei:parts) + then( + let $mdiv := $mei/id($mdivID) + let $measureNs := for $measure in $mdiv//mei:measure + return measure:analyzeLabels($measure) + + let $measureNsDistinct := distinct-values(eutil:sort-as-numeric-alpha($measureNs)) + return + for $measureN in $measureNsDistinct + let $measures := measure:resolveMultiMeasureRests($mdiv, $measureN) + 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, '", ', + 'measures: [', string-join($measures, ','), '], ', + 'mdivs: ["', $mdiv/@xml:id, '"], ', + 'name: "', $measureN, '"', + '}') + ) + + else( + for $measure in $mei/id($mdivID)//mei:measure + let $hasLabel := exists($measure[@label]) + let $attr := if($hasLabel)then('label')else('n') + let $measures := $mei/id($mdivID)//mei:measure[@*[local-name() = $attr] = $measure/@*[local-name() = $attr]] + let $measure := $measures[1] + let $measureLabel := measure:getMeasureLabelAttr($measure) + return + concat('{', + 'id: "', $measure/@xml:id, '", ', + 'measures: [{id:"', $measure/@xml:id, '", voice: "score"}], ', + 'mdivs: ["', $measure/ancestor::mei:mdiv[1]/@xml:id, '"], ', + 'name: "', $measureLabel, '"', + '}') + ) +}; + + (:~ : Returns an attribute from a measure for labeling : @@ -172,4 +229,38 @@ declare function measure:resolveMultiMeasureRests($mdiv as node(), $measureN as 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))]) +}; + +(:~ + Finds all measures on a page. + + @param $mei The sourcefile + @param $surface The surface to look at + @returns A list of json objects with measure information +:) +declare function measure:getMeasuresOnPage($mei as node(), $surface as node()) as map(*)* { + + for $zone in $surface/mei:zone[@type='measure'] + let $zoneRef := concat('#', $zone/@xml:id) + (: + The first predicate with `contains` is just a rough estimate to narrow down the result set. + It uses the index and is fast while the second (exact) predicate is generally too slow + :) + let $measures := $mei//mei:measure[contains(@facs, $zoneRef)][$zoneRef = tokenize(@facs, '\s+')] + return + for $measure in $measures + let $measureLabel := measure:getMeasureLabel($measure) + + return + map { + 'zoneId': $zone/string(@xml:id), + 'ulx': $zone/string(@ulx), + 'uly': $zone/string(@uly), + 'lrx': $zone/string(@lrx), + 'lry': $zone/string(@lry), + 'id': $measure/string(@xml:id), + 'name': $measureLabel, + 'type': $measure/string(@type), + 'rest': measure:getMRest($measure) + } }; \ No newline at end of file From 9b068a755bbaac42539d9be25cf4b74612a5ccaa Mon Sep 17 00:00:00 2001 From: bwbohl Date: Mon, 26 Feb 2024 10:49:46 +0100 Subject: [PATCH 10/51] add and format structuring comments, XQdoc comments --- add/data/xqm/measure.xqm | 152 ++++++++++++++++++--------------------- 1 file changed, 71 insertions(+), 81 deletions(-) diff --git a/add/data/xqm/measure.xqm b/add/data/xqm/measure.xqm index 0406cb3f7..60ab48a51 100644 --- a/add/data/xqm/measure.xqm +++ b/add/data/xqm/measure.xqm @@ -1,52 +1,42 @@ xquery version "3.1"; (: - Edirom Online - Copyright (C) 2011 The Edirom Project - http://www.edirom.de + : For LICENSE-Details please refer to the LICENSE file in the root directory of this repository. + :) - 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. +(:~ + : This module provides library functions for Sources + : + : @author Dennis Ried + :) +module namespace measure = "http://www.edirom.de/xquery/measure"; - You should have received a copy of the GNU General Public License - along with Edirom Online. If not, see . +(: IMPORTS ================================================================= :) -:) +import module namespace functx="http://www.functx.com"; +import module namespace eutil="http://www.edirom.de/xquery/util" at "/db/apps/Edirom-Online/data/xqm/util.xqm"; -(:~ -: This module provides library functions for Sources -: -: @author Dennis Ried -:) -module namespace measure = "http://www.edirom.de/xquery/measure"; +(: NAMESPACE DECLARATIONS ================================================== :) declare namespace mei="http://www.music-encoding.org/ns/mei"; -import module namespace eutil="http://www.edirom.de/xquery/util" at "/db/apps/Edirom-Online/data/xqm/util.xqm"; -import module namespace functx="http://www.functx.com"; +(: FUNCTION DECLARATIONS =================================================== :) (:~ -: Returns maps for each measure containing measure ID, measures (if multiRest), mdiv ID and a label -: -: @param $mei the mei file -: @param $mdivID the ID of the mdiv -: @return Maps (as strings) -:) + : Returns maps for each measure containing measure ID, measures (if multiRest), mdiv ID and a label + : + : @param $mei the mei file + : @param $mdivID the ID of the mdiv + : @return Maps (as strings) + :) declare function measure:getMeasures($mei as node(), $mdivID as xs:string) as xs:string* { - + if($mei//mei:parts) then( let $mdiv := $mei/id($mdivID) let $measureNs := for $measure in $mdiv//mei:measure return measure:analyzeLabels($measure) - + let $measureNsDistinct := distinct-values(eutil:sort-as-numeric-alpha($measureNs)) return for $measureN in $measureNsDistinct @@ -70,7 +60,7 @@ declare function measure:getMeasures($mei as node(), $mdivID as xs:string) as xs 'name: "', $measureN, '"', '}') ) - + else( for $measure in $mei/id($mdivID)//mei:measure let $hasLabel := exists($measure[@label]) @@ -90,11 +80,11 @@ declare function measure:getMeasures($mei as node(), $mdivID as xs:string) as xs (:~ -: Returns an attribute from a measure for labeling -: -: @param $measure The measure to be processed -: @return Attribute Label or N -:) + : Returns an attribute from a measure for labeling + : + : @param $measure The measure to be processed + : @return Attribute Label or N + :) declare function measure:getMeasureLabelAttr($measure as node()){ if(exists($measure[@label])) then($measure/@label) @@ -102,12 +92,12 @@ declare function measure:getMeasureLabelAttr($measure as node()){ }; (:~ -: Adds diacritical characters -: -: @param $measure The measure to be processed -: @param $measureLabel The label of the measure -: @return A span containing the label -:) + : Adds diacritical characters + : + : @param $measure The measure to be processed + : @param $measureLabel The label of the measure + : @return A span containing the label + :) declare function measure:makeMeasureLabelCritical($measure as node(), $measureLabel as xs:string) as node() { let $measureParentElem := local-name($measure/parent::node()) return @@ -119,18 +109,18 @@ declare function measure:makeMeasureLabelCritical($measure as node(), $measureLa }; (:~ -: Returns a label for a measure (range) -: -: @param $measure The measure to be processed -: @return A span containing the label -:) + : Returns a label for a measure (range) + : + : @param $measure The measure to be processed + : @return A span containing the label + :) declare function measure:getMeasureLabel($measure as node()) as node() { let $measureLabel := measure:getMeasureLabelAttr($measure) let $measureID := $measure/@xml:id let $measureFacs := $measure/@facs let $measuresZoneRef := $measure/ancestor::mei:mdiv//mei:measure[@facs = $measureFacs] let $measureZoneRefCount := count($measuresZoneRef) - let $measureLabels := + let $measureLabels := if(not($measure/parent::mei:reg)) then( if(($measureZoneRefCount gt 1) and ($measure//mei:multiRest)) @@ -157,11 +147,11 @@ declare function measure:getMeasureLabel($measure as node()) as node() { }; (:~ -: Returns a label for a measure (range) -: -: @param $labels The measure to be processed -: @return A span containing the joined label -:) + : Returns a label for a measure (range) + : + : @param $labels The measure to be processed + : @return A span containing the joined label + :) declare function measure:joinMeasureLabels($labels as node()*) as node() { {for $label at $pos in functx:distinct-deep($labels) return @@ -172,11 +162,11 @@ declare function measure:joinMeasureLabels($labels as node()*) as node() { }; (:~ -: Returns a label for a regularized measure (range) -: -: @param $reg The reg element (containing measure) to be processed -: @return The label as string -:) + : Returns a label for a regularized measure (range) + : + : @param $reg The reg element (containing measure) to be processed + : @return The label as string + :) declare function measure:getRegMeasureLabel($reg as node()) as node() { let $measures := $reg/mei:measure let $measuresCount := count($measures) @@ -188,11 +178,11 @@ declare function measure:getRegMeasureLabel($reg as node()) as node() { }; (:~ -: Returns the value of a (multi) measure rest -: -: @param $measure The measure to be processed -: @return The value of the rest as string -:) + : Returns the value of a (multi) measure rest + : + : @param $measure The measure to be processed + : @return The value of the rest as string + :) declare function measure:getMRest($measure) { if($measure//mei:mRest) then(string('1')) @@ -202,11 +192,11 @@ declare function measure:getMRest($measure) { }; (:~ -: Returns resolved labels -: -: @param $measure The measure to be processed -: @return An array of strings -:) + : Returns resolved labels + : + : @param $measure The measure to be processed + : @return An array of strings + :) declare function measure:analyzeLabels($measure as node()) { let $labels := $measure/@label let $labelsAnalyzed := for $label in $labels @@ -232,25 +222,25 @@ declare function measure:resolveMultiMeasureRests($mdiv as node(), $measureN as }; (:~ - Finds all measures on a page. - - @param $mei The sourcefile - @param $surface The surface to look at - @returns A list of json objects with measure information -:) + : Finds all measures on a page. + : + : @param $mei The sourcefile + : @param $surface The surface to look at + : @returns A list of json objects with measure information + :) declare function measure:getMeasuresOnPage($mei as node(), $surface as node()) as map(*)* { for $zone in $surface/mei:zone[@type='measure'] let $zoneRef := concat('#', $zone/@xml:id) - (: - The first predicate with `contains` is just a rough estimate to narrow down the result set. - It uses the index and is fast while the second (exact) predicate is generally too slow - :) + (: + : The first predicate with `contains` is just a rough estimate to narrow down the result set. + : It uses the index and is fast while the second (exact) predicate is generally too slow + :) let $measures := $mei//mei:measure[contains(@facs, $zoneRef)][$zoneRef = tokenize(@facs, '\s+')] return for $measure in $measures let $measureLabel := measure:getMeasureLabel($measure) - + return map { 'zoneId': $zone/string(@xml:id), @@ -263,4 +253,4 @@ declare function measure:getMeasuresOnPage($mei as node(), $surface as node()) a 'type': $measure/string(@type), 'rest': measure:getMRest($measure) } -}; \ No newline at end of file +}; From 119d92878e7fef2c96fe779e798ba55268f28476 Mon Sep 17 00:00:00 2001 From: bwbohl Date: Mon, 26 Feb 2024 11:34:23 +0100 Subject: [PATCH 11/51] apply current XQuery style guide --- add/data/xqm/measure.xqm | 204 ++++++++++++++++++++++----------------- 1 file changed, 118 insertions(+), 86 deletions(-) diff --git a/add/data/xqm/measure.xqm b/add/data/xqm/measure.xqm index 60ab48a51..f1ebb36f5 100644 --- a/add/data/xqm/measure.xqm +++ b/add/data/xqm/measure.xqm @@ -31,27 +31,35 @@ declare namespace mei="http://www.music-encoding.org/ns/mei"; :) declare function measure:getMeasures($mei as node(), $mdivID as xs:string) as xs:string* { - if($mei//mei:parts) - then( + if($mei//mei:parts) then ( let $mdiv := $mei/id($mdivID) - let $measureNs := for $measure in $mdiv//mei:measure - return measure:analyzeLabels($measure) + + let $measureNs := + for $measure in $mdiv//mei:measure + return measure:analyzeLabels($measure) let $measureNsDistinct := distinct-values(eutil:sort-as-numeric-alpha($measureNs)) + return for $measureN in $measureNsDistinct let $measures := measure:resolveMultiMeasureRests($mdiv, $measureN) - 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'), - '"}') + + 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, '", ', @@ -59,26 +67,23 @@ declare function measure:getMeasures($mei as node(), $mdivID as xs:string) as xs 'mdivs: ["', $mdiv/@xml:id, '"], ', 'name: "', $measureN, '"', '}') - ) - - else( + ) else ( for $measure in $mei/id($mdivID)//mei:measure - let $hasLabel := exists($measure[@label]) - let $attr := if($hasLabel)then('label')else('n') - let $measures := $mei/id($mdivID)//mei:measure[@*[local-name() = $attr] = $measure/@*[local-name() = $attr]] - let $measure := $measures[1] - let $measureLabel := measure:getMeasureLabelAttr($measure) - return - concat('{', - 'id: "', $measure/@xml:id, '", ', - 'measures: [{id:"', $measure/@xml:id, '", voice: "score"}], ', - 'mdivs: ["', $measure/ancestor::mei:mdiv[1]/@xml:id, '"], ', - 'name: "', $measureLabel, '"', - '}') - ) + let $hasLabel := exists($measure[@label]) + let $attr := if($hasLabel)then('label')else('n') + let $measures := $mei/id($mdivID)//mei:measure[@*[local-name() = $attr] = $measure/@*[local-name() = $attr]] + let $measure := $measures[1] + let $measureLabel := measure:getMeasureLabelAttr($measure) + return + concat('{', + 'id: "', $measure/@xml:id, '", ', + 'measures: [{id:"', $measure/@xml:id, '", voice: "score"}], ', + 'mdivs: ["', $measure/ancestor::mei:mdiv[1]/@xml:id, '"], ', + 'name: "', $measureLabel, '"', + '}') + ) }; - (:~ : Returns an attribute from a measure for labeling : @@ -86,9 +91,12 @@ declare function measure:getMeasures($mei as node(), $mdivID as xs:string) as xs : @return Attribute Label or N :) declare function measure:getMeasureLabelAttr($measure as node()){ - if(exists($measure[@label])) - then($measure/@label) - else($measure/@n) + + if(exists($measure[@label])) then ( + $measure/@label + ) else ( + $measure/@n + ) }; (:~ @@ -99,13 +107,16 @@ declare function measure:getMeasureLabelAttr($measure as node()){ : @return A span containing the label :) declare function measure:makeMeasureLabelCritical($measure as node(), $measureLabel as xs:string) as node() { + let $measureParentElem := local-name($measure/parent::node()) return - if($measureParentElem = 'supplied') - then({'[' || $measureLabel || ']'}) - else if($measureParentElem = 'del') - then({$measureLabel}) - else({$measureLabel}) + if($measureParentElem = 'supplied') then ( + {'[' || $measureLabel || ']'} + ) else if($measureParentElem = 'del') then ( + {$measureLabel} + ) else ( + {$measureLabel} + ) }; (:~ @@ -115,33 +126,37 @@ declare function measure:makeMeasureLabelCritical($measure as node(), $measureLa : @return A span containing the label :) declare function measure:getMeasureLabel($measure as node()) as node() { + let $measureLabel := measure:getMeasureLabelAttr($measure) let $measureID := $measure/@xml:id let $measureFacs := $measure/@facs let $measuresZoneRef := $measure/ancestor::mei:mdiv//mei:measure[@facs = $measureFacs] let $measureZoneRefCount := count($measuresZoneRef) + let $measureLabels := - if(not($measure/parent::mei:reg)) - then( - if(($measureZoneRefCount gt 1) and ($measure//mei:multiRest)) - then(for $measure in $measuresZoneRef - let $measureLabel := measure:getMeasureLabelAttr($measure) - let $measureLabel := measure:makeMeasureLabelCritical($measure, $measureLabel) - let $measureLabel := ($measureLabel || '–' || number($measureLabel) + number($measure//mei:multiRest/@num) - 1) - return - {$measureLabel} - ) - else if ($measureZoneRefCount gt 1) - then(for $label in $measuresZoneRef - return - measure:makeMeasureLabelCritical($label, $label/string(@label))) - else(measure:makeMeasureLabelCritical($measure, $measureLabel)) - ) - else if($measure/parent::mei:reg) - then(for $measure in $measuresZoneRef + if(not($measure/parent::mei:reg)) then ( + if(($measureZoneRefCount gt 1) and ($measure//mei:multiRest)) then ( + for $measure in $measuresZoneRef + let $measureLabel := measure:getMeasureLabelAttr($measure) + let $measureLabel := measure:makeMeasureLabelCritical($measure, $measureLabel) + let $measureLabel := ($measureLabel || '–' || number($measureLabel) + number($measure//mei:multiRest/@num) - 1) return - measure:getRegMeasureLabel($measure/parent::mei:reg)) - else(noLabel) + {$measureLabel} + ) else if ($measureZoneRefCount gt 1) then ( + for $label in $measuresZoneRef + return + measure:makeMeasureLabelCritical($label, $label/string(@label)) + ) else ( + measure:makeMeasureLabelCritical($measure, $measureLabel) + ) + ) else if($measure/parent::mei:reg) then ( + for $measure in $measuresZoneRef + return + measure:getRegMeasureLabel($measure/parent::mei:reg) + ) else ( + noLabel + ) + return measure:joinMeasureLabels($measureLabels) }; @@ -153,12 +168,16 @@ declare function measure:getMeasureLabel($measure as node()) as node() { : @return A span containing the joined label :) declare function measure:joinMeasureLabels($labels as node()*) as node() { - {for $label at $pos in functx:distinct-deep($labels) - return - if($pos = 1) - then($label) - else('/',$label) - } + + { + for $label at $pos in functx:distinct-deep($labels) + return + if($pos = 1) then ( + $label + ) else( + '/',$label + ) + } }; (:~ @@ -168,6 +187,7 @@ declare function measure:joinMeasureLabels($labels as node()*) as node() { : @return The label as string :) declare function measure:getRegMeasureLabel($reg as node()) as node() { + let $measures := $reg/mei:measure let $measuresCount := count($measures) let $measureStart := $measures[1] @@ -184,11 +204,14 @@ declare function measure:getRegMeasureLabel($reg as node()) as node() { : @return The value of the rest as string :) declare function measure:getMRest($measure) { - if($measure//mei:mRest) - then(string('1')) - else if($measure//mei:multiRest) - then($measure//mei:multiRest/string(@num)) - else(string('0')) + + if($measure//mei:mRest) then ( + string('1') + ) else if($measure//mei:multiRest) then( + $measure//mei:multiRest/string(@num) + ) else ( + string('0') + ) }; (:~ @@ -198,27 +221,37 @@ declare function measure:getMRest($measure) { : @return An array of strings :) declare function measure:analyzeLabels($measure as node()) { + let $labels := $measure/@label - let $labelsAnalyzed := for $label in $labels - return - if (contains($label, '–')) - then (let $first := substring-before($label, '–') - let $last := substring-after($label, '–') - let $steps := xs:integer(number($last) - number($first) + number(1)) - for $i in 1 to $steps return string(number($first) + $i - 1)) - else ($label) + + let $labelsAnalyzed := + for $label in $labels + return + if (contains($label, '–')) then ( + let $first := substring-before($label, '–') + let $last := substring-after($label, '–') + let $steps := xs:integer(number($last) - number($first) + number(1)) + for $i in 1 to $steps + return string(number($first) + $i - 1) + ) else ($label) + return - if($labels) - then($labelsAnalyzed) - else ($measure/@n) + if($labels) then ( + $labelsAnalyzed + ) else ( + $measure/@n + ) }; declare function measure:resolveMultiMeasureRests($mdiv as node(), $measureN as xs:string) { + let $measureNNumber := number($measureN) return - 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))]) + 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))] + ) }; (:~ @@ -240,7 +273,6 @@ declare function measure:getMeasuresOnPage($mei as node(), $surface as node()) a return for $measure in $measures let $measureLabel := measure:getMeasureLabel($measure) - return map { 'zoneId': $zone/string(@xml:id), From d7da75b9832efb792890ff945bfefbcde6b086b4 Mon Sep 17 00:00:00 2001 From: bwbohl Date: Mon, 26 Feb 2024 11:43:31 +0100 Subject: [PATCH 12/51] fix return tpe to proper JSON --- add/data/xql/getMeasuresOnPage.xql | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/add/data/xql/getMeasuresOnPage.xql b/add/data/xql/getMeasuresOnPage.xql index 0440dfd41..18e8eb16f 100644 --- a/add/data/xql/getMeasuresOnPage.xql +++ b/add/data/xql/getMeasuresOnPage.xql @@ -37,8 +37,6 @@ let $mei := doc($uri)/root() let $surface := $mei/id($surfaceId) return ( - array { - (: TODO: überlegen, wie die Staff-spezifischen Ausschnitte angezeigt werden sollen :) - measure:getMeasuresOnPage($mei, $surface) - } + (: TODO: überlegen, wie die Staff-spezifischen Ausschnitte angezeigt werden sollen :) + measure:getMeasuresOnPage($mei, $surface) ) From 14837c2761d9d49c583c69571af04e029d7e6a14 Mon Sep 17 00:00:00 2001 From: Dennis Ried Date: Fri, 21 Jun 2024 11:02:47 +0200 Subject: [PATCH 13/51] adding else case if no multiple measures point to a zone --- add/data/xqm/measure.xqm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/add/data/xqm/measure.xqm b/add/data/xqm/measure.xqm index f1ebb36f5..532cd3731 100644 --- a/add/data/xqm/measure.xqm +++ b/add/data/xqm/measure.xqm @@ -146,6 +146,8 @@ declare function measure:getMeasureLabel($measure as node()) as node() { for $label in $measuresZoneRef return measure:makeMeasureLabelCritical($label, $label/string(@label)) + ) else if ($measure//mei:multiRest) then ( + {$measureLabel || '–' || (number($measureLabel) + number($measure//mei:multiRest/@num) - 1)} ) else ( measure:makeMeasureLabelCritical($measure, $measureLabel) ) From 09974a5108d8d5c08cec9d0205c0e4e0dbf56a48 Mon Sep 17 00:00:00 2001 From: Peter Stadler Date: Fri, 8 Nov 2024 11:44:10 +0100 Subject: [PATCH 14/51] add first test for the measure module --- testing/XQSuite/measure-tests.xqm | 25 +++++++++++++++++++++++++ testing/XQSuite/run-unit-tests.xq | 4 +++- 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 testing/XQSuite/measure-tests.xqm diff --git a/testing/XQSuite/measure-tests.xqm b/testing/XQSuite/measure-tests.xqm new file mode 100644 index 000000000..95389a2df --- /dev/null +++ b/testing/XQSuite/measure-tests.xqm @@ -0,0 +1,25 @@ +xquery version "3.1"; + +module namespace measuretests = "http://www.edirom.de/xquery/xqsuite/measure-tests"; + +import module namespace measure = "http://www.edirom.de/xquery/measure" at "xmldb:exist:///db/apps/Edirom-Online/data/xqm/measure.xqm"; + +declare namespace mei="http://www.music-encoding.org/ns/mei"; +declare namespace tei="http://www.tei-c.org/ns/1.0"; +declare namespace test="http://exist-db.org/xquery/xqsuite"; +declare namespace xhtml="http://www.w3.org/1999/xhtml"; + +declare + %test:args("Some Title") %test:assertEmpty + %test:args("some content") %test:assertEquals("1") + %test:args("some content") %test:assertEquals("foo") + %test:args("some content") %test:assertEquals("bar") + %test:args("some content") %test:assertEquals("bar") + function measuretests:getMeasureLabelAttr($node as element()) { + measure:getMeasureLabelAttr($node) +}; diff --git a/testing/XQSuite/run-unit-tests.xq b/testing/XQSuite/run-unit-tests.xq index 6b11c1a37..709b51c98 100644 --- a/testing/XQSuite/run-unit-tests.xq +++ b/testing/XQSuite/run-unit-tests.xq @@ -9,8 +9,10 @@ xquery version "3.1"; import module namespace test="http://exist-db.org/xquery/xqsuite" at "resource:org/exist/xquery/lib/xqsuite/xqsuite.xql"; import module namespace eut="http://www.edirom.de/xquery/xqsuite/eutil-tests" at "eutil-tests.xqm"; +import module namespace measuretests = "http://www.edirom.de/xquery/xqsuite/measure-tests" at "measure-tests.xqm"; (: the test:suite() function will run all the test-annotated functions in the module whose namespace URI you provide :) test:suite(( - util:list-functions("http://www.edirom.de/xquery/xqsuite/eutil-tests") + util:list-functions("http://www.edirom.de/xquery/xqsuite/eutil-tests"), + util:list-functions("http://www.edirom.de/xquery/xqsuite/measure-tests") )) From 9b2d51efaf94db8db3db4db6675b2a15eea32dfc Mon Sep 17 00:00:00 2001 From: Dennis Ried Date: Thu, 7 Nov 2024 18:30:33 +0100 Subject: [PATCH 15/51] fixing broken syntax https://github.com/Edirom/Edirom-Online/pull/302#pullrequestreview-2420605260 --- add/data/xql/getMeasurePage.xql | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/add/data/xql/getMeasurePage.xql b/add/data/xql/getMeasurePage.xql index 4c2563614..36c91879d 100644 --- a/add/data/xql/getMeasurePage.xql +++ b/add/data/xql/getMeasurePage.xql @@ -25,7 +25,8 @@ declare function local:findMeasure($mei, $movementId, $measureIdName) as element ($m) else (($mei/id($movementId)//mei:measure[@label eq $measureIdName], $mei/id($movementId)//mei:measure[@n eq $measureIdName])[1]) -} +}; + declare function local:getMeasure($mei, $measure, $movementId) as map(*) { let $measureId := $measure/string(@xml:id) let $zoneId := substring-after($measure/string(@facs), '#') From 62cc4d4c03931959d14a9ae0e65b39c386010583 Mon Sep 17 00:00:00 2001 From: Dennis Ried Date: Wed, 13 Nov 2024 09:07:06 +0100 Subject: [PATCH 16/51] adding documentation and return types #302 --- add/data/xqm/measure.xqm | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/add/data/xqm/measure.xqm b/add/data/xqm/measure.xqm index 532cd3731..3f847caaa 100644 --- a/add/data/xqm/measure.xqm +++ b/add/data/xqm/measure.xqm @@ -90,7 +90,7 @@ declare function measure:getMeasures($mei as node(), $mdivID as xs:string) as xs : @param $measure The measure to be processed : @return Attribute Label or N :) -declare function measure:getMeasureLabelAttr($measure as node()){ +declare function measure:getMeasureLabelAttr($measure as node()) as xs:string { if(exists($measure[@label])) then ( $measure/@label @@ -205,7 +205,7 @@ declare function measure:getRegMeasureLabel($reg as node()) as node() { : @param $measure The measure to be processed : @return The value of the rest as string :) -declare function measure:getMRest($measure) { +declare function measure:getMRest($measure) as xs:string { if($measure//mei:mRest) then ( string('1') @@ -222,7 +222,7 @@ declare function measure:getMRest($measure) { : @param $measure The measure to be processed : @return An array of strings :) -declare function measure:analyzeLabels($measure as node()) { +declare function measure:analyzeLabels($measure as node()) as xs:string* { let $labels := $measure/@label @@ -245,8 +245,14 @@ declare function measure:analyzeLabels($measure as node()) { ) }; -declare function measure:resolveMultiMeasureRests($mdiv as node(), $measureN as xs:string) { - +(:~ + : Resolvs multi-measure rests + : + : @param $mdiv The mdiv to be processed + : @param $measureN The number of the measure to be resolved + : @return The measures coverd by the multi-measure rest + :) +declare function measure:resolveMultiMeasureRests($mdiv as node(), $measureN as xs:string) as node()* { let $measureNNumber := number($measureN) return if ($mdiv//mei:measure/@label) then ( From 2beae371626334b65699085bdebc7e23152e22be Mon Sep 17 00:00:00 2001 From: Dennis Ried Date: Wed, 13 Nov 2024 09:50:09 +0100 Subject: [PATCH 17/51] extend handling for mei:perfRes attributes --- add/data/xqm/util.xqm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/add/data/xqm/util.xqm b/add/data/xqm/util.xqm index 49e466099..39f54d309 100644 --- a/add/data/xqm/util.xqm +++ b/add/data/xqm/util.xqm @@ -208,6 +208,7 @@ declare function eutil:getDocumentLabel($doc as xs:string, $edition as xs:string declare function eutil:getPartLabel($measureOrPerfRes as node(), $type as xs:string) as xs:string { (: request:get-parameter('lang', '') doesn't work?? [DeRi]:) + (: replace with eutil:getLanguage($edition) or similar:) let $lang := if(request:get-parameter('lang', '') = '') then @@ -221,9 +222,9 @@ declare function eutil:getPartLabel($measureOrPerfRes as node(), $type as xs:str let $perfResLabel := if($type eq 'measure') then - ($measureOrPerfRes/ancestor::mei:mei/id($voiceID)/@label) + ($measureOrPerfRes/ancestor::mei:mei/id($voiceID)/(@label|@codedval)) else - ($measureOrPerfRes/@label) + ($measureOrPerfRes/(@label|@codedval)) let $dictKey := 'perfMedium.perfRes.' || functx:substring-before-if-contains($perfResLabel,'.') From da9a7ecf771f8d2dd6c680732cbc000c8ab936ca Mon Sep 17 00:00:00 2001 From: Peter Stadler Date: Fri, 15 Nov 2024 09:48:23 +0100 Subject: [PATCH 18/51] need to catch errors and failures --- testing/ant-tests.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/ant-tests.xml b/testing/ant-tests.xml index 2a67eabdd..03bdf40a0 100644 --- a/testing/ant-tests.xml +++ b/testing/ant-tests.xml @@ -32,7 +32,7 @@ - + From ce0b55af060d07ecf47b09705475b49d5f4115bd Mon Sep 17 00:00:00 2001 From: Peter Stadler Date: Fri, 15 Nov 2024 09:49:00 +0100 Subject: [PATCH 19/51] add initial test for `measure:resolveMultiMeasureRests#2` along with test data --- testing/XQSuite/measure-tests.xqm | 9 + .../XQSuite/testdata/multiMeasureRests.xml | 172 ++++++++++++++++++ 2 files changed, 181 insertions(+) create mode 100644 testing/XQSuite/testdata/multiMeasureRests.xml diff --git a/testing/XQSuite/measure-tests.xqm b/testing/XQSuite/measure-tests.xqm index 95389a2df..df37080e9 100644 --- a/testing/XQSuite/measure-tests.xqm +++ b/testing/XQSuite/measure-tests.xqm @@ -23,3 +23,12 @@ declare function measuretests:getMeasureLabelAttr($node as element()) { measure:getMeasureLabelAttr($node) }; + +declare + %test:args("4") %test:assertEmpty + %test:args("foo") %test:assertEmpty + %test:args("108") %test:assertExists + function measuretests:resolveMultiMeasureRests($measureN as xs:string) as node()* { + doc("testdata/multiMeasureRests.xml")/mei:mdiv => + measure:resolveMultiMeasureRests($measureN) +}; diff --git a/testing/XQSuite/testdata/multiMeasureRests.xml b/testing/XQSuite/testdata/multiMeasureRests.xml new file mode 100644 index 000000000..03e03a18e --- /dev/null +++ b/testing/XQSuite/testdata/multiMeasureRests.xml @@ -0,0 +1,172 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + (Fine) + +

Der Stichfehler in der Cl (zwei statt vier Takte Pause nach T. 105) wurde in ED₂ + nicht korrigiert und hat daher Eingang in weitere Ausgaben gefunden.

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + p + Trio + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
From ae98754506300d3e351031b13c1fb71ec901fb4c Mon Sep 17 00:00:00 2001 From: Dennis Ried Date: Sat, 23 Nov 2024 16:33:13 +0100 Subject: [PATCH 20/51] Update add/data/xqm/measure.xqm Co-authored-by: Peter Stadler --- add/data/xqm/measure.xqm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/add/data/xqm/measure.xqm b/add/data/xqm/measure.xqm index 3f847caaa..3e5bda643 100644 --- a/add/data/xqm/measure.xqm +++ b/add/data/xqm/measure.xqm @@ -88,7 +88,7 @@ declare function measure:getMeasures($mei as node(), $mdivID as xs:string) as xs : Returns an attribute from a measure for labeling : : @param $measure The measure to be processed - : @return Attribute Label or N + : @return the string value of the `@label` or the `@n` attribute if present, the empty sequence otherwise. :) declare function measure:getMeasureLabelAttr($measure as node()) as xs:string { From f0dc4b60134a7e45a71ba81e8eac46d743e8e7e6 Mon Sep 17 00:00:00 2001 From: Dennis Ried Date: Sat, 23 Nov 2024 16:33:24 +0100 Subject: [PATCH 21/51] Update add/data/xqm/measure.xqm Co-authored-by: Peter Stadler --- add/data/xqm/measure.xqm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/add/data/xqm/measure.xqm b/add/data/xqm/measure.xqm index 3e5bda643..a02876a7f 100644 --- a/add/data/xqm/measure.xqm +++ b/add/data/xqm/measure.xqm @@ -93,7 +93,7 @@ declare function measure:getMeasures($mei as node(), $mdivID as xs:string) as xs declare function measure:getMeasureLabelAttr($measure as node()) as xs:string { if(exists($measure[@label])) then ( - $measure/@label + $measure/@label => data() ) else ( $measure/@n ) From c3971d72d8be7eaed086e1092d0f272b9a5c4c4d Mon Sep 17 00:00:00 2001 From: Dennis Ried Date: Sat, 23 Nov 2024 16:33:32 +0100 Subject: [PATCH 22/51] Update add/data/xqm/measure.xqm Co-authored-by: Peter Stadler --- add/data/xqm/measure.xqm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/add/data/xqm/measure.xqm b/add/data/xqm/measure.xqm index a02876a7f..0e8be34b4 100644 --- a/add/data/xqm/measure.xqm +++ b/add/data/xqm/measure.xqm @@ -95,7 +95,7 @@ declare function measure:getMeasureLabelAttr($measure as node()) as xs:string { if(exists($measure[@label])) then ( $measure/@label => data() ) else ( - $measure/@n + $measure/@n => data() ) }; From 006fe7bda1bdb9db1d084a327b968cd56c565063 Mon Sep 17 00:00:00 2001 From: Dennis Ried Date: Sat, 23 Nov 2024 16:33:44 +0100 Subject: [PATCH 23/51] Update add/data/xqm/measure.xqm Co-authored-by: Peter Stadler --- add/data/xqm/measure.xqm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/add/data/xqm/measure.xqm b/add/data/xqm/measure.xqm index 0e8be34b4..4ea8c16c6 100644 --- a/add/data/xqm/measure.xqm +++ b/add/data/xqm/measure.xqm @@ -85,7 +85,8 @@ declare function measure:getMeasures($mei as node(), $mdivID as xs:string) as xs }; (:~ - : Returns an attribute from a measure for labeling + : Returns a label for a measure, taken either from the `@label` attribute + : if present or the `@n` attribute otherwise. : : @param $measure The measure to be processed : @return the string value of the `@label` or the `@n` attribute if present, the empty sequence otherwise. From 537bf5e99fe7a17294b574857f7266169101563e Mon Sep 17 00:00:00 2001 From: Dennis Ried Date: Wed, 4 Dec 2024 19:51:19 +0100 Subject: [PATCH 24/51] Update add/data/xqm/measure.xqm Co-authored-by: Peter Stadler --- add/data/xqm/measure.xqm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/add/data/xqm/measure.xqm b/add/data/xqm/measure.xqm index 4ea8c16c6..b478410a4 100644 --- a/add/data/xqm/measure.xqm +++ b/add/data/xqm/measure.xqm @@ -91,7 +91,7 @@ declare function measure:getMeasures($mei as node(), $mdivID as xs:string) as xs : @param $measure The measure to be processed : @return the string value of the `@label` or the `@n` attribute if present, the empty sequence otherwise. :) -declare function measure:getMeasureLabelAttr($measure as node()) as xs:string { +declare function measure:getMeasureLabelAttr($measure as element(mei:measure)) as xs:string? { if(exists($measure[@label])) then ( $measure/@label => data() From 7f89d50c0325b1fc77daf65c20407236eef61ed9 Mon Sep 17 00:00:00 2001 From: Dennis Ried Date: Wed, 4 Dec 2024 20:02:48 +0100 Subject: [PATCH 25/51] small adjustments following suggestions of the code review --- add/data/xqm/measure.xqm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/add/data/xqm/measure.xqm b/add/data/xqm/measure.xqm index 4ea8c16c6..e083124d6 100644 --- a/add/data/xqm/measure.xqm +++ b/add/data/xqm/measure.xqm @@ -254,12 +254,12 @@ declare function measure:analyzeLabels($measure as node()) as xs:string* { : @return The measures coverd by the multi-measure rest :) declare function measure:resolveMultiMeasureRests($mdiv as node(), $measureN as xs:string) as node()* { - let $measureNNumber := number($measureN) + let $measureNNumber := $measureN/number() return - 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, '–')))] + if ($mdiv//mei:measure[.//mei:multiRest][@label]) then ( + $mdiv//mei:measure[.//mei:multiRest][substring-before(@label, '–')/number() <= $measureNNumber][.//mei:multiRest/@num/number() gt ($measureNNumber - substring-before(@label, '–')/number())] ) else ( - $mdiv//mei:measure[.//mei:multiRest][number(@n) lt $measureNNumber][.//mei:multiRest/number(@num) gt ($measureNNumber - number(@n))] + $mdiv//mei:measure[.//mei:multiRest][@n/number() lt $measureNNumber][.//mei:multiRest/@num/number() gt ($measureNNumber - @n/number())] ) }; From b1bcda699eabefd8e2f599f4ae668b3323994904 Mon Sep 17 00:00:00 2001 From: Dennis Ried Date: Tue, 10 Dec 2024 09:39:09 +0100 Subject: [PATCH 26/51] Update add/data/xqm/measure.xqm Co-authored-by: Peter Stadler --- add/data/xqm/measure.xqm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/add/data/xqm/measure.xqm b/add/data/xqm/measure.xqm index f35e11e37..1085c9765 100644 --- a/add/data/xqm/measure.xqm +++ b/add/data/xqm/measure.xqm @@ -206,7 +206,7 @@ declare function measure:getRegMeasureLabel($reg as node()) as node() { : @param $measure The measure to be processed : @return The value of the rest as string :) -declare function measure:getMRest($measure) as xs:string { +declare function measure:getMRest($measure as element(mei:measure)) as xs:string { if($measure//mei:mRest) then ( string('1') From 59154139d70f02deb098beb3e8f95f213efe2241 Mon Sep 17 00:00:00 2001 From: Dennis Ried Date: Tue, 10 Dec 2024 09:42:37 +0100 Subject: [PATCH 27/51] Update add/data/xqm/measure.xqm Co-authored-by: Peter Stadler --- add/data/xqm/measure.xqm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/add/data/xqm/measure.xqm b/add/data/xqm/measure.xqm index 1085c9765..1b1f45451 100644 --- a/add/data/xqm/measure.xqm +++ b/add/data/xqm/measure.xqm @@ -223,7 +223,7 @@ declare function measure:getMRest($measure as element(mei:measure)) as xs:string : @param $measure The measure to be processed : @return An array of strings :) -declare function measure:analyzeLabels($measure as node()) as xs:string* { +declare function measure:analyzeLabels($measure as element(mei:measure)) as xs:string* { let $labels := $measure/@label From c8ec168653899b3662be401b815adba78d6399aa Mon Sep 17 00:00:00 2001 From: Dennis Ried Date: Tue, 10 Dec 2024 09:50:52 +0100 Subject: [PATCH 28/51] revert 7f89d50c0325b1fc77daf65c20407236eef61ed9 partially --- add/data/xqm/measure.xqm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/add/data/xqm/measure.xqm b/add/data/xqm/measure.xqm index 1b1f45451..76091152f 100644 --- a/add/data/xqm/measure.xqm +++ b/add/data/xqm/measure.xqm @@ -254,12 +254,12 @@ declare function measure:analyzeLabels($measure as element(mei:measure)) as xs:s : @return The measures coverd by the multi-measure rest :) declare function measure:resolveMultiMeasureRests($mdiv as node(), $measureN as xs:string) as node()* { - let $measureNNumber := $measureN/number() + let $measureNNumber := number($measureN) return if ($mdiv//mei:measure[.//mei:multiRest][@label]) then ( - $mdiv//mei:measure[.//mei:multiRest][substring-before(@label, '–')/number() <= $measureNNumber][.//mei:multiRest/@num/number() gt ($measureNNumber - substring-before(@label, '–')/number())] + number($mdiv//mei:measure[.//mei:multiRest][substring-before(@label, '–')) <= $measureNNumber][.//mei:multiRest/number(@num) gt (number($measureNNumber - substring-before(@label, '–')))] ) else ( - $mdiv//mei:measure[.//mei:multiRest][@n/number() lt $measureNNumber][.//mei:multiRest/@num/number() gt ($measureNNumber - @n/number())] + $mdiv//mei:measure[.//mei:multiRest][number(@n) lt $measureNNumber][.//mei:multiRest/number(@num) gt ($measureNNumber - number(@n))] ) }; From a7a604f88b111916e27aaa3aba45fab4a4f55237 Mon Sep 17 00:00:00 2001 From: Dennis Ried Date: Tue, 10 Dec 2024 09:55:49 +0100 Subject: [PATCH 29/51] adding xhtml namespace to created elements --- add/data/xqm/measure.xqm | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/add/data/xqm/measure.xqm b/add/data/xqm/measure.xqm index 76091152f..19ba8e05e 100644 --- a/add/data/xqm/measure.xqm +++ b/add/data/xqm/measure.xqm @@ -19,6 +19,7 @@ import module namespace eutil="http://www.edirom.de/xquery/util" at "/db/apps/Ed (: NAMESPACE DECLARATIONS ================================================== :) declare namespace mei="http://www.music-encoding.org/ns/mei"; +declare namespace xhtml="http://www.w3.org/1999/xhtml"; (: FUNCTION DECLARATIONS =================================================== :) @@ -112,11 +113,11 @@ declare function measure:makeMeasureLabelCritical($measure as node(), $measureLa let $measureParentElem := local-name($measure/parent::node()) return if($measureParentElem = 'supplied') then ( - {'[' || $measureLabel || ']'} + {'[' || $measureLabel || ']'} ) else if($measureParentElem = 'del') then ( - {$measureLabel} + {$measureLabel} ) else ( - {$measureLabel} + {$measureLabel} ) }; @@ -142,13 +143,13 @@ declare function measure:getMeasureLabel($measure as node()) as node() { let $measureLabel := measure:makeMeasureLabelCritical($measure, $measureLabel) let $measureLabel := ($measureLabel || '–' || number($measureLabel) + number($measure//mei:multiRest/@num) - 1) return - {$measureLabel} + {$measureLabel} ) else if ($measureZoneRefCount gt 1) then ( for $label in $measuresZoneRef return measure:makeMeasureLabelCritical($label, $label/string(@label)) ) else if ($measure//mei:multiRest) then ( - {$measureLabel || '–' || (number($measureLabel) + number($measure//mei:multiRest/@num) - 1)} + {$measureLabel || '–' || (number($measureLabel) + number($measure//mei:multiRest/@num) - 1)} ) else ( measure:makeMeasureLabelCritical($measure, $measureLabel) ) @@ -157,7 +158,7 @@ declare function measure:getMeasureLabel($measure as node()) as node() { return measure:getRegMeasureLabel($measure/parent::mei:reg) ) else ( - noLabel + noLabel ) return @@ -172,7 +173,7 @@ declare function measure:getMeasureLabel($measure as node()) as node() { :) declare function measure:joinMeasureLabels($labels as node()*) as node() { - { + { for $label at $pos in functx:distinct-deep($labels) return if($pos = 1) then ( @@ -180,7 +181,7 @@ declare function measure:joinMeasureLabels($labels as node()*) as node() { ) else( '/',$label ) - } + } }; (:~ @@ -197,7 +198,7 @@ declare function measure:getRegMeasureLabel($reg as node()) as node() { let $measureStop := $measures[$measuresCount] let $measureLabel := measure:getMeasureLabelAttr($measureStart) || '–' || measure:getMeasureLabelAttr($measureStop) return - {$measureLabel} + {$measureLabel} }; (:~ From 5522f8a3bfc205fc8024b0cb3c8745cba79bf190 Mon Sep 17 00:00:00 2001 From: Dennis Ried Date: Tue, 10 Dec 2024 10:02:39 +0100 Subject: [PATCH 30/51] update variable names, remove obsolete loop --- add/data/xqm/measure.xqm | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/add/data/xqm/measure.xqm b/add/data/xqm/measure.xqm index 19ba8e05e..37547d206 100644 --- a/add/data/xqm/measure.xqm +++ b/add/data/xqm/measure.xqm @@ -37,7 +37,7 @@ declare function measure:getMeasures($mei as node(), $mdivID as xs:string) as xs let $measureNs := for $measure in $mdiv//mei:measure - return measure:analyzeLabels($measure) + return measure:analyzeLabel($measure) let $measureNsDistinct := distinct-values(eutil:sort-as-numeric-alpha($measureNs)) @@ -224,24 +224,22 @@ declare function measure:getMRest($measure as element(mei:measure)) as xs:string : @param $measure The measure to be processed : @return An array of strings :) -declare function measure:analyzeLabels($measure as element(mei:measure)) as xs:string* { +declare function measure:analyzeLabel($measure as element(mei:measure)) as xs:string* { - let $labels := $measure/@label + let $label := $measure/@label - let $labelsAnalyzed := - for $label in $labels - return - if (contains($label, '–')) then ( - let $first := substring-before($label, '–') - let $last := substring-after($label, '–') - let $steps := xs:integer(number($last) - number($first) + number(1)) - for $i in 1 to $steps - return string(number($first) + $i - 1) - ) else ($label) - - return - if($labels) then ( - $labelsAnalyzed + let $labelAnalyzed := if (contains($label, '–')) then( + let $first := substring-before($label, '–') + let $last := substring-after($label, '–') + let $steps := xs:integer(number($last) - number($first) + number(1)) + for $i in 1 to $steps + return + string(number($first) + $i - 1) + ) else ($label) + + return + if($label) then ( + $labelAnalyzed ) else ( $measure/@n ) From 8708dccc3fd39a4b61f4e53263228506255eb51f Mon Sep 17 00:00:00 2001 From: Dennis Ried Date: Tue, 10 Dec 2024 10:45:13 +0100 Subject: [PATCH 31/51] fix syntax error --- add/data/xqm/measure.xqm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/add/data/xqm/measure.xqm b/add/data/xqm/measure.xqm index 37547d206..95a6ce35d 100644 --- a/add/data/xqm/measure.xqm +++ b/add/data/xqm/measure.xqm @@ -256,7 +256,7 @@ declare function measure:resolveMultiMeasureRests($mdiv as node(), $measureN as let $measureNNumber := number($measureN) return if ($mdiv//mei:measure[.//mei:multiRest][@label]) then ( - number($mdiv//mei:measure[.//mei:multiRest][substring-before(@label, '–')) <= $measureNNumber][.//mei:multiRest/number(@num) gt (number($measureNNumber - substring-before(@label, '–')))] + $mdiv//mei:measure[.//mei:multiRest][number(substring-before(@label, '–')) <= $measureNNumber][.//mei:multiRest/number(@num) gt number($measureNNumber - substring-before(@label, '–'))] ) else ( $mdiv//mei:measure[.//mei:multiRest][number(@n) lt $measureNNumber][.//mei:multiRest/number(@num) gt ($measureNNumber - number(@n))] ) From 741a51a750b7ee8432db9bc1ab2946d4d1b83750 Mon Sep 17 00:00:00 2001 From: Dennis Ried Date: Tue, 10 Dec 2024 10:45:34 +0100 Subject: [PATCH 32/51] add fallback (key not found) --- add/data/xqm/eutil.xqm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/add/data/xqm/eutil.xqm b/add/data/xqm/eutil.xqm index 7af8df142..e25cdf3e7 100644 --- a/add/data/xqm/eutil.xqm +++ b/add/data/xqm/eutil.xqm @@ -267,7 +267,9 @@ declare function eutil:getLanguageString($key as xs:string, $values as xs:string let $base := system:get-module-load-path() let $file := eutil:getDoc(concat($base, '/../locale/edirom-lang-', $lang, '.xml')) - let $string := $file//entry[@key = $key]/string(@value) + let $string := if($file//entry[@key = $key]) then ( + $file//entry[@key = $key]/string(@value) + ) else('noValueFound') let $string := functx:replace-multi($string, for $i in (0 to (count($values) - 1)) return concat('\{',$i,'\}'), $values) return From 13c8c8b4c856be46045254b07c54ff5e80ef9025 Mon Sep 17 00:00:00 2001 From: Dennis Ried Date: Tue, 10 Dec 2024 10:55:40 +0100 Subject: [PATCH 33/51] fix namespace and module location --- add/data/xql/getMeasuresOnPage.xql | 2 +- add/data/xqm/measure.xqm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/add/data/xql/getMeasuresOnPage.xql b/add/data/xql/getMeasuresOnPage.xql index 28d76d345..90e3a69e1 100644 --- a/add/data/xql/getMeasuresOnPage.xql +++ b/add/data/xql/getMeasuresOnPage.xql @@ -11,7 +11,7 @@ xquery version "3.1"; (: IMPORTS ================================================================= :) -import module namespace eutil="http://www.edirom.de/xquery/util" at "/db/apps/Edirom-Online/data/xqm/util.xqm"; +import module namespace eutil="http://www.edirom.de/xquery/eutil" at "/db/apps/Edirom-Online/data/xqm/eutil.xqm"; import module namespace measure = "http://www.edirom.de/xquery/measure" at "/db/apps/Edirom-Online/data/xqm/measure.xqm"; diff --git a/add/data/xqm/measure.xqm b/add/data/xqm/measure.xqm index 95a6ce35d..8c31fbf7d 100644 --- a/add/data/xqm/measure.xqm +++ b/add/data/xqm/measure.xqm @@ -14,7 +14,7 @@ module namespace measure = "http://www.edirom.de/xquery/measure"; import module namespace functx="http://www.functx.com"; -import module namespace eutil="http://www.edirom.de/xquery/util" at "/db/apps/Edirom-Online/data/xqm/util.xqm"; +import module namespace eutil="http://www.edirom.de/xquery/eutil" at "/db/apps/Edirom-Online/data/xqm/eutil.xqm"; (: NAMESPACE DECLARATIONS ================================================== :) From e5dc953ce912c4bcff107447aa6c433fc3940afd Mon Sep 17 00:00:00 2001 From: Dennis Ried Date: Tue, 10 Dec 2024 10:55:58 +0100 Subject: [PATCH 34/51] add extended handling for perfRes labeling --- add/data/xqm/eutil.xqm | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/add/data/xqm/eutil.xqm b/add/data/xqm/eutil.xqm index e25cdf3e7..e37e4a363 100644 --- a/add/data/xqm/eutil.xqm +++ b/add/data/xqm/eutil.xqm @@ -215,12 +215,17 @@ declare function eutil:getPartLabel($measureOrPerfRes as node(), $type as xs:str let $part := $measureOrPerfRes/ancestor::mei:part let $voiceRef := $part//mei:staffDef/@decls let $voiceID := substring-after($voiceRef, '#') + let $voiceElem := $measureOrPerfRes/ancestor::mei:mei/id($voiceID) let $perfResLabel := - if($type eq 'measure') then - ($measureOrPerfRes/ancestor::mei:mei/id($voiceID)/(@label|@codedval)) + if($type eq 'measure' and $voiceElem[@label]) then + ($voiceElem/@label) + else if($type eq 'measure' and $voiceElem[@codedval]) then + ($voiceElem/@codedval) + else if ($measureOrPerfRes[@label]) then + ($measureOrPerfRes/@label) else - ($measureOrPerfRes/(@label|@codedval)) + ($measureOrPerfRes/@codedval) let $dictKey := 'perfMedium.perfRes.' || functx:substring-before-if-contains($perfResLabel,'.') From 5452ba60a34ea4d31aea7e66a2980a4b5eeac4a3 Mon Sep 17 00:00:00 2001 From: Dennis Ried Date: Tue, 10 Dec 2024 14:26:38 +0100 Subject: [PATCH 35/51] Update add/data/xqm/measure.xqm Co-authored-by: Peter Stadler --- add/data/xqm/measure.xqm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/add/data/xqm/measure.xqm b/add/data/xqm/measure.xqm index 8c31fbf7d..ebba2115c 100644 --- a/add/data/xqm/measure.xqm +++ b/add/data/xqm/measure.xqm @@ -250,7 +250,7 @@ declare function measure:analyzeLabel($measure as element(mei:measure)) as xs:st : : @param $mdiv The mdiv to be processed : @param $measureN The number of the measure to be resolved - : @return The measures coverd by the multi-measure rest + : @return The measures covered by the multi-measure rest :) declare function measure:resolveMultiMeasureRests($mdiv as node(), $measureN as xs:string) as node()* { let $measureNNumber := number($measureN) From 6946585101c3b32dc2b42c38b3bd7782f0156dd0 Mon Sep 17 00:00:00 2001 From: Dennis Ried Date: Tue, 10 Dec 2024 14:26:48 +0100 Subject: [PATCH 36/51] Update add/data/xqm/measure.xqm Co-authored-by: Peter Stadler --- add/data/xqm/measure.xqm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/add/data/xqm/measure.xqm b/add/data/xqm/measure.xqm index ebba2115c..53a470aa3 100644 --- a/add/data/xqm/measure.xqm +++ b/add/data/xqm/measure.xqm @@ -222,7 +222,7 @@ declare function measure:getMRest($measure as element(mei:measure)) as xs:string : Returns resolved labels : : @param $measure The measure to be processed - : @return An array of strings + : @return A sequence of strings :) declare function measure:analyzeLabel($measure as element(mei:measure)) as xs:string* { From 2acb3b2149bb4e06053e4c53529fb110cbe26342 Mon Sep 17 00:00:00 2001 From: Dennis Ried Date: Tue, 10 Dec 2024 14:28:41 +0100 Subject: [PATCH 37/51] Update add/data/xqm/measure.xqm Co-authored-by: Peter Stadler --- add/data/xqm/measure.xqm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/add/data/xqm/measure.xqm b/add/data/xqm/measure.xqm index 53a470aa3..d93fb5776 100644 --- a/add/data/xqm/measure.xqm +++ b/add/data/xqm/measure.xqm @@ -190,7 +190,7 @@ declare function measure:joinMeasureLabels($labels as node()*) as node() { : @param $reg The reg element (containing measure) to be processed : @return The label as string :) -declare function measure:getRegMeasureLabel($reg as node()) as node() { +declare function measure:getRegMeasureLabel($reg as node()) as element(xhtml:span) { let $measures := $reg/mei:measure let $measuresCount := count($measures) From 91349fa4e15f5ff6fd56af7eb05b28019ce298f6 Mon Sep 17 00:00:00 2001 From: Dennis Ried Date: Tue, 10 Dec 2024 14:28:52 +0100 Subject: [PATCH 38/51] Update add/data/xqm/measure.xqm Co-authored-by: Peter Stadler --- add/data/xqm/measure.xqm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/add/data/xqm/measure.xqm b/add/data/xqm/measure.xqm index d93fb5776..d9c44eb8e 100644 --- a/add/data/xqm/measure.xqm +++ b/add/data/xqm/measure.xqm @@ -267,7 +267,7 @@ declare function measure:resolveMultiMeasureRests($mdiv as node(), $measureN as : : @param $mei The sourcefile : @param $surface The surface to look at - : @returns A list of json objects with measure information + : @returns A sequence of map objects with measure information :) declare function measure:getMeasuresOnPage($mei as node(), $surface as node()) as map(*)* { From 07141a9f5d8e2e781810a04a8e4b397ea3824241 Mon Sep 17 00:00:00 2001 From: Dennis Ried Date: Tue, 10 Dec 2024 14:29:04 +0100 Subject: [PATCH 39/51] Update add/data/xqm/measure.xqm Co-authored-by: Peter Stadler --- add/data/xqm/measure.xqm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/add/data/xqm/measure.xqm b/add/data/xqm/measure.xqm index d9c44eb8e..9239aa7de 100644 --- a/add/data/xqm/measure.xqm +++ b/add/data/xqm/measure.xqm @@ -108,7 +108,7 @@ declare function measure:getMeasureLabelAttr($measure as element(mei:measure)) a : @param $measureLabel The label of the measure : @return A span containing the label :) -declare function measure:makeMeasureLabelCritical($measure as node(), $measureLabel as xs:string) as node() { +declare function measure:makeMeasureLabelCritical($measure as node(), $measureLabel as xs:string) as element(xhtml:span) { let $measureParentElem := local-name($measure/parent::node()) return From def111dac49f7e97cf52f161cd41f14c1861bb08 Mon Sep 17 00:00:00 2001 From: Dennis Ried Date: Tue, 10 Dec 2024 14:29:24 +0100 Subject: [PATCH 40/51] Update testing/XQSuite/measure-tests.xqm Co-authored-by: Peter Stadler --- testing/XQSuite/measure-tests.xqm | 2 -- 1 file changed, 2 deletions(-) diff --git a/testing/XQSuite/measure-tests.xqm b/testing/XQSuite/measure-tests.xqm index df37080e9..bb7612689 100644 --- a/testing/XQSuite/measure-tests.xqm +++ b/testing/XQSuite/measure-tests.xqm @@ -10,8 +10,6 @@ declare namespace test="http://exist-db.org/xquery/xqsuite"; declare namespace xhtml="http://www.w3.org/1999/xhtml"; declare - %test:args("Some Title") %test:assertEmpty %test:args("some content") %test:assertEquals("1") %test:args(" Date: Tue, 10 Dec 2024 14:29:46 +0100 Subject: [PATCH 41/51] Update add/data/xqm/measure.xqm Co-authored-by: Peter Stadler --- add/data/xqm/measure.xqm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/add/data/xqm/measure.xqm b/add/data/xqm/measure.xqm index 9239aa7de..323308ec5 100644 --- a/add/data/xqm/measure.xqm +++ b/add/data/xqm/measure.xqm @@ -171,7 +171,7 @@ declare function measure:getMeasureLabel($measure as node()) as node() { : @param $labels The measure to be processed : @return A span containing the joined label :) -declare function measure:joinMeasureLabels($labels as node()*) as node() { +declare function measure:joinMeasureLabels($labels as node()*) as element(xhtml:span) { { for $label at $pos in functx:distinct-deep($labels) From 88212eb7e3c943899711c38c856c1279bc1bd8df Mon Sep 17 00:00:00 2001 From: Dennis Ried Date: Tue, 10 Dec 2024 14:30:04 +0100 Subject: [PATCH 42/51] Update add/data/xqm/measure.xqm Co-authored-by: Peter Stadler --- add/data/xqm/measure.xqm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/add/data/xqm/measure.xqm b/add/data/xqm/measure.xqm index 323308ec5..c26009549 100644 --- a/add/data/xqm/measure.xqm +++ b/add/data/xqm/measure.xqm @@ -127,7 +127,7 @@ declare function measure:makeMeasureLabelCritical($measure as node(), $measureLa : @param $measure The measure to be processed : @return A span containing the label :) -declare function measure:getMeasureLabel($measure as node()) as node() { +declare function measure:getMeasureLabel($measure as element(mei:measure)) as element(xhtml:span) { let $measureLabel := measure:getMeasureLabelAttr($measure) let $measureID := $measure/@xml:id From 4d745b92a02def43479b0ba5db1f3892d03aff6c Mon Sep 17 00:00:00 2001 From: Peter Stadler Date: Wed, 11 Dec 2024 08:04:11 +0100 Subject: [PATCH 43/51] add test for `getMeasureLabel#1` --- testing/XQSuite/measure-tests.xqm | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/testing/XQSuite/measure-tests.xqm b/testing/XQSuite/measure-tests.xqm index bb7612689..d0cd72f18 100644 --- a/testing/XQSuite/measure-tests.xqm +++ b/testing/XQSuite/measure-tests.xqm @@ -30,3 +30,12 @@ declare doc("testdata/multiMeasureRests.xml")/mei:mdiv => measure:resolveMultiMeasureRests($measureN) }; + +declare + %test:args("xacea1fff-da53-42b4-bb5e-e814e1ca653a") %test:assertXPath("/xhtml:span[parent::xhtml:span][.='107']") + %test:args("x9cafb006-025b-4019-9430-936ab85a62db") %test:assertXPath("/xhtml:span[parent::xhtml:span][.='108']") + %test:args("xf48dfa96-2cf1-43e5-8fbf-ec8d1dca7501") %test:assertXPath("/xhtml:span[parent::xhtml:span][.='110']") + function measuretests:getMeasureLabel($measureID as xs:string) as element(xhtml:span) { + doc("testdata/multiMeasureRests.xml")/id($measureID) => + measure:getMeasureLabel() +}; From 89b86cd23c36759480eb4f5295db28dfc34edf57 Mon Sep 17 00:00:00 2001 From: Dennis Ried Date: Mon, 16 Dec 2024 18:06:00 +0100 Subject: [PATCH 44/51] remove import for unused module --- add/data/xql/getMeasures.xql | 2 -- 1 file changed, 2 deletions(-) diff --git a/add/data/xql/getMeasures.xql b/add/data/xql/getMeasures.xql index 77c5689fd..46e4cf13b 100644 --- a/add/data/xql/getMeasures.xql +++ b/add/data/xql/getMeasures.xql @@ -9,8 +9,6 @@ import module namespace functx = "http://www.functx.com"; import module namespace eutil = "http://www.edirom.de/xquery/eutil" at "/db/apps/Edirom-Online/data/xqm/eutil.xqm"; -import module namespace measure = "http://www.edirom.de/xquery/measure" at "/db/apps/Edirom-Online/data/xqm/measure.xqm"; - (: NAMESPACE DECLARATIONS ================================================== :) declare namespace mei = "http://www.music-encoding.org/ns/mei"; From 2ad0a2d2012d6b4697c5f0e9f3226e7f50d03d75 Mon Sep 17 00:00:00 2001 From: Dennis Ried Date: Mon, 16 Dec 2024 18:08:53 +0100 Subject: [PATCH 45/51] remove brackets and comment --- add/data/xql/getMeasuresOnPage.xql | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/add/data/xql/getMeasuresOnPage.xql b/add/data/xql/getMeasuresOnPage.xql index 90e3a69e1..c72816043 100644 --- a/add/data/xql/getMeasuresOnPage.xql +++ b/add/data/xql/getMeasuresOnPage.xql @@ -38,7 +38,5 @@ let $mei := doc($uri)/root() let $surface := $mei/id($surfaceId) -return ( - (: TODO: überlegen, wie die Staff-spezifischen Ausschnitte angezeigt werden sollen :) +return measure:getMeasuresOnPage($mei, $surface) -) From 4eefd32aad9227d5adcbf8d82614d9b75c4ad568 Mon Sep 17 00:00:00 2001 From: Dennis Ried Date: Mon, 16 Dec 2024 18:25:19 +0100 Subject: [PATCH 46/51] changed strings-maps to json-maps --- add/data/xqm/measure.xqm | 41 +++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/add/data/xqm/measure.xqm b/add/data/xqm/measure.xqm index c26009549..f0a901e31 100644 --- a/add/data/xqm/measure.xqm +++ b/add/data/xqm/measure.xqm @@ -28,9 +28,9 @@ declare namespace xhtml="http://www.w3.org/1999/xhtml"; : : @param $mei the mei file : @param $mdivID the ID of the mdiv - : @return Maps (as strings) + : @return Maps :) -declare function measure:getMeasures($mei as node(), $mdivID as xs:string) as xs:string* { +declare function measure:getMeasures($mei as node(), $mdivID as xs:string) as map(*)* { if($mei//mei:parts) then ( let $mdiv := $mei/id($mdivID) @@ -56,18 +56,18 @@ declare function measure:getMeasures($mei as node(), $mdivID as xs:string) as xs 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'), - '"}') + map{ + 'id:' : $measure/@xml:id, + 'voice' : $voiceRef, + 'partLabel' : eutil:getPartLabel($measure, 'measure') + } return - concat('{', - 'id: "measure_', $mdiv/@xml:id, '_', $measureN, '", ', - 'measures: [', string-join($measures, ','), '], ', - 'mdivs: ["', $mdiv/@xml:id, '"], ', - 'name: "', $measureN, '"', - '}') + map{ + 'id' : 'measure_' || $mdiv/@xml:id || '_' || $measureN, + 'measures' : array{ string-join($measures, ',') }, + 'mdivs' : array{ $mdiv/@xml:id }, + 'name' : $measureN + } ) else ( for $measure in $mei/id($mdivID)//mei:measure let $hasLabel := exists($measure[@label]) @@ -76,12 +76,15 @@ declare function measure:getMeasures($mei as node(), $mdivID as xs:string) as xs let $measure := $measures[1] let $measureLabel := measure:getMeasureLabelAttr($measure) return - concat('{', - 'id: "', $measure/@xml:id, '", ', - 'measures: [{id:"', $measure/@xml:id, '", voice: "score"}], ', - 'mdivs: ["', $measure/ancestor::mei:mdiv[1]/@xml:id, '"], ', - 'name: "', $measureLabel, '"', - '}') + map { + 'id' : $measure/@xml:id, + 'measures' : map { + 'id' : $measure/@xml:id, + 'voice' : 'score' + }, + 'mdivs' : array { $measure/ancestor::mei:mdiv[1]/@xml:id }, + 'name' : $measureLabel + } ) }; From 01568d2b0f697774217f9687d41389a57544a484 Mon Sep 17 00:00:00 2001 From: Dennis Ried Date: Tue, 17 Dec 2024 11:29:10 +0100 Subject: [PATCH 47/51] return array instead of maps* #302 --- add/data/xqm/measure.xqm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/add/data/xqm/measure.xqm b/add/data/xqm/measure.xqm index f0a901e31..2ed983f2b 100644 --- a/add/data/xqm/measure.xqm +++ b/add/data/xqm/measure.xqm @@ -28,9 +28,9 @@ declare namespace xhtml="http://www.w3.org/1999/xhtml"; : : @param $mei the mei file : @param $mdivID the ID of the mdiv - : @return Maps + : @return An Array of maps :) -declare function measure:getMeasures($mei as node(), $mdivID as xs:string) as map(*)* { +declare function measure:getMeasures($mei as node(), $mdivID as xs:string) as array(*) { if($mei//mei:parts) then ( let $mdiv := $mei/id($mdivID) From 45082e6bae7c24256e344aabaf556ab5739ea249 Mon Sep 17 00:00:00 2001 From: Peter Stadler Date: Tue, 17 Dec 2024 21:59:55 +0100 Subject: [PATCH 48/51] refactor `measure:analyzeLabel#1` and add tests --- add/data/xqm/measure.xqm | 34 +++++++++---------- testing/XQSuite/measure-tests.xqm | 11 ++++++ .../XQSuite/testdata/multiMeasureRests.xml | 7 ++-- 3 files changed, 31 insertions(+), 21 deletions(-) diff --git a/add/data/xqm/measure.xqm b/add/data/xqm/measure.xqm index 2ed983f2b..404781950 100644 --- a/add/data/xqm/measure.xqm +++ b/add/data/xqm/measure.xqm @@ -223,29 +223,27 @@ declare function measure:getMRest($measure as element(mei:measure)) as xs:string (:~ : Returns resolved labels + : E.g., for a measure with the label "3-5" this function will return "3,4,5"; + : for a measure with the n attribute "4a" this function will return "4a". : : @param $measure The measure to be processed - : @return A sequence of strings + : @return A sequence of measure numbers or labels :) declare function measure:analyzeLabel($measure as element(mei:measure)) as xs:string* { - - let $label := $measure/@label - - let $labelAnalyzed := if (contains($label, '–')) then( - let $first := substring-before($label, '–') - let $last := substring-after($label, '–') - let $steps := xs:integer(number($last) - number($first) + number(1)) - for $i in 1 to $steps - return - string(number($first) + $i - 1) - ) else ($label) - - return - if($label) then ( - $labelAnalyzed - ) else ( - $measure/@n + if($measure/@label) + then ( + if (matches($measure/@label, '^\d+[\-–]\d+$')) + then ( + let $first := functx:substring-before-match($measure/@label, '[\-–]') => number() + let $last := functx:substring-after-match($measure/@label, '[\-–]') => number() + let $steps := ($last - $first + 1) => xs:integer() + for $i in 1 to $steps + return + string($first + $i - 1) ) + else $measure/@label => data() + ) + else $measure/@n => data() }; (:~ diff --git a/testing/XQSuite/measure-tests.xqm b/testing/XQSuite/measure-tests.xqm index d0cd72f18..3d7a86e67 100644 --- a/testing/XQSuite/measure-tests.xqm +++ b/testing/XQSuite/measure-tests.xqm @@ -39,3 +39,14 @@ declare doc("testdata/multiMeasureRests.xml")/id($measureID) => measure:getMeasureLabel() }; + +declare + %test:args("xacea1fff-da53-42b4-bb5e-e814e1ca653a") %test:assertEquals("107") + %test:args("x9cafb006-025b-4019-9430-936ab85a62db") %test:assertEquals("108","109") + %test:args("xf48dfa96-2cf1-43e5-8fbf-ec8d1dca7501") %test:assertEquals("110a") + %test:args("x10f96702-291d-4d4e-962a-755a4eed2507") %test:assertEquals("104","105","106","107") + %test:args("foo") %test:assertEmpty + function measuretests:analyzeLabel($measureID as xs:string) as xs:string* { + doc("testdata/multiMeasureRests.xml")/id($measureID) => + measure:analyzeLabel() +}; diff --git a/testing/XQSuite/testdata/multiMeasureRests.xml b/testing/XQSuite/testdata/multiMeasureRests.xml index 03e03a18e..8491b13ec 100644 --- a/testing/XQSuite/testdata/multiMeasureRests.xml +++ b/testing/XQSuite/testdata/multiMeasureRests.xml @@ -61,7 +61,7 @@ - + @@ -98,7 +98,7 @@ - + @@ -135,7 +135,7 @@ >Trio - + @@ -168,5 +168,6 @@ startid="#x762b7489-482f-4b1e-8ba7-1ace39afe415" tstamp="1.000000" endid="#x09d63b7f-dd86-4abc-b7b5-e05763317358" tstamp2="5m+1.0000" layer="1"/> + From d72d013c256d364c3fcebe3eb87d7ee6a991c944 Mon Sep 17 00:00:00 2001 From: Peter Stadler Date: Tue, 17 Dec 2024 22:07:01 +0100 Subject: [PATCH 49/51] properly return a JSON array and replace the direct call to the `doc` function with the more robust `eutil:getDoc#1` --- add/data/xql/getMeasuresOnPage.xql | 10 +++++----- add/data/xqm/measure.xqm | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/add/data/xql/getMeasuresOnPage.xql b/add/data/xql/getMeasuresOnPage.xql index c72816043..5b14047a0 100644 --- a/add/data/xql/getMeasuresOnPage.xql +++ b/add/data/xql/getMeasuresOnPage.xql @@ -4,9 +4,7 @@ xquery version "3.1"; :) (:~ - Returns a JSON sequence with all measures on a specific page. - - @author Daniel Röwenstrunk + Returns a JSON array with all measures on a specific page. :) (: IMPORTS ================================================================= :) @@ -34,9 +32,11 @@ let $uri := request:get-parameter('uri', '') let $surfaceId := request:get-parameter('pageId', '') -let $mei := doc($uri)/root() +let $mei := eutil:getDoc($uri) let $surface := $mei/id($surfaceId) return - measure:getMeasuresOnPage($mei, $surface) + array { + measure:getMeasuresOnPage($mei, $surface) + } diff --git a/add/data/xqm/measure.xqm b/add/data/xqm/measure.xqm index 404781950..8d282b701 100644 --- a/add/data/xqm/measure.xqm +++ b/add/data/xqm/measure.xqm @@ -30,7 +30,7 @@ declare namespace xhtml="http://www.w3.org/1999/xhtml"; : @param $mdivID the ID of the mdiv : @return An Array of maps :) -declare function measure:getMeasures($mei as node(), $mdivID as xs:string) as array(*) { +declare function measure:getMeasures($mei as node(), $mdivID as xs:string) as map(*)* { if($mei//mei:parts) then ( let $mdiv := $mei/id($mdivID) From decd5629366af61befa82b91834191e3ce84e3bc Mon Sep 17 00:00:00 2001 From: Peter Stadler Date: Wed, 18 Dec 2024 09:42:32 +0100 Subject: [PATCH 50/51] comment out not-working and not needed code --- add/data/xqm/measure.xqm | 73 ++++------------------------------------ 1 file changed, 6 insertions(+), 67 deletions(-) diff --git a/add/data/xqm/measure.xqm b/add/data/xqm/measure.xqm index 8d282b701..56230e49b 100644 --- a/add/data/xqm/measure.xqm +++ b/add/data/xqm/measure.xqm @@ -23,71 +23,6 @@ declare namespace xhtml="http://www.w3.org/1999/xhtml"; (: FUNCTION DECLARATIONS =================================================== :) -(:~ - : Returns maps for each measure containing measure ID, measures (if multiRest), mdiv ID and a label - : - : @param $mei the mei file - : @param $mdivID the ID of the mdiv - : @return An Array of maps - :) -declare function measure:getMeasures($mei as node(), $mdivID as xs:string) as map(*)* { - - if($mei//mei:parts) then ( - let $mdiv := $mei/id($mdivID) - - let $measureNs := - for $measure in $mdiv//mei:measure - return measure:analyzeLabel($measure) - - let $measureNsDistinct := distinct-values(eutil:sort-as-numeric-alpha($measureNs)) - - return - for $measureN in $measureNsDistinct - let $measures := measure:resolveMultiMeasureRests($mdiv, $measureN) - - 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 - map{ - 'id:' : $measure/@xml:id, - 'voice' : $voiceRef, - 'partLabel' : eutil:getPartLabel($measure, 'measure') - } - return - map{ - 'id' : 'measure_' || $mdiv/@xml:id || '_' || $measureN, - 'measures' : array{ string-join($measures, ',') }, - 'mdivs' : array{ $mdiv/@xml:id }, - 'name' : $measureN - } - ) else ( - for $measure in $mei/id($mdivID)//mei:measure - let $hasLabel := exists($measure[@label]) - let $attr := if($hasLabel)then('label')else('n') - let $measures := $mei/id($mdivID)//mei:measure[@*[local-name() = $attr] = $measure/@*[local-name() = $attr]] - let $measure := $measures[1] - let $measureLabel := measure:getMeasureLabelAttr($measure) - return - map { - 'id' : $measure/@xml:id, - 'measures' : map { - 'id' : $measure/@xml:id, - 'voice' : 'score' - }, - 'mdivs' : array { $measure/ancestor::mei:mdiv[1]/@xml:id }, - 'name' : $measureLabel - } - ) -}; - (:~ : Returns a label for a measure, taken either from the `@label` attribute : if present or the `@n` attribute otherwise. @@ -253,6 +188,8 @@ declare function measure:analyzeLabel($measure as element(mei:measure)) as xs:st : @param $measureN The number of the measure to be resolved : @return The measures covered by the multi-measure rest :) +(: This does not work, see discussion at https://github.com/Edirom/Edirom-Online/pull/302 :) +(: declare function measure:resolveMultiMeasureRests($mdiv as node(), $measureN as xs:string) as node()* { let $measureNNumber := number($measureN) return @@ -262,6 +199,7 @@ declare function measure:resolveMultiMeasureRests($mdiv as node(), $measureN as $mdiv//mei:measure[.//mei:multiRest][number(@n) lt $measureNNumber][.//mei:multiRest/number(@num) gt ($measureNNumber - number(@n))] ) }; +:) (:~ : Finds all measures on a page. @@ -270,9 +208,10 @@ declare function measure:resolveMultiMeasureRests($mdiv as node(), $measureN as : @param $surface The surface to look at : @returns A sequence of map objects with measure information :) -declare function measure:getMeasuresOnPage($mei as node(), $surface as node()) as map(*)* { +declare function measure:getMeasuresOnPage($mei as document-node()?, $surface as element(mei:surface)) as map(*)* { - for $zone in $surface/mei:zone[@type='measure'] + for $zone in $surface/mei:zone[@type='measure'][@xml:id] + (: do we need to compute an id for zones without @xml:id? :) let $zoneRef := concat('#', $zone/@xml:id) (: : The first predicate with `contains` is just a rough estimate to narrow down the result set. From c9ed32faccde8bc611e8639f63fbba3098cd496a Mon Sep 17 00:00:00 2001 From: Peter Stadler Date: Wed, 18 Dec 2024 09:43:44 +0100 Subject: [PATCH 51/51] comment out test for disabled function --- testing/XQSuite/measure-tests.xqm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/testing/XQSuite/measure-tests.xqm b/testing/XQSuite/measure-tests.xqm index 3d7a86e67..f886b1048 100644 --- a/testing/XQSuite/measure-tests.xqm +++ b/testing/XQSuite/measure-tests.xqm @@ -22,6 +22,8 @@ declare measure:getMeasureLabelAttr($node) }; +(: The function `measure:resolveMultiMeasureRests#2` is currently commented out :) +(: declare %test:args("4") %test:assertEmpty %test:args("foo") %test:assertEmpty @@ -30,6 +32,7 @@ declare doc("testdata/multiMeasureRests.xml")/mei:mdiv => measure:resolveMultiMeasureRests($measureN) }; +:) declare %test:args("xacea1fff-da53-42b4-bb5e-e814e1ca653a") %test:assertXPath("/xhtml:span[parent::xhtml:span][.='107']")