ulalume3@11: /* ulalume3@11: * searchtools.js_t ulalume3@11: * ~~~~~~~~~~~~~~~~ ulalume3@11: * ulalume3@11: * Sphinx JavaScript utilties for the full-text search. ulalume3@11: * ulalume3@11: * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. ulalume3@11: * :license: BSD, see LICENSE for details. ulalume3@11: * ulalume3@11: */ ulalume3@11: ulalume3@11: /** ulalume3@11: * helper function to return a node containing the ulalume3@11: * search summary for a given text. keywords is a list ulalume3@11: * of stemmed words, hlwords is the list of normal, unstemmed ulalume3@11: * words. the first one is used to find the occurance, the ulalume3@11: * latter for highlighting it. ulalume3@11: */ ulalume3@11: ulalume3@11: jQuery.makeSearchSummary = function(text, keywords, hlwords) { ulalume3@11: var textLower = text.toLowerCase(); ulalume3@11: var start = 0; ulalume3@11: $.each(keywords, function() { ulalume3@11: var i = textLower.indexOf(this.toLowerCase()); ulalume3@11: if (i > -1) ulalume3@11: start = i; ulalume3@11: }); ulalume3@11: start = Math.max(start - 120, 0); ulalume3@11: var excerpt = ((start > 0) ? '...' : '') + ulalume3@11: $.trim(text.substr(start, 240)) + ulalume3@11: ((start + 240 - text.length) ? '...' : ''); ulalume3@11: var rv = $('
').text(excerpt); ulalume3@11: $.each(hlwords, function() { ulalume3@11: rv = rv.highlightText(this, 'highlighted'); ulalume3@11: }); ulalume3@11: return rv; ulalume3@11: } ulalume3@11: ulalume3@11: ulalume3@11: /** ulalume3@11: * Porter Stemmer ulalume3@11: */ ulalume3@11: var Stemmer = function() { ulalume3@11: ulalume3@11: var step2list = { ulalume3@11: ational: 'ate', ulalume3@11: tional: 'tion', ulalume3@11: enci: 'ence', ulalume3@11: anci: 'ance', ulalume3@11: izer: 'ize', ulalume3@11: bli: 'ble', ulalume3@11: alli: 'al', ulalume3@11: entli: 'ent', ulalume3@11: eli: 'e', ulalume3@11: ousli: 'ous', ulalume3@11: ization: 'ize', ulalume3@11: ation: 'ate', ulalume3@11: ator: 'ate', ulalume3@11: alism: 'al', ulalume3@11: iveness: 'ive', ulalume3@11: fulness: 'ful', ulalume3@11: ousness: 'ous', ulalume3@11: aliti: 'al', ulalume3@11: iviti: 'ive', ulalume3@11: biliti: 'ble', ulalume3@11: logi: 'log' ulalume3@11: }; ulalume3@11: ulalume3@11: var step3list = { ulalume3@11: icate: 'ic', ulalume3@11: ative: '', ulalume3@11: alize: 'al', ulalume3@11: iciti: 'ic', ulalume3@11: ical: 'ic', ulalume3@11: ful: '', ulalume3@11: ness: '' ulalume3@11: }; ulalume3@11: ulalume3@11: var c = "[^aeiou]"; // consonant ulalume3@11: var v = "[aeiouy]"; // vowel ulalume3@11: var C = c + "[^aeiouy]*"; // consonant sequence ulalume3@11: var V = v + "[aeiou]*"; // vowel sequence ulalume3@11: ulalume3@11: var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0 ulalume3@11: var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 ulalume3@11: var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 ulalume3@11: var s_v = "^(" + C + ")?" + v; // vowel in stem ulalume3@11: ulalume3@11: this.stemWord = function (w) { ulalume3@11: var stem; ulalume3@11: var suffix; ulalume3@11: var firstch; ulalume3@11: var origword = w; ulalume3@11: ulalume3@11: if (w.length < 3) ulalume3@11: return w; ulalume3@11: ulalume3@11: var re; ulalume3@11: var re2; ulalume3@11: var re3; ulalume3@11: var re4; ulalume3@11: ulalume3@11: firstch = w.substr(0,1); ulalume3@11: if (firstch == "y") ulalume3@11: w = firstch.toUpperCase() + w.substr(1); ulalume3@11: ulalume3@11: // Step 1a ulalume3@11: re = /^(.+?)(ss|i)es$/; ulalume3@11: re2 = /^(.+?)([^s])s$/; ulalume3@11: ulalume3@11: if (re.test(w)) ulalume3@11: w = w.replace(re,"$1$2"); ulalume3@11: else if (re2.test(w)) ulalume3@11: w = w.replace(re2,"$1$2"); ulalume3@11: ulalume3@11: // Step 1b ulalume3@11: re = /^(.+?)eed$/; ulalume3@11: re2 = /^(.+?)(ed|ing)$/; ulalume3@11: if (re.test(w)) { ulalume3@11: var fp = re.exec(w); ulalume3@11: re = new RegExp(mgr0); ulalume3@11: if (re.test(fp[1])) { ulalume3@11: re = /.$/; ulalume3@11: w = w.replace(re,""); ulalume3@11: } ulalume3@11: } ulalume3@11: else if (re2.test(w)) { ulalume3@11: var fp = re2.exec(w); ulalume3@11: stem = fp[1]; ulalume3@11: re2 = new RegExp(s_v); ulalume3@11: if (re2.test(stem)) { ulalume3@11: w = stem; ulalume3@11: re2 = /(at|bl|iz)$/; ulalume3@11: re3 = new RegExp("([^aeiouylsz])\\1$"); ulalume3@11: re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); ulalume3@11: if (re2.test(w)) ulalume3@11: w = w + "e"; ulalume3@11: else if (re3.test(w)) { ulalume3@11: re = /.$/; ulalume3@11: w = w.replace(re,""); ulalume3@11: } ulalume3@11: else if (re4.test(w)) ulalume3@11: w = w + "e"; ulalume3@11: } ulalume3@11: } ulalume3@11: ulalume3@11: // Step 1c ulalume3@11: re = /^(.+?)y$/; ulalume3@11: if (re.test(w)) { ulalume3@11: var fp = re.exec(w); ulalume3@11: stem = fp[1]; ulalume3@11: re = new RegExp(s_v); ulalume3@11: if (re.test(stem)) ulalume3@11: w = stem + "i"; ulalume3@11: } ulalume3@11: ulalume3@11: // Step 2 ulalume3@11: re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; ulalume3@11: if (re.test(w)) { ulalume3@11: var fp = re.exec(w); ulalume3@11: stem = fp[1]; ulalume3@11: suffix = fp[2]; ulalume3@11: re = new RegExp(mgr0); ulalume3@11: if (re.test(stem)) ulalume3@11: w = stem + step2list[suffix]; ulalume3@11: } ulalume3@11: ulalume3@11: // Step 3 ulalume3@11: re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; ulalume3@11: if (re.test(w)) { ulalume3@11: var fp = re.exec(w); ulalume3@11: stem = fp[1]; ulalume3@11: suffix = fp[2]; ulalume3@11: re = new RegExp(mgr0); ulalume3@11: if (re.test(stem)) ulalume3@11: w = stem + step3list[suffix]; ulalume3@11: } ulalume3@11: ulalume3@11: // Step 4 ulalume3@11: re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; ulalume3@11: re2 = /^(.+?)(s|t)(ion)$/; ulalume3@11: if (re.test(w)) { ulalume3@11: var fp = re.exec(w); ulalume3@11: stem = fp[1]; ulalume3@11: re = new RegExp(mgr1); ulalume3@11: if (re.test(stem)) ulalume3@11: w = stem; ulalume3@11: } ulalume3@11: else if (re2.test(w)) { ulalume3@11: var fp = re2.exec(w); ulalume3@11: stem = fp[1] + fp[2]; ulalume3@11: re2 = new RegExp(mgr1); ulalume3@11: if (re2.test(stem)) ulalume3@11: w = stem; ulalume3@11: } ulalume3@11: ulalume3@11: // Step 5 ulalume3@11: re = /^(.+?)e$/; ulalume3@11: if (re.test(w)) { ulalume3@11: var fp = re.exec(w); ulalume3@11: stem = fp[1]; ulalume3@11: re = new RegExp(mgr1); ulalume3@11: re2 = new RegExp(meq1); ulalume3@11: re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); ulalume3@11: if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) ulalume3@11: w = stem; ulalume3@11: } ulalume3@11: re = /ll$/; ulalume3@11: re2 = new RegExp(mgr1); ulalume3@11: if (re.test(w) && re2.test(w)) { ulalume3@11: re = /.$/; ulalume3@11: w = w.replace(re,""); ulalume3@11: } ulalume3@11: ulalume3@11: // and turn initial Y back to y ulalume3@11: if (firstch == "y") ulalume3@11: w = firstch.toLowerCase() + w.substr(1); ulalume3@11: return w; ulalume3@11: } ulalume3@11: } ulalume3@11: ulalume3@11: ulalume3@11: /** ulalume3@11: * Search Module ulalume3@11: */ ulalume3@11: var Search = { ulalume3@11: ulalume3@11: _index : null, ulalume3@11: _queued_query : null, ulalume3@11: _pulse_status : -1, ulalume3@11: ulalume3@11: init : function() { ulalume3@11: var params = $.getQueryParameters(); ulalume3@11: if (params.q) { ulalume3@11: var query = params.q[0]; ulalume3@11: $('input[name="q"]')[0].value = query; ulalume3@11: this.performSearch(query); ulalume3@11: } ulalume3@11: }, ulalume3@11: ulalume3@11: loadIndex : function(url) { ulalume3@11: $.ajax({type: "GET", url: url, data: null, success: null, ulalume3@11: dataType: "script", cache: true}); ulalume3@11: }, ulalume3@11: ulalume3@11: setIndex : function(index) { ulalume3@11: var q; ulalume3@11: this._index = index; ulalume3@11: if ((q = this._queued_query) !== null) { ulalume3@11: this._queued_query = null; ulalume3@11: Search.query(q); ulalume3@11: } ulalume3@11: }, ulalume3@11: ulalume3@11: hasIndex : function() { ulalume3@11: return this._index !== null; ulalume3@11: }, ulalume3@11: ulalume3@11: deferQuery : function(query) { ulalume3@11: this._queued_query = query; ulalume3@11: }, ulalume3@11: ulalume3@11: stopPulse : function() { ulalume3@11: this._pulse_status = 0; ulalume3@11: }, ulalume3@11: ulalume3@11: startPulse : function() { ulalume3@11: if (this._pulse_status >= 0) ulalume3@11: return; ulalume3@11: function pulse() { ulalume3@11: Search._pulse_status = (Search._pulse_status + 1) % 4; ulalume3@11: var dotString = ''; ulalume3@11: for (var i = 0; i < Search._pulse_status; i++) ulalume3@11: dotString += '.'; ulalume3@11: Search.dots.text(dotString); ulalume3@11: if (Search._pulse_status > -1) ulalume3@11: window.setTimeout(pulse, 500); ulalume3@11: }; ulalume3@11: pulse(); ulalume3@11: }, ulalume3@11: ulalume3@11: /** ulalume3@11: * perform a search for something ulalume3@11: */ ulalume3@11: performSearch : function(query) { ulalume3@11: // create the required interface elements ulalume3@11: this.out = $('#search-results'); ulalume3@11: this.title = $('

' + _('Searching') + '

').appendTo(this.out); ulalume3@11: this.dots = $('').appendTo(this.title); ulalume3@11: this.status = $('

').appendTo(this.out); ulalume3@11: this.output = $('