home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2004 December / PCpro_2004_12.ISO / files / webserver / tsw / TSW_3.4.0.exe / Apache2 / perl / Search_db.pm < prev    next >
Encoding:
Perl POD Document  |  2003-09-16  |  5.3 KB  |  207 lines

  1. #AnyDBM handling from perlindex:
  2. # NDBM_File as LAST resort
  3.  
  4. package
  5.     AnyDBM_File; # hide from indexer
  6. use vars '@ISA';
  7. @ISA = qw(DB_File GDBM_File SDBM_File ODBM_File NDBM_File) unless @ISA;
  8. my $mod;
  9. for $mod (@ISA) {
  10.     last if eval "require $mod"
  11. };
  12.  
  13. package Tk::Pod::Search_db;
  14.  
  15. use strict;
  16. use vars qw($VERSION);
  17.  
  18. $VERSION = substr(q$Revision: 1.2 $, 10) . "";
  19.  
  20. use Carp;
  21. use Fcntl;
  22. use Text::English;
  23. use Config;
  24.  
  25. (my $PREFIX = $Config::Config{prefix}) =~ y|\\|/|d;
  26. (my $IDXDIR = $Config::Config{man1dir}) =~ s|/[^/]+$||;
  27. $IDXDIR ||= $PREFIX; # use perl directory if no manual directory exists
  28.  
  29. sub new {
  30.     my $class = shift;
  31.     my $idir  = shift;
  32.  
  33.     $idir ||= $IDXDIR;
  34.  
  35.     my (%self, %IF, %IDF, %FN);
  36.     tie (%IF,   'AnyDBM_File', "$idir/index_if",   O_RDONLY, 0644)
  37.             or confess "Could not tie $idir/index_if: $!\n".
  38.                 "Did you run 'perlindex -index'?\n";
  39.     tie (%IDF,  'AnyDBM_File', "$idir/index_idf",   O_RDONLY, 0644)
  40.             or confess "Could not tie $idir/index_idf: $!\n";
  41.     tie (%FN,   'AnyDBM_File', "$idir/index_fn",   O_RDONLY, 0644)
  42.             or confess "Could not tie $idir/index_fn: $!\n";
  43.  
  44.     $self{IF}  = \%IF;
  45.     $self{IDF} = \%IDF;
  46.     $self{FN}  = \%FN;
  47.     #xxx: -idir depended but where can I get this info?
  48.     #    o A fourth index file?
  49.     #   o todo: check perlindex index routine
  50.     $self{PREFIX} = $PREFIX;
  51.  
  52.     bless \%self, $class;
  53. }
  54.  
  55. # changes to perlindex's normalize
  56. #    o removed useless(?) stemmer check
  57. #    o lexicalized $word
  58.  
  59. sub normalize {
  60.     my $line = join ' ', @_;
  61.     my @result;
  62.  
  63.     $line =~ tr/A-Z/a-z/;
  64.     $line =~ tr/a-z0-9/ /cs;
  65.  
  66.     my $word;
  67.     for $word (split ' ', $line ) {
  68.         $word =~ s/^\d+//;
  69.         next unless length($word) > 2;
  70.         push @result, &Text::English::stem($word);
  71.     }
  72.     @result;
  73. }
  74.  
  75. # changes for perlindex's search slightly modified
  76. sub searchWords {
  77.     my $self = shift;
  78.  
  79.     #print "try words|", join('|',@_),"\n";
  80.     my %score;
  81.     my $maxhits = 15;
  82.     my (@unknown, @stop);
  83.  
  84.     my $IF  = $self->{IF};
  85.     my $IDF = $self->{IDF};
  86.     my $FN  = $self->{FN};
  87.  
  88.     #xxx &initstop if $opt_verbose;
  89.     my ($word, $did, %post); #xxx
  90.     for $word (normalize(@_)) {
  91.         unless ($IF->{$word}) {
  92.             #xxxif ($stop{$word}) {
  93.             #xxx    push @stop, $word;
  94.             #xxx} else {
  95.             #xxx    push @unknown, $word;
  96.             #xxx}
  97.             next;
  98.         }
  99.         #my %post = unpack($p.'*',$IF->{$word});
  100.         %post = unpack('w*',$IF->{$word});
  101.         my $idf = log($FN->{'last'}/$IDF->{$word});
  102.         for $did (keys %post) {
  103.             #xxx my ($maxtf) = unpack($p, $FN->{$did});
  104.             my ($maxtf) = unpack('w', $FN->{$did});
  105.             $score{$did} = 0 unless defined $score{$did}; # perl -w
  106.             $score{$did} += $post{$did} / $maxtf * $idf;
  107.         }
  108.     }
  109.  
  110.     my @results;
  111.     for $did (sort {$score{$b} <=> $score{$a}} keys %score) {
  112.             my ($mtf, $path) = unpack('wa*', $FN->{$did});
  113.             push @results, $score{$did}, $path;
  114.             last unless --$maxhits;
  115.     }
  116.  
  117.     #print "results|", join('|',@results),"\n";
  118.     @results;
  119. }
  120.  
  121. sub prefix {
  122.     shift->{PREFIX};
  123. }
  124.  
  125. 1;
  126. __END__
  127.  
  128. =head1 NAME
  129.  
  130. Tk::Pod::Search_db - dirty OO wrapper for C<perlindex>'s search functionality
  131.  
  132. =head1 SYNOPSIS
  133.  
  134.     ** THIS IS ALPHA SOFTWARE everything may and should change **
  135.     **   stuff here is more a scratch pad than docomentation!  **
  136.  
  137.     use Tk::Pod::Search_db;
  138.     ...
  139.     $idx = Tk::Pod::Search_db->new?(INDEXDIR)?;
  140.     ...
  141.     @hits = $idx->searchWords(WORD1,...); # @hits is a list of
  142.                                              # relpath1,score1,...  where
  143.                                              # score is increasing
  144.     $prefix = $idx->prefix();
  145.  
  146.     @word = Tk::Pod::Search_db::normalize(STRING1,...);
  147.  
  148. =head1 DESCRIPTION
  149.  
  150. Module to search Pod documentation.  Before you can use
  151. the module one should create the indices with C<perlindex -index>.
  152.  
  153. =head1 MISSING
  154.  
  155. Enable options like -maxhits (currently = 15).  Solve PREFIX
  156. dependency.  Interface for @stop and @unknown also as methods
  157. return lists for last searchWords call?
  158.  
  159. Lots more ...
  160.  
  161. =head1 METHODS
  162.  
  163. =over 4
  164.  
  165. =item $idx = Tk::Pod::Search_db->new(INDEXDIR)
  166.  
  167. Interface may change to support options like -maxhits
  168.  
  169. =item $idx->seachWords(WORD1?,...?)
  170.  
  171. search for WORD(s). Return a list of
  172.  
  173.   relpath1, score1, relpath2, score2, ...
  174.  
  175. or empty list if no match is found.
  176.  
  177. =item $pathprefix = $idx->pathprefix()
  178.  
  179. The return path prefix and C<$relpath> give together the full path
  180. name of the Pod documentation.
  181.  
  182.     $fullpath = $patchprefix . '/' . $relpath
  183.  
  184. B<Note:> Should make it easy to use Tk::Pod::Search with perlindex but
  185. index specific prefix handling is a mess up to know.
  186.  
  187. =back
  188.  
  189. =head1 SEE ALSO
  190.  
  191. tkpod, perlindex perlpod, Tk::Pod::Search
  192.  
  193. =head1 AUTHORS
  194.  
  195. Achim Bohnet  <F<ach@mpe.mpg.de>>
  196.  
  197. Most of the code here is borrowed from L<perlindex> written by
  198. Ulrich Pfeifer <F<Ulrich.Pfeifer@de.uu.net>>.
  199.  
  200. Current maintainer is Slaven Rezic <F<slaven@rezic.de>>.
  201.  
  202. Copyright (c) 1997-1998 Achim Bohnet. All rights reserved.  This program is
  203. free software; you can redistribute it and/or modify it under the same
  204. terms as Perl itself.
  205.  
  206. =cut
  207.