mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
* 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.
This commit is contained in:
parent
b21d71abfd
commit
c4b660c5e0
@ -33,7 +33,8 @@ class _JavaScriptIndex(object):
|
||||
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 @@ class IndexBuilder(object):
|
||||
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 @@ class IndexBuilder(object):
|
||||
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 @@ class IndexBuilder(object):
|
||||
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 @@ class IndexBuilder(object):
|
||||
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):
|
||||
|
@ -294,7 +294,7 @@ var Search = {
|
||||
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,18 +321,30 @@ var Search = {
|
||||
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++) {
|
||||
@ -350,8 +362,7 @@ var Search = {
|
||||
}
|
||||
}
|
||||
|
||||
// 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 @@ var Search = {
|
||||
// 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 @@ var Search = {
|
||||
});
|
||||
|
||||
// combine both
|
||||
results = regularResults.concat(results);
|
||||
var results = regularResults.concat(keywordResults);
|
||||
|
||||
// print the results
|
||||
var resultCount = results.length;
|
||||
@ -400,14 +411,22 @@ var Search = {
|
||||
item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX +
|
||||
highlightstring +
|
||||
(item[2] ? '#' + item[2] : '')).html(item[1]));
|
||||
if (item[3]) {
|
||||
listItem.append($('<span> (' + item[3] + ')</span>'));
|
||||
Search.output.append(listItem);
|
||||
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(10, function() {
|
||||
listItem.slideDown(5, function() {
|
||||
displayNextItem();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
// search finished, update title and status message
|
||||
else {
|
||||
Search.stopPulse();
|
||||
|
Loading…
Reference in New Issue
Block a user