Commits

Georg Brandl committed a51398a Merge

branch merge

Comments (0)

Files changed (3)

sphinx/builders/gettext.py

         catalog = self.catalogs[docname.split(SEP, 1)[0]]
 
         for node, msg in extract_messages(doctree):
-            catalog.setdefault(node.uid, msg)
+            if not msg in catalog:
+                catalog[msg] = []
+            if node.source and node.line:
+                position = {"source": node.source,
+                            "line": node.line}
+                catalog[msg].append(position)
 
 
 class MessageCatalogBuilder(I18nBuilder):
             pofile = open(pofn, 'w', encoding='utf-8')
             try:
                 pofile.write(POHEADER % data)
-                for uid, message in messages.iteritems():
+                for message, positions in messages.iteritems():
                     # message contains *one* line of text ready for translation
                     message = message.replace(u'\\', ur'\\'). \
                                       replace(u'"', ur'\"')
-                    pomsg = u'#%s\nmsgid "%s"\nmsgstr ""\n\n' % (uid, message)
-                    pofile.write(pomsg)
+                    for position in positions:
+                        source = path.relpath(position["source"], self.outdir)
+                        line = position["line"]
+                        pofile.write(u'#: %s:%d\n' % (source, line))
+                    pofile.write(u'msgid "%s"\nmsgstr ""\n\n' % message)
             finally:
                 pofile.close()

sphinx/ext/coverage.py

                         op.write('\n')
                     if undoc['classes']:
                         op.write('Classes:\n')
-                        for name, methods in undoc['classes'].iteritems():
+                        for name, methods in sorted(undoc['classes'].iteritems()):
                             if not methods:
                                 op.write(' * %s\n' % name)
                             else:

sphinx/themes/basic/static/searchtools.js_t

     var excluded = [];
     var hlterms = [];
     var tmp = query.split(/\s+/);
-    var object = (tmp.length == 1) ? tmp[0].toLowerCase() : null;
+    var objectterms = [];
     for (var i = 0; i < tmp.length; i++) {
+      if (tmp[i] != "") {
+          objectterms.push(tmp[i].toLowerCase());
+      }
+
       if ($u.indexOf(stopwords, tmp[i]) != -1 || tmp[i].match(/^\d+$/) ||
           tmp[i] == "") {
         // skip this "word"
     var filenames = this._index.filenames;
     var titles = this._index.titles;
     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
     $('#search-progress').empty();
 
     // lookup as object
-    if (object != null) {
-      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 = objnames[match[1]] + _(', in ') + titles[match[0]];
-            // XXX the generated anchors are not generally correct
-            // XXX there may be custom prefixes
-            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;
-            }
-          }
-        }
-      }
+    for (var i = 0; i < objectterms.length; i++) {
+      var others = Array.concat(objectterms.slice(0,i),
+                                objectterms.slice(i+1, objectterms.length))
+      var results = this.performObjectSearch(objectterms[i], others);
+      // Assume first word is most likely to be the object,
+      // other words more likely to be in description.
+      // Therefore put matches for earlier words first.
+      // (Results are eventually used in reverse order).
+      objectResults = results[0].concat(objectResults);
+      importantResults = results[1].concat(importantResults);
+      unimportantResults = results[2].concat(unimportantResults);
     }
 
-    // sort results descending
-    objectResults.sort(function(a, b) {
-      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++) {
       var word = searchterms[i];
       }
     }
     displayNextItem();
+  },
+
+  performObjectSearch : function(object, otherterms) {
+    var filenames = this._index.filenames;
+    var objects = this._index.objects;
+    var objnames = this._index.objnames;
+    var titles = this._index.titles;
+
+    var importantResults = [];
+    var objectResults = [];
+    var unimportantResults = [];
+
+    for (var prefix in objects) {
+      for (var name in objects[prefix]) {
+        var fullname = (prefix ? prefix + '.' : '') + name;
+        if (fullname.toLowerCase().indexOf(object) > -1) {
+          var match = objects[prefix][name];
+          var objname = objnames[match[1]];
+          var title = titles[match[0]];
+          // If more than one term searched for, we require other words to be
+          // found in the name/title/description
+          if (otherterms.length > 0) {
+            var haystack = (prefix + ' ' + name + ' ' + objname + ' ' + title).toLowerCase();
+            var allfound = true;
+            for (var i = 0; i < otherterms.length; i++) {
+              if (haystack.indexOf(otherterms[i]) == -1) {
+                allfound = false;
+                break;
+              }
+            }
+            if (!allfound) {
+              continue;
+            }
+          }
+          var descr = objname + _(', in ') + title;
+          // XXX the generated anchors are not generally correct
+          // XXX there may be custom prefixes
+          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;
+          }
+        }
+      }
+    }
+
+    // sort results descending
+    objectResults.sort(function(a, b) {
+      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);
+    });
+
+    return [importantResults, objectResults, unimportantResults]
   }
 }