[Python-checkins] r66574 - in doctools/trunk/sphinx: search.py static/searchtools.js

georg.brandl python-checkins at python.org
Wed Sep 24 10:46:33 CEST 2008


Author: georg.brandl
Date: Wed Sep 24 10:46:33 2008
New Revision: 66574

Log:
* Search for partial keyword matches and be case insensitive.
* Show keyword results before regular ones.
* Show full name, type of keyword and title of containing doc.


Modified:
   doctools/trunk/sphinx/search.py
   doctools/trunk/sphinx/static/searchtools.js

Modified: doctools/trunk/sphinx/search.py
==============================================================================
--- doctools/trunk/sphinx/search.py	(original)
+++ doctools/trunk/sphinx/search.py	Wed Sep 24 10:46:33 2008
@@ -33,7 +33,8 @@
     SUFFIX = ')'
 
     def dumps(self, data):
-        return self.PREFIX + json.dumps(data) + self.SUFFIX
+        return self.PREFIX + json.dumps(data, separators=(',', ':')) \
+               + self.SUFFIX
 
     def loads(self, s):
         data = s[len(self.PREFIX):-len(self.SUFFIX)]
@@ -94,6 +95,8 @@
         self._titles = {}
         # stemmed word -> set(filenames)
         self._mapping = {}
+        # desctypes -> index
+        self._desctypes = {'module': 0}
 
     def load(self, stream, format):
         """Reconstruct from frozen data."""
@@ -104,9 +107,10 @@
         if not isinstance(frozen, dict):
             raise ValueError('old format')
         index2fn = frozen['filenames']
-        self._titles = dict(zip(frozen['filenames'], frozen['titles']))
+        self._titles = dict(zip(index2fn, frozen['titles']))
         self._mapping = dict((k, set(index2fn[i] for i in v))
                              for (k, v) in frozen['terms'].iteritems())
+        # no need to load keywords/desctypes
 
     def dump(self, stream, format):
         """Dump the frozen index to a stream."""
@@ -117,14 +121,20 @@
     def get_keyword_map(self):
         """Return a dict of all keywords."""
         rv = {}
+        dt = self._desctypes
         for kw, (ref, _, _, _) in self.env.modules.iteritems():
-            rv[kw] = (ref, 'module', 'module-' + kw)
+            rv[kw] = (ref, 0, 'module-' + kw)
         for kw, (ref, ref_type) in self.env.descrefs.iteritems():
-            rv[kw] = (ref, ref_type, kw)
+            try:
+                i = dt[ref_type]
+            except KeyError:
+                i = len(dt)
+                dt[ref_type] = i
+            rv[kw] = (ref, i, kw)
         return rv
 
     def freeze(self):
-        """Create a useable data structure for serializing."""
+        """Create a usable data structure for serializing."""
         filenames = self._titles.keys()
         titles = self._titles.values()
         fn2index = dict((f, i) for (i, f) in enumerate(filenames))
@@ -134,7 +144,8 @@
             terms=dict((k, [fn2index[fn] for fn in v])
                        for (k, v) in self._mapping.iteritems()),
             keywords=dict((k, (fn2index[v[0]],) + v[1:]) for k, v in
-                          self.get_keyword_map().iteritems())
+                          self.get_keyword_map().iteritems()),
+            desctypes=dict((v, k) for (k, v) in self._desctypes.items()),
         )
 
     def prune(self, filenames):

Modified: doctools/trunk/sphinx/static/searchtools.js
==============================================================================
--- doctools/trunk/sphinx/static/searchtools.js	(original)
+++ doctools/trunk/sphinx/static/searchtools.js	Wed Sep 24 10:46:33 2008
@@ -294,7 +294,7 @@
     var excluded = [];
     var hlwords = [];
     var tmp = query.split(/\s+/);
-    var keyword = (tmp.length == 1) ? tmp[0] : null;
+    var keyword = (tmp.length == 1) ? tmp[0].toLowerCase() : null;
     for (var i = 0; i < tmp.length; i++) {
       // stem the word
       var word = stemmer.stemWord(tmp[i]).toLowerCase();
@@ -321,19 +321,31 @@
     var filenames = this._index.filenames;
     var titles = this._index.titles;
     var words = this._index.terms;
+    var keywords = this._index.keywords;
+    var desctypes = this._index.desctypes;
     var fileMap = {};
     var files = null;
-    var results = [];
+    var keywordResults = [];
     var regularResults = [];
     $('#search-progress').empty();
 
     // lookup the keyword
     if (keyword != null) {
-      var match = this._index.keywords[keyword];
-      if (match)
-        results.push([filenames[match[0]], titles[match[0]], match[2]]);
+      for (var kw in keywords) {
+        if (kw.toLowerCase().indexOf(keyword, kw.lastIndexOf('.')) > -1) {
+          match = keywords[kw];
+          descr = desctypes[match[1]] + _(', in ') + titles[match[0]];
+          keywordResults.push([filenames[match[0]], kw, match[2], descr]);
+        }
+      }
     }
 
+    // sort descending by keyword
+    keywordResults.sort(function(a, b) {
+      return (a[1] > b[1]) ? -1 : ((a[1] < b[1]) ? 1 : 0);
+    });
+
+
     // perform the search on the required words
     for (var i = 0; i < searchwords.length; i++) {
       var word = searchwords[i];
@@ -350,8 +362,7 @@
       }
     }
 
-    // now check if the files are in the correct
-    // areas and if the don't contain excluded words
+    // now check if the files don't contain excluded words
     for (var file in fileMap) {
       var valid = true;
 
@@ -371,14 +382,14 @@
       // if we have still a valid result we can add it
       // to the result list
       if (valid)
-        regularResults.push([filenames[file], titles[file], null]);
+        regularResults.push([filenames[file], titles[file], null, null]);
     }
 
     // delete unused variables in order to not waste
     // memory until list is retrieved completely
     delete filenames, titles, words;
 
-    // now sort the regular results by title
+    // now sort the regular results descending by title
     regularResults.sort(function(a, b) {
       var left = a[1].toLowerCase();
       var right = b[1].toLowerCase();
@@ -386,7 +397,7 @@
     });
 
     // combine both
-    results = regularResults.concat(results);
+    var results = regularResults.concat(keywordResults);
 
     // print the results
     var resultCount = results.length;
@@ -400,13 +411,21 @@
           item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX +
           highlightstring +
           (item[2] ? '#' + item[2] : '')).html(item[1]));
-        $.get('_sources/' + item[0] + '.txt', function(data) {
-          listItem.append($.makeSearchSummary(data, searchwords, hlwords));
+        if (item[3]) {
+          listItem.append($('<span> (' + item[3] + ')</span>'));
           Search.output.append(listItem);
-          listItem.slideDown(10, function() {
+          listItem.slideDown(5, function() {
             displayNextItem();
           });
-        });
+        } else {
+          $.get('_sources/' + item[0] + '.txt', function(data) {
+            listItem.append($.makeSearchSummary(data, searchwords, hlwords));
+            Search.output.append(listItem);
+            listItem.slideDown(5, function() {
+              displayNextItem();
+            });
+          });
+        }
       }
       // search finished, update title and status message
       else {


More information about the Python-checkins mailing list