diff --git a/xq/abv-mod.xqm b/xq/abv-mod.xqm index 41516b8..841ec71 100644 --- a/xq/abv-mod.xqm +++ b/xq/abv-mod.xqm @@ -217,7 +217,7 @@ declare function abv-m:insert-full-lang($abbr as node(), $lang as xs:string) { } }; -declare function abv-m:make-html($src as document-node()+, +declare function abv-m:make-html($src as node()+, $lang as xs:string) as node()+ { for $doc in $src @@ -270,12 +270,11 @@ declare function abv-m:entry-form-by-id($id as xs:string) { }; declare function abv-m:mark-element($doc as document-node(), - $path as xs:string, - $query as xs:string) { + $path as xs:string) { let $doc-tr := $doc transform with { for $n in xquery:eval($path, {'': .}) return replace node $n - with ft:mark($n[. contains text {$query}]) + with {$n} } return $doc-tr }; @@ -286,19 +285,53 @@ declare function abv-m:search($db-lang as xs:string, $query as xs:string) { let $db-name := `abaevdict_{$db-lang}` let $docs := collection(`{$db-name}/xml`) - let $hits := switch($type) - case "full" return $docs//text()[. contains text {$query}] - case "form" return $docs/tei:entry[1]/tei:form[./tei:orth contains text {$query}] - case "sense" return $docs/tei:entry[1]//tei:sense[./tei:cit[@type='translationEquivalent'] contains text {$query}] - case "example" return $docs/tei:entry[1]//tei:cit[@type='example']/tei:quote[. contains text {$query}] - case "translation" return $docs/tei:entry[1]//tei:cit[@type='translation' and . contains text {$query}] - case "mentioned" return $docs/tei:entry[1]//tei:mentioned/(tei:m|tei:w|tei:phr|tei:s)[. contains text {$query}] - case "gloss" return $docs/tei:entry[1]//tei:gloss[. contains text {$query}] - case "etym" return $docs/tei:entry[1]/tei:etym[1][. contains text {$query}] - default return $docs//text()[. contains text {$query}] + let $test := switch($type) + case "full" return + fn ($node) { + $node//text() contains text {$query} + } + case "form" return + fn ($node) { + $node//tei:form/tei:orth//text() contains text {$query} + } + case "sense" return + fn ($node) { + $node//tei:cit[@type='translationEquivalent']//text() contains text {$query} + } + case "example" return + fn ($node) { + $node//tei:cit[@type='example']/tei:quote//text() contains text {$query} + } + case "translation" return + fn ($node) { + $node//tei:cit[@type='translation']//text() contains text {$query} + } + case "mentioned" return + fn ($node) { + $node//tei:mentioned/(tei:m|tei:w|tei:phr|tei:s)/text() contains text {$query} + } + case "gloss" return + fn ($node) { + $node//tei:gloss//text() contains text {$query} + } + case "etym" return + fn ($node) { + $node/tei:etym[1]//text() contains text {$query} + } + default return + fn ($node) { + $node//text() contains text {$query} + } + let $hits := $docs//tei:entry[1][$test(.)] return array:build(for $hit in $hits - let $entry-id := db:get($db-name,db:path($hit))/tei:entry[1]/string(@xml:id) - group by $entry-id - order by abv-m:sortKey(abv-m:entry-form-by-id($entry-id)) - return {'entry': $entry-id, 'nodes': array:build(for $node in $hit return path($node))}) + let $entry-id := $hit/@xml:id + (: group by $entry-id :) + let $mark := ft:mark($hit[$test(.)]) + order by abv-m:sortKey($hit/@xml:id) + return {'entry': $entry-id, + (: 'nodes': array:build(for $node in $hit return path($node)), :) + 'tei': ft:mark($hit[$test(.)]), + 'fragment': {util:strip-namespaces(($mark//*[tei:mark])[1])/child::node()} + } + ) }; \ No newline at end of file diff --git a/xq/restx_dict_cached.xq b/xq/restx_dict_cached.xq index dad7ef0..6c5de2d 100644 --- a/xq/restx_dict_cached.xq +++ b/xq/restx_dict_cached.xq @@ -199,7 +199,7 @@ declare %rest:path("{$lang}/search/new") if(array:size($sd) > 0) then page:by-id($lang, $sd(1)('entry'), - string-join($sd(1)('nodes'),'|')) + '') else web:redirect('../search/clear') }; @@ -211,7 +211,7 @@ declare %rest:path("{$lang}/search/next") let $n as xs:integer := session:get('searchN')+1 let $r1 := session:set('searchN', $n) let $sd := session:get('searchData') - return page:by-id($lang, $sd($n)('entry'), string-join($sd($n)('nodes'),'|')) + return page:by-id($lang, $sd($n)('entry'), ()) }; declare %rest:path("{$lang}/search/prev") @@ -221,7 +221,7 @@ declare %rest:path("{$lang}/search/prev") let $n as xs:integer := session:get('searchN')-1 let $r1 := session:set('searchN', $n) let $sd := session:get('searchData') - return page:by-id($lang, $sd($n)('entry'), string-join($sd($n)('nodes'),'|')) + return page:by-id($lang, $sd($n)('entry'), ()) }; declare %rest:path("{$lang}/search/position") @@ -231,7 +231,7 @@ declare %rest:path("{$lang}/search/position") function page:search-position($lang, $p as xs:integer) { let $r1 := session:set('searchN', $p) let $sd := session:get('searchData') - return page:by-id($lang, $sd($p)('entry'), string-join($sd($p)('nodes'),'|')) + return page:by-id($lang, $sd($p)('entry'), ()) }; declare %rest:path("{$lang}/search/clear") @@ -519,8 +519,13 @@ declare %rest:path("{$lang}/dict") let $html := if ($xpath != '' and $entry = $doc/@xml:id) then abv-m:mark-element( doc(`abaevdict_{$lang}/xml/{$doc/@xml:id}.xml`), - $xpath, session:get('searchQuery')) => abv-m:make-html($lang) - else doc(`abaevdict_{$lang}/html/{$doc/@xml:id}.html`) + $xpath) => abv-m:make-html($lang) + else + let $sd := session:get('searchData') + let $sn := session:get('searchN') + return if (exists($sd) and $sd($sn)('entry') = $doc/@xml:id) + then abv-m:make-html($sd($sn)('tei'), $lang) + else doc(`abaevdict_{$lang}/html/{$doc/@xml:id}.html`) return ( (: Block with icons to the left of entry (floating) :)