On Sat, 2020-04-25 at 13:46 -0400, Graydon Saunders wrote: > > I think I have figured out a way to connect the adjacent marked words > in > the phrasal term into a single mark element. I cannot convince myself > that > this is the right way; is there a better approach than tumbling > windows?
I just search for the multi-word phrase and surround that. Enclosed is a sample from a prototype for a keyword in context search index for fromoldbooks.org (not yet live). Lookognow i see it's not very neat but maybe it'll give some ideas. let $results := ( let $matches := $doc//p[not(ancestor::longdesc) and (.//text() contains text { $term })] for $match at $pos in $matches let $sock := <singleton>{ft:mark( $match[text() contains text { $term }] , 'sock')}</singleton>, (: "sock" is now a singleton element likely containing a p or title element, : with every phrase matching the query surrounded with a sock element. :) $longbefore := concat( " ", local:ws( string-join(($sock//sock)[1]/preceding-sibling::node(), '' ))), $before := replace($longbefore, " $", " "), $after:= local:ws( string-join( ($sock//sock)[last()]/following-sibling::node(), '')), $uri := document-uri( $match/ancestor::document-node() ), $image := $match/ancestor::image where not( empty(($sock//sock))) return <details id="d{$pos}" data-group="{ ($image/@source) }"> <summary class="{if ($image) then 'image' else 'text'}{ if ($image and ($image eq $matches[$pos - 1]/ancestor::image)) then ' same ' else ''}" > <before> { substring($before, string-length($before) - 100, string-length($before)) } </before> <match><b>{ string-join($sock//sock, ' ') }</b><after>{ local:trunc($after, 60) }</after> </match> </summary> ) return <results> { for $r in $results group by $g := $r/@data-group return <div class="group"> <p class="metadata">{ if ($g ne "") then let $source := $doc//source[@id = $g] return ( <a href="/{$g}/">{ $source/title/node() }</a>, if ($source/author and ($source/author ne "Anonymous")) then ", by " || $source/author else "", if ($source/date) then " (" || $source/date || ")" else "" ) else $r[1]//a[contains-token(@class, 'info')] }</p> {$r} </div> } </results> -- Liam Quin, https://www.delightfulcomputing.com/ Available for XML/Document/Information Architecture/XSLT/ XSL/XQuery/Web/Text Processing/A11Y training, work & consulting. Barefoot Web-slave, antique illustrations: http://www.fromoldbooks.org