[Home]WikiPatches/SearchWithOperators

UseModWiki | WikiPatches | RecentChanges | Preferences

This is used in OddMuse, a UseMod 0.92 descendant, based on WikiPatches/BetterSearchOutput. The #FILE stuff can safely be removed; it relates to OddMuse's file upload feature where the uploaded files are stored in pages. This is why they have to be excluded, normally. See the Oddmuse manual for more. [1]

    sub SearchTitleAndBody {
      my $string = shift;
      my $and = T('and');
      my $or = T('or');
      my @strings = split(/ +$and +/, $string);
      my @found;
      foreach my $name (AllPagesList()) {
	OpenPage($name);
	OpenDefaultText();
	next if ($Text{'text'} =~ /^#FILE / and $string !~ /^\^#FILE/); # skip files unless requested
	my $found = 1; # assume found
	foreach my $str (@strings) {
	  my @temp = split(/ +$or +/, $str);
	  $str = join('|', @temp);
	  if (not ($Text{'text'} =~ /$str/i)) {
	    $found = 0;
	    last;
	  }
	}
	if ($found or $name =~ /$string/i) {
	  push(@found, $name);
	} elsif ($FreeLinks && ($name =~ m/_/)) {
	  my $freeName = $name;
	  $freeName =~ s/_/ /g;
	  if ($freeName =~ /$string/i) {
	    push(@found, $name);
	  }
	}
      }
      return @found;
    }

    sub PrintSearchResults {
      my ($searchstring, @results) = @_ ;
      my $and = T('and');
      my $or = T('or');
      my $searchstring = join('|', split(/ +(?:$and|$or) +/, $searchstring));
      my ($snippetlen, $maxsnippets) = (100, 4) ; #  these seem nice.
      print $q->h2(Ts('%s pages found:', ($#results + 1)));
      my $files = ($searchstring =~ /^\^#FILE/); # usually skip files
      foreach my $name (@results) {
	OpenPage($name);
	OpenDefaultText();
	my $pageText = QuoteHtml($Text{'text'});
	#  get the page, filter it, remove all tags
	$pageText =~ s/$FS//g;	# Remove separators (paranoia)
	$pageText =~ s/[\s]+/ /g;	#  Shrink whitespace
	$pageText =~ s/([-_=\\*\\.]){10,}/$1$1$1$1$1/g ; # e.g. shrink "----------"
	my $htmlre = join('|',(@HtmlTags, 'pre', 'nowiki', 'code'));
	$pageText =~ s/\<\/?($htmlre)(\s[^<>]+?)?\>//gi;
	#  entry header
	print '<p>' . $q->span({-class=>'result'}, GetPageLink($name)), $q->br();
	if ($files) {
	  $pageText =~ /^#FILE ([^ ]+)/;
	  print $1;
	} else {
	  # show a snippet from the top of the document
	  my $j = index($pageText, ' ', $snippetlen); # end on word boundary
	  my $t = substr($pageText, 0, $j);
	  $t =~ s/($searchstring)/<strong>\1<\/strong>/gi;
	  print $t, ' ', $q->b('...');
	  $pageText = substr($pageText, $j); # to avoid rematching
	  # search for occurrences of searchstring
	  my $jsnippet = 0 ;
	  while ($jsnippet < $maxsnippets && $pageText =~ m/($searchstring)/i) {
	    $jsnippet++;
	    if (($j = index($pageText, $1)) > -1 ) {
	      # get substr containing (start of) match, ending on word boundaries
	      my $start = index($pageText, ' ', $j-($snippetlen/2));
	      $start = 0 if ($start == -1);
	      my $end = index($pageText, ' ', $j+($snippetlen/2));
	      $end = length($pageText ) if ($end == -1);
	      $t = substr($pageText, $start, $end-$start);
	      # highlight occurrences and tack on to output stream.
	      $t =~ s/($searchstring)/<strong>\1<\/strong>/gi;
	      print $t, ' ', $q->b('...');
	      # truncate text to avoid rematching the same string.
	      $pageText = substr($pageText, $end);
	    }
	  }
	}
	#  entry trailer
	print $q->br(), $q->span({-class=>'info'},
	  int((length($pageText)/1024)+1) . 'K - ' . T('last updated') . ' '
	  . TimeToText($Section{ts}) . ' ' . T('by') . ' '
	  . GetAuthorLink($Section{'host'}, $Section{'username'})), '</p>';
      }
    }

UseModWiki | WikiPatches | RecentChanges | Preferences
Edit text of this page | View other revisions | Search MetaWiki
Last edited October 17, 2007 5:44 pm by MarkusLude (diff)
Search: