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 = ')'
|
SUFFIX = ')'
|
||||||
|
|
||||||
def dumps(self, data):
|
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):
|
def loads(self, s):
|
||||||
data = s[len(self.PREFIX):-len(self.SUFFIX)]
|
data = s[len(self.PREFIX):-len(self.SUFFIX)]
|
||||||
@ -94,6 +95,8 @@ class IndexBuilder(object):
|
|||||||
self._titles = {}
|
self._titles = {}
|
||||||
# stemmed word -> set(filenames)
|
# stemmed word -> set(filenames)
|
||||||
self._mapping = {}
|
self._mapping = {}
|
||||||
|
# desctypes -> index
|
||||||
|
self._desctypes = {'module': 0}
|
||||||
|
|
||||||
def load(self, stream, format):
|
def load(self, stream, format):
|
||||||
"""Reconstruct from frozen data."""
|
"""Reconstruct from frozen data."""
|
||||||
@ -104,9 +107,10 @@ class IndexBuilder(object):
|
|||||||
if not isinstance(frozen, dict):
|
if not isinstance(frozen, dict):
|
||||||
raise ValueError('old format')
|
raise ValueError('old format')
|
||||||
index2fn = frozen['filenames']
|
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))
|
self._mapping = dict((k, set(index2fn[i] for i in v))
|
||||||
for (k, v) in frozen['terms'].iteritems())
|
for (k, v) in frozen['terms'].iteritems())
|
||||||
|
# no need to load keywords/desctypes
|
||||||
|
|
||||||
def dump(self, stream, format):
|
def dump(self, stream, format):
|
||||||
"""Dump the frozen index to a stream."""
|
"""Dump the frozen index to a stream."""
|
||||||
@ -117,14 +121,20 @@ class IndexBuilder(object):
|
|||||||
def get_keyword_map(self):
|
def get_keyword_map(self):
|
||||||
"""Return a dict of all keywords."""
|
"""Return a dict of all keywords."""
|
||||||
rv = {}
|
rv = {}
|
||||||
|
dt = self._desctypes
|
||||||
for kw, (ref, _, _, _) in self.env.modules.iteritems():
|
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():
|
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
|
return rv
|
||||||
|
|
||||||
def freeze(self):
|
def freeze(self):
|
||||||
"""Create a useable data structure for serializing."""
|
"""Create a usable data structure for serializing."""
|
||||||
filenames = self._titles.keys()
|
filenames = self._titles.keys()
|
||||||
titles = self._titles.values()
|
titles = self._titles.values()
|
||||||
fn2index = dict((f, i) for (i, f) in enumerate(filenames))
|
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])
|
terms=dict((k, [fn2index[fn] for fn in v])
|
||||||
for (k, v) in self._mapping.iteritems()),
|
for (k, v) in self._mapping.iteritems()),
|
||||||
keywords=dict((k, (fn2index[v[0]],) + v[1:]) for k, v in
|
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):
|
def prune(self, filenames):
|
||||||
|
@ -294,7 +294,7 @@ var Search = {
|
|||||||
var excluded = [];
|
var excluded = [];
|
||||||
var hlwords = [];
|
var hlwords = [];
|
||||||
var tmp = query.split(/\s+/);
|
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++) {
|
for (var i = 0; i < tmp.length; i++) {
|
||||||
// stem the word
|
// stem the word
|
||||||
var word = stemmer.stemWord(tmp[i]).toLowerCase();
|
var word = stemmer.stemWord(tmp[i]).toLowerCase();
|
||||||
@ -321,19 +321,31 @@ var Search = {
|
|||||||
var filenames = this._index.filenames;
|
var filenames = this._index.filenames;
|
||||||
var titles = this._index.titles;
|
var titles = this._index.titles;
|
||||||
var words = this._index.terms;
|
var words = this._index.terms;
|
||||||
|
var keywords = this._index.keywords;
|
||||||
|
var desctypes = this._index.desctypes;
|
||||||
var fileMap = {};
|
var fileMap = {};
|
||||||
var files = null;
|
var files = null;
|
||||||
var results = [];
|
var keywordResults = [];
|
||||||
var regularResults = [];
|
var regularResults = [];
|
||||||
$('#search-progress').empty();
|
$('#search-progress').empty();
|
||||||
|
|
||||||
// lookup the keyword
|
// lookup the keyword
|
||||||
if (keyword != null) {
|
if (keyword != null) {
|
||||||
var match = this._index.keywords[keyword];
|
for (var kw in keywords) {
|
||||||
if (match)
|
if (kw.toLowerCase().indexOf(keyword, kw.lastIndexOf('.')) > -1) {
|
||||||
results.push([filenames[match[0]], titles[match[0]], match[2]]);
|
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
|
// perform the search on the required words
|
||||||
for (var i = 0; i < searchwords.length; i++) {
|
for (var i = 0; i < searchwords.length; i++) {
|
||||||
var word = searchwords[i];
|
var word = searchwords[i];
|
||||||
@ -350,8 +362,7 @@ var Search = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// now check if the files are in the correct
|
// now check if the files don't contain excluded words
|
||||||
// areas and if the don't contain excluded words
|
|
||||||
for (var file in fileMap) {
|
for (var file in fileMap) {
|
||||||
var valid = true;
|
var valid = true;
|
||||||
|
|
||||||
@ -371,14 +382,14 @@ var Search = {
|
|||||||
// if we have still a valid result we can add it
|
// if we have still a valid result we can add it
|
||||||
// to the result list
|
// to the result list
|
||||||
if (valid)
|
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
|
// delete unused variables in order to not waste
|
||||||
// memory until list is retrieved completely
|
// memory until list is retrieved completely
|
||||||
delete filenames, titles, words;
|
delete filenames, titles, words;
|
||||||
|
|
||||||
// now sort the regular results by title
|
// now sort the regular results descending by title
|
||||||
regularResults.sort(function(a, b) {
|
regularResults.sort(function(a, b) {
|
||||||
var left = a[1].toLowerCase();
|
var left = a[1].toLowerCase();
|
||||||
var right = b[1].toLowerCase();
|
var right = b[1].toLowerCase();
|
||||||
@ -386,7 +397,7 @@ var Search = {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// combine both
|
// combine both
|
||||||
results = regularResults.concat(results);
|
var results = regularResults.concat(keywordResults);
|
||||||
|
|
||||||
// print the results
|
// print the results
|
||||||
var resultCount = results.length;
|
var resultCount = results.length;
|
||||||
@ -400,13 +411,21 @@ var Search = {
|
|||||||
item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX +
|
item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX +
|
||||||
highlightstring +
|
highlightstring +
|
||||||
(item[2] ? '#' + item[2] : '')).html(item[1]));
|
(item[2] ? '#' + item[2] : '')).html(item[1]));
|
||||||
$.get('_sources/' + item[0] + '.txt', function(data) {
|
if (item[3]) {
|
||||||
listItem.append($.makeSearchSummary(data, searchwords, hlwords));
|
listItem.append($('<span> (' + item[3] + ')</span>'));
|
||||||
Search.output.append(listItem);
|
Search.output.append(listItem);
|
||||||
listItem.slideDown(10, function() {
|
listItem.slideDown(5, function() {
|
||||||
displayNextItem();
|
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
|
// search finished, update title and status message
|
||||||
else {
|
else {
|
||||||
|
Loading…
Reference in New Issue
Block a user