search: make the search work with the new domain model.

This commit is contained in:
Georg Brandl 2009-09-08 00:04:25 +02:00
parent b4ef4bd670
commit 92aa430241
6 changed files with 72 additions and 54 deletions

View File

@ -17,7 +17,7 @@ class ObjType(object):
"""
known_attrs = {
'search': True,
'searchprio': 1,
}
def __init__(self, lname, *roles, **attrs):
@ -158,8 +158,13 @@ class Domain(object):
* `type` -- object type, a key in ``self.object_types``
* `docname` -- the document where it is to be found
* `anchor` -- the anchor name for the object
* `priority` -- how "important" the object is; an integer
(XXX assign meanings)
* `priority` -- how "important" the object is (determines placement
in search results)
1: default priority (placed before full-text matches)
0: object is important (placed before default-priority objects)
2: object is unimportant (placed after full-text matches)
-1: object should not show up in search at all
"""
return []

View File

@ -201,4 +201,4 @@ class CDomain(Domain):
def get_objects(self):
for refname, (docname, type) in self.data['objects'].iteritems():
yield (refname, type, docname, refname, 0)
yield (refname, type, docname, refname, 1)

View File

@ -512,6 +512,6 @@ class PythonDomain(Domain):
def get_objects(self):
for modname, info in self.data['modules'].iteritems():
yield (modname, 'module', info[0], 'module-' + modname, 1)
yield (modname, 'module', info[0], 'module-' + modname, 0)
for refname, (docname, type) in self.data['objects'].iteritems():
yield (refname, type, docname, refname, 0)
yield (refname, type, docname, refname, 1)

View File

@ -301,8 +301,8 @@ class StandardDomain(Domain):
label = 'Default'
object_types = {
'term': ObjType(l_('glossary term'), 'term', search=False),
'token': ObjType(l_('grammar token'), 'token', search=False),
'term': ObjType(l_('glossary term'), 'term', searchprio=-1),
'token': ObjType(l_('grammar token'), 'token', searchprio=-1),
'envvar': ObjType(l_('environment variable'), 'envvar'),
'cmdoption': ObjType(l_('program option'), 'option'),
}
@ -358,4 +358,8 @@ class StandardDomain(Domain):
labelid, contnode)
def get_objects(self):
return [] # XXX implement
for (prog, option), info in self.data['progoptions'].iteritems():
yield (option, 'option', info[0], info[1], 1)
for (type, name), info in self.data['objects'].iteritems():
yield (name, type, info[0], info[1],
self.object_types[type].attrs['searchprio'])

View File

@ -121,6 +121,8 @@ class IndexBuilder(object):
self._mapping = {}
# objtype -> index
self._objtypes = {}
# objtype index -> objname (localized)
self._objnames = {}
def load(self, stream, format):
"""Reconstruct from frozen data."""
@ -146,31 +148,30 @@ class IndexBuilder(object):
format = self.formats[format]
format.dump(self.freeze(), stream)
def get_modules(self, fn2index):
def get_objects(self, fn2index):
rv = {}
# XXX implement search capability
return rv
for name, (doc, _, _, _) in self.env.modules.iteritems():
if doc in fn2index:
rv[name] = fn2index[doc]
return rv
def get_descrefs(self, fn2index):
rv = {}
dt = self._objtypes
# XXX implement search capability
return rv
for fullname, (doc, desctype) in self.env.descrefs.iteritems():
if doc not in fn2index:
continue
prefix, name = rpartition(fullname, '.')
pdict = rv.setdefault(prefix, {})
try:
i = dt[desctype]
except KeyError:
i = len(dt)
dt[desctype] = i
pdict[name] = (fn2index[doc], i)
ot = self._objtypes
on = self._objnames
for domainname, domain in self.env.domains.iteritems():
for fullname, type, docname, anchor, prio in domain.get_objects():
if docname not in fn2index:
continue
if prio < 0:
continue
# XXX splitting at dot is kind of Python specific
prefix, name = rpartition(fullname, '.')
pdict = rv.setdefault(prefix, {})
try:
i = ot[domainname, type]
except KeyError:
i = len(ot)
ot[domainname, type] = i
otype = domain.object_types.get(type)
if otype:
on[i] = str(otype.lname) # fire translation proxies
else:
on[i] = type
pdict[name] = (fn2index[docname], i, prio)
return rv
def get_terms(self, fn2index):
@ -189,15 +190,13 @@ class IndexBuilder(object):
filenames = self._titles.keys()
titles = self._titles.values()
fn2index = dict((f, i) for (i, f) in enumerate(filenames))
return dict(
filenames=filenames,
titles=titles,
terms=self.get_terms(fn2index),
# XXX
#descrefs=self.get_descrefs(fn2index),
#modules=self.get_modules(fn2index),
objtypes=dict((v, k) for (k, v) in self._objtypes.items()),
)
terms = self.get_terms(fn2index)
objects = self.get_objects(fn2index) # populates _objtypes
objtypes = dict((v, k[0] + ':' + k[1])
for (k, v) in self._objtypes.iteritems())
objnames = self._objnames
return dict(filenames=filenames, titles=titles, terms=terms,
objects=objects, objtypes=objtypes, objnames=objnames)
def prune(self, filenames):
"""Remove data for all filenames not in the list."""

View File

@ -332,29 +332,30 @@ var Search = {
var terms = this._index.terms;
var objects = this._index.objects;
var objtypes = this._index.objtypes;
var objnames = this._index.objnames;
var fileMap = {};
var files = null;
// different result priorities
var importantResults = [];
var objectResults = [];
var regularResults = [];
var unimportantResults = [];
$('#search-progress').empty();
// lookup as object
if (object != null) {
// XXX must be adapted
for (var module in modules) {
if (module.indexOf(object) > -1) {
fn = modules[module];
descr = _('module, in ') + titles[fn];
objectResults.push([filenames[fn], module, '#module-'+module, descr]);
}
}
for (var prefix in objects) {
for (var name in objects[prefix]) {
var fullname = (prefix ? prefix + '.' : '') + name;
if (fullname.toLowerCase().indexOf(object) > -1) {
match = objects[prefix][name];
descr = objtypes[match[1]] + _(', in ') + titles[match[0]];
objectResults.push([filenames[match[0]], fullname, '#'+fullname, descr]);
descr = objnames[match[1]] + _(', in ') + titles[match[0]];
result = [filenames[match[0]], fullname, '#'+fullname, descr];
switch (match[2]) {
case 1: objectResults.push(result); break;
case 0: importantResults.push(result); break;
case 2: unimportantResults.push(result); break;
}
}
}
}
@ -365,6 +366,14 @@ var Search = {
return (a[1] > b[1]) ? -1 : ((a[1] < b[1]) ? 1 : 0);
});
importantResults.sort(function(a, b) {
return (a[1] > b[1]) ? -1 : ((a[1] < b[1]) ? 1 : 0);
});
unimportantResults.sort(function(a, b) {
return (a[1] > b[1]) ? -1 : ((a[1] < b[1]) ? 1 : 0);
});
// perform the search on the required terms
for (var i = 0; i < searchterms.length; i++) {
@ -420,8 +429,9 @@ var Search = {
return (left > right) ? -1 : ((left < right) ? 1 : 0);
});
// combine both
var results = regularResults.concat(objectResults);
// combine all results
var results = unimportantResults.concat(regularResults)
.concat(objectResults).concat(importantResults);
// print the results
var resultCount = results.length;