xquery version "3.0"; module namespace app="http://divvun.no/iskkan/templates"; import module namespace templates="http://exist-db.org/xquery/templates" ; import module namespace config="http://divvun.no/iskkan/config" at "config.xqm"; import module namespace display="http://divvun.no/iskkan/display" at "display.xql"; (:~ : This is a sample templating function. It will be called by the templating module if : it encounters an HTML element with an attribute data-template="app:test" : or class="app:test" (deprecated). The function has to take at least 2 default : parameters. Additional parameters will be mapped to matching request or session parameters. : : @param $node the HTML node with the attribute which triggered this call : @param $model a map containing arbitrary data - used to pass information between template calls :) declare function app:test($node as node(), $model as map(*)) {

Dummy template output generated by function app:test at {current-dateTime()}. The templating function was triggered by the class attribute class="app:test".

}; declare %templates:wrap (: %templates:default("result-lang", "") :) function app:results($node as node(), $model as map(*)) as map(*) { map { "results" := collection($config:data-root)//spelltestresult/header } }; declare %templates:wrap (: %templates:default("result-lang", "") :) function app:result($node as node(), $model as map(*), $timestamp as xs:string*) as map(*) { let $col := '/db/apps/iskkan/data' for $result in collection($col)//spelltestresult[./header/timestamp = $timestamp] let $hits := $result/results, $words := count($hits/word), $origcorr := $hits/word[./original/@status = "correct"], $origerr := $hits/word[./original/@status = "error"], $spcorr := $hits/word[./speller/@status = "correct"], $sperr := $hits/word[./speller/@status = "error"], $tp := $hits/word[./original/@status = "error"][./speller/@status = "error"], $tn := $hits/word[./original/@status = "correct"][./speller/@status = "correct"], $fn := $hits/word[./original/@status = "error"][./speller/@status = "correct"], $fp := $hits/word[./speller/@status = "error"][./original/@status = "correct"] return map { "result" := $result, "count" := $words, 'tp' := $tp, 'original' := map { 'correct' := count($origcorr), 'error' := count($origerr) }, 'speller' := map { 'correct' := count($spcorr), 'error' := count($sperr) }, 'positives' := map { 'true' := count($tp), 'false' := count($fp) }, 'negatives' := map { 'true' := count($tn), 'false' := count($fn) }, 'precision' := round-half-to-even(count($tp) div sum(count($tp) + count($fp)) * 100, 2), 'recall' := round-half-to-even(count($tp) div sum(count($tp) + count($fn)) * 100, 2), 'accuracy' := round-half-to-even((sum(count($tp) + count($tn)) div $words) * 100, 2) } }; declare (:%templates:wrap:) function app:print-summary($node as node(), $model as map(*)) { display:summary($model) }; declare (:%templates:wrap:) function app:print-quality($node as node(), $model as map(*)) { display:quality(app:suggestionsummary($model('tp'))) }; declare (:%templates:wrap:) function app:print-type($node as node(), $model as map(*)) {

{$model('error-type')}

}; declare (:%templates:wrap:) function app:print-timestamp($node as node(), $model as map(*)) { {$model("result")/timestamp/text()} }; declare function app:error-types($node as node(), $model as map(*)) { let $types := distinct-values(collection('/db/apps/iskkan/data')//errors/error/@type) let $control := return templates:form-control($control, $model) }; declare function app:result-filter($node as node(), $model as map(*)) { let $langs := distinct-values(collection($config:data-root)//header/lang) let $control := return templates:form-control($control, $model) }; declare %templates:wrap %templates:default("timestamp", "20141106-1227") function app:summary-old($node as node(), $model as map(*), $timestamp as xs:string*) { let $col := '/db/apps/iskkan/data' for $header in collection($col)//spelltestresult/header[matches(./timestamp, $timestamp)] let $words := $header/truefalsesummary/@wordcount, $origcorr := $header/truefalsesummary/original/@correct, $origerr := $header/truefalsesummary/original/@error, $spcorr := $header/truefalsesummary/speller/@correct, $sperr := $header/truefalsesummary/speller/@error, $tp := $header/truefalsesummary/positive/@true, $fp := $header/truefalsesummary/positive/@false, $tn := $header/truefalsesummary/negative/@true, $fn := $header/truefalsesummary/negative/@false, $invocation := map { 'words' := string($words), 'original' := map { 'correct' := string($origcorr), 'error' := string($origerr) }, 'speller' := map { 'correct' := string($spcorr), 'error' := string($sperr) }, 'positives' := map { 'true' := string($tp), 'false' := string($fp) }, 'negatives' := map { 'true' := string($tn), 'false' := string($fn) }, 'precision' := round-half-to-even($tp div sum(($tp + $fp)) * 100, 2), 'recall' := round-half-to-even($tp div sum(($tp + $fn)) * 100, 2), 'accuracy' := round-half-to-even((sum(($tp + $tn)) div $words) * 100, 2) } return (

Summary

{display:summary($invocation), display:edit-dist-table($tp, $header/suggestionsummary)}
) }; declare function app:suggestionsummary($el as element()*) { let $word-count := count($el) return { for $p in 1 to 6 return for $dist in 1 to 3 let $hits := if ($dist ne 3 and $p ne 6) then $el[./edit_dist=$dist][./position=$p] else if ($dist eq 3 and $p eq 6) then $el[./edit_dist>=$dist][./position>=$p] else if ($dist eq 3) then $el[./edit_dist>=$dist][./position=$p] else $el[./edit_dist=$dist][./position>=$p] return {round-half-to-even((count($hits) div $word-count) * 100, 2)} } }; declare %templates:wrap function app:summary($node as node(), $model as map(*), $timestamp as xs:string*) { let $lang := 'sme', $engine := 'pl', $col := '/db/apps/iskkan/data' for $result in collection($col)//spelltestresult[./header/timestamp = $timestamp] let $hits := $result/results, $words := count($hits/word), $origcorr := $hits/word[./original/@status = "correct"], $origerr := $hits/word[./original/@status = "error"], $spcorr := $hits/word[./speller/@status = "correct"], $sperr := $hits/word[./speller/@status = "error"], (: $tp := count(functx:value-intersect($origerr, $sperr)), $tn := count(functx:value-intersect($origcorr , $spcorr)), $fp := count(functx:value-intersect($origerr , $spcorr)), $fn := count(functx:value-intersect($origcorr , $sperr)), :) $tp := $hits/word[./original/@status = "error"][./speller/@status = "error"], $tn := $hits/word[./original/@status = "correct"][./speller/@status = "correct"], $fn := $hits/word[./original/@status = "error"][./speller/@status = "correct"], $fp := $hits/word[./speller/@status = "error"][./original/@status = "correct"], $invocation := map { 'words' := $words, 'original' := map { 'correct' := count($origcorr), 'error' := count($origerr) }, 'speller' := map { 'correct' := count($spcorr), 'error' := count($sperr) }, 'positives' := map { 'true' := count($tp), 'false' := count($fp) }, 'negatives' := map { 'true' := count($tn), 'false' := count($fn) }, 'precision' := round-half-to-even(count($tp) div sum(count($tp) + count($fp)) * 100, 2), 'recall' := round-half-to-even(count($tp) div sum(count($tp) + count($fn)) * 100, 2), 'accuracy' := round-half-to-even((sum(count($tp) + count($tn)) div $words) * 100, 2) } return ( display:summary($invocation), display:quality(app:suggestionsummary($tp)) ) };