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, " $", "&#160;"),
    $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

Reply via email to