[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