From 7a18aa93616dbde253c2b34c8eb83cd30fb53ee6 Mon Sep 17 00:00:00 2001 From: Alex Schroeder Date: Sat, 21 Mar 2009 01:36:26 +0000 Subject: [PATCH] (NewTagSave, NewTagDeletePage): Eliminate and merge with NewTagSave and NewTagDeletePage respectively. (TagFind, NewTagGrepFiltered, NewTagSearchString): New functions to use the tag file while searching. --- modules/tags.pl | 75 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 65 insertions(+), 10 deletions(-) diff --git a/modules/tags.pl b/modules/tags.pl index 551020a9..c5717e1b 100644 --- a/modules/tags.pl +++ b/modules/tags.pl @@ -29,7 +29,7 @@ automatically. =cut -$ModulesDescription .= '

$Id: tags.pl,v 1.9 2009/03/20 13:59:32 as Exp $

'; +$ModulesDescription .= '

$Id: tags.pl,v 1.10 2009/03/21 01:36:26 as Exp $

'; =head1 CONFIGURATION @@ -112,10 +112,6 @@ will be regenerated. sub NewTagSave { # called within a lock! OldTagSave(@_); - TagIndex(@_); -} - -sub TagIndex { my $id = shift; # Within a tag, space is replaced by _ as in foo_bar. my %tag = map { FreeToNormal($_) => 1 } @@ -178,10 +174,6 @@ removed from the tags db. sub NewTagDeletePage { # called within a lock! OldTagDeletePage(@_); - TagDeletePage(@_); -} - -sub TagDeletePage { my $id = shift; # open the DB file @@ -206,13 +198,76 @@ sub TagDeletePage { untie %h; } +=pod +When searching, the tags db is read and used. This works by scanning +the search string for tag:foo and -tag:bar elements, searching for +those, and then calling the grep filter code with the new list of +pages and a new search term without the tag terms. + +=cut + +sub TagFind { + my @tags = @_; + # open the DB file + require DB_File; + tie %h, "DB_File", $TagFile; + my %page; + foreach my $tag (@tags) { + foreach my $id (split(/$FS/, $h{$tag})) { + $page{$id} = 1; + } + } + untie %h; + return sort keys %page; +} + +*OldTagGrepFiltered = *GrepFiltered; +*GrepFiltered = *NewTagGrepFiltered; + +sub NewTagGrepFiltered { # called within a lock! + my ($string, @pages) = @_; + my %page = map { $_ => 1 } @pages; + # this is based on the code in SearchRegexp() + my @tagterms = grep(/^-?tag:/, shift =~ /\"([^\"]+)\"|(\S+)/g); + my @positives = map {substr($_, 4)} grep(/^tag:/, @tagterms); + my @negatives = map {substr($_, 5)} grep(/^-tag:/, @tagterms); + if (@positives) { + my %found; + foreach my $id (TagFind(@positives)) { + $found{$id} = 1 if $page = {$id}; + } + %page = %found; + } + # remove the negatives + foreach my $id (TagFind(@negatives)) { + delete $page{$id}; + } + # filter out the tags from the search string + $string = join(' ', grep(!/^-?tag:/, $string =~ /\"([^\"]+)\"|(\S+)/g)); + # run grep + return OldTagGrepFiltered($string, sort keys %page); +} =pod -When searching, the tags db is read and used. +There remains a problem: The real search code will still be in +operation, and terms of the form -tag:foo will never match. That's why +the code that does the ordinary search has to be changed as well. +We're need to remove all tag terms (again) in order to not confuse it. + =cut +*OldTagSearchString = *SearchString; +*SearchString = *NewTagSearchString; + +sub NewTagSearchString { + # filter out the tags from the search string + my $string = join(' ', grep(!/^-?tag:/, shift =~ /\"([^\"]+)\"|(\S+)/g)); + return 1 unless $string; + return OldTagSearchString($string, @_); +} + =head1 COPYRIGHT AND LICENSE Copyright (C) 2005, 2009 Alex Schroeder