Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
| Download
Sage Reference Manual
Project: SageManifolds
Views: 717109/*1* searchtools.js_t2* ~~~~~~~~~~~~~~~~3*4* Sphinx JavaScript utilties for the full-text search.5*6* :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS.7* :license: BSD, see LICENSE for details.8*9*/101112/**13* Porter Stemmer14*/15var Stemmer = function() {1617var step2list = {18ational: 'ate',19tional: 'tion',20enci: 'ence',21anci: 'ance',22izer: 'ize',23bli: 'ble',24alli: 'al',25entli: 'ent',26eli: 'e',27ousli: 'ous',28ization: 'ize',29ation: 'ate',30ator: 'ate',31alism: 'al',32iveness: 'ive',33fulness: 'ful',34ousness: 'ous',35aliti: 'al',36iviti: 'ive',37biliti: 'ble',38logi: 'log'39};4041var step3list = {42icate: 'ic',43ative: '',44alize: 'al',45iciti: 'ic',46ical: 'ic',47ful: '',48ness: ''49};5051var c = "[^aeiou]"; // consonant52var v = "[aeiouy]"; // vowel53var C = c + "[^aeiouy]*"; // consonant sequence54var V = v + "[aeiou]*"; // vowel sequence5556var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>057var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=158var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>159var s_v = "^(" + C + ")?" + v; // vowel in stem6061this.stemWord = function (w) {62var stem;63var suffix;64var firstch;65var origword = w;6667if (w.length < 3)68return w;6970var re;71var re2;72var re3;73var re4;7475firstch = w.substr(0,1);76if (firstch == "y")77w = firstch.toUpperCase() + w.substr(1);7879// Step 1a80re = /^(.+?)(ss|i)es$/;81re2 = /^(.+?)([^s])s$/;8283if (re.test(w))84w = w.replace(re,"$1$2");85else if (re2.test(w))86w = w.replace(re2,"$1$2");8788// Step 1b89re = /^(.+?)eed$/;90re2 = /^(.+?)(ed|ing)$/;91if (re.test(w)) {92var fp = re.exec(w);93re = new RegExp(mgr0);94if (re.test(fp[1])) {95re = /.$/;96w = w.replace(re,"");97}98}99else if (re2.test(w)) {100var fp = re2.exec(w);101stem = fp[1];102re2 = new RegExp(s_v);103if (re2.test(stem)) {104w = stem;105re2 = /(at|bl|iz)$/;106re3 = new RegExp("([^aeiouylsz])\\1$");107re4 = new RegExp("^" + C + v + "[^aeiouwxy]$");108if (re2.test(w))109w = w + "e";110else if (re3.test(w)) {111re = /.$/;112w = w.replace(re,"");113}114else if (re4.test(w))115w = w + "e";116}117}118119// Step 1c120re = /^(.+?)y$/;121if (re.test(w)) {122var fp = re.exec(w);123stem = fp[1];124re = new RegExp(s_v);125if (re.test(stem))126w = stem + "i";127}128129// Step 2130re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;131if (re.test(w)) {132var fp = re.exec(w);133stem = fp[1];134suffix = fp[2];135re = new RegExp(mgr0);136if (re.test(stem))137w = stem + step2list[suffix];138}139140// Step 3141re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;142if (re.test(w)) {143var fp = re.exec(w);144stem = fp[1];145suffix = fp[2];146re = new RegExp(mgr0);147if (re.test(stem))148w = stem + step3list[suffix];149}150151// Step 4152re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;153re2 = /^(.+?)(s|t)(ion)$/;154if (re.test(w)) {155var fp = re.exec(w);156stem = fp[1];157re = new RegExp(mgr1);158if (re.test(stem))159w = stem;160}161else if (re2.test(w)) {162var fp = re2.exec(w);163stem = fp[1] + fp[2];164re2 = new RegExp(mgr1);165if (re2.test(stem))166w = stem;167}168169// Step 5170re = /^(.+?)e$/;171if (re.test(w)) {172var fp = re.exec(w);173stem = fp[1];174re = new RegExp(mgr1);175re2 = new RegExp(meq1);176re3 = new RegExp("^" + C + v + "[^aeiouwxy]$");177if (re.test(stem) || (re2.test(stem) && !(re3.test(stem))))178w = stem;179}180re = /ll$/;181re2 = new RegExp(mgr1);182if (re.test(w) && re2.test(w)) {183re = /.$/;184w = w.replace(re,"");185}186187// and turn initial Y back to y188if (firstch == "y")189w = firstch.toLowerCase() + w.substr(1);190return w;191}192}193194195196/**197* Simple result scoring code.198*/199var Scorer = {200// Implement the following function to further tweak the score for each result201// The function takes a result array [filename, title, anchor, descr, score]202// and returns the new score.203/*204score: function(result) {205return result[4];206},207*/208209// query matches the full name of an object210objNameMatch: 11,211// or matches in the last dotted part of the object name212objPartialMatch: 6,213// Additive scores depending on the priority of the object214objPrio: {0: 15, // used to be importantResults2151: 5, // used to be objectResults2162: -5}, // used to be unimportantResults217// Used when the priority is not in the mapping.218objPrioDefault: 0,219220// query found in title221title: 15,222// query found in terms223term: 5224};225226227/**228* Search Module229*/230var Search = {231232_index : null,233_queued_query : null,234_pulse_status : -1,235236init : function() {237var params = $.getQueryParameters();238if (params.q) {239var query = params.q[0];240$('input[name="q"]')[0].value = query;241this.performSearch(query);242}243},244245loadIndex : function(url) {246$.ajax({type: "GET", url: url, data: null,247dataType: "script", cache: true,248complete: function(jqxhr, textstatus) {249if (textstatus != "success") {250document.getElementById("searchindexloader").src = url;251}252}});253},254255setIndex : function(index) {256var q;257this._index = index;258if ((q = this._queued_query) !== null) {259this._queued_query = null;260Search.query(q);261}262},263264hasIndex : function() {265return this._index !== null;266},267268deferQuery : function(query) {269this._queued_query = query;270},271272stopPulse : function() {273this._pulse_status = 0;274},275276startPulse : function() {277if (this._pulse_status >= 0)278return;279function pulse() {280var i;281Search._pulse_status = (Search._pulse_status + 1) % 4;282var dotString = '';283for (i = 0; i < Search._pulse_status; i++)284dotString += '.';285Search.dots.text(dotString);286if (Search._pulse_status > -1)287window.setTimeout(pulse, 500);288}289pulse();290},291292/**293* perform a search for something (or wait until index is loaded)294*/295performSearch : function(query) {296// create the required interface elements297this.out = $('#search-results');298this.title = $('<h2>' + _('Searching') + '</h2>').appendTo(this.out);299this.dots = $('<span></span>').appendTo(this.title);300this.status = $('<p style="display: none"></p>').appendTo(this.out);301this.output = $('<ul class="search"/>').appendTo(this.out);302303$('#search-progress').text(_('Preparing search...'));304this.startPulse();305306// index already loaded, the browser was quick!307if (this.hasIndex())308this.query(query);309else310this.deferQuery(query);311},312313/**314* execute search (requires search index to be loaded)315*/316query : function(query) {317var i;318var stopwords = ["a","and","are","as","at","be","but","by","for","if","in","into","is","it","near","no","not","of","on","or","such","that","the","their","then","there","these","they","this","to","was","will","with"];319320// stem the searchterms and add them to the correct list321var stemmer = new Stemmer();322var searchterms = [];323var excluded = [];324var hlterms = [];325var tmp = query.split(/\s+/);326var objectterms = [];327for (i = 0; i < tmp.length; i++) {328if (tmp[i] !== "") {329objectterms.push(tmp[i].toLowerCase());330}331332if ($u.indexOf(stopwords, tmp[i].toLowerCase()) != -1 || tmp[i].match(/^\d+$/) ||333tmp[i] === "") {334// skip this "word"335continue;336}337// stem the word338var word = stemmer.stemWord(tmp[i].toLowerCase());339var toAppend;340// select the correct list341if (word[0] == '-') {342toAppend = excluded;343word = word.substr(1);344}345else {346toAppend = searchterms;347hlterms.push(tmp[i].toLowerCase());348}349// only add if not already in the list350if (!$u.contains(toAppend, word))351toAppend.push(word);352}353var highlightstring = '?highlight=' + $.urlencode(hlterms.join(" "));354355// console.debug('SEARCH: searching for:');356// console.info('required: ', searchterms);357// console.info('excluded: ', excluded);358359// prepare search360var terms = this._index.terms;361var titleterms = this._index.titleterms;362363// array of [filename, title, anchor, descr, score]364var results = [];365$('#search-progress').empty();366367// lookup as object368for (i = 0; i < objectterms.length; i++) {369var others = [].concat(objectterms.slice(0, i),370objectterms.slice(i+1, objectterms.length));371results = results.concat(this.performObjectSearch(objectterms[i], others));372}373374// lookup as search terms in fulltext375results = results.concat(this.performTermsSearch(searchterms, excluded, terms, Scorer.term))376.concat(this.performTermsSearch(searchterms, excluded, titleterms, Scorer.title));377378// let the scorer override scores with a custom scoring function379if (Scorer.score) {380for (i = 0; i < results.length; i++)381results[i][4] = Scorer.score(results[i]);382}383384// now sort the results by score (in opposite order of appearance, since the385// display function below uses pop() to retrieve items) and then386// alphabetically387results.sort(function(a, b) {388var left = a[4];389var right = b[4];390if (left > right) {391return 1;392} else if (left < right) {393return -1;394} else {395// same score: sort alphabetically396left = a[1].toLowerCase();397right = b[1].toLowerCase();398return (left > right) ? -1 : ((left < right) ? 1 : 0);399}400});401402// for debugging403//Search.lastresults = results.slice(); // a copy404//console.info('search results:', Search.lastresults);405406// print the results407var resultCount = results.length;408function displayNextItem() {409// results left, load the summary and display it410if (results.length) {411var item = results.pop();412var listItem = $('<li style="display:none"></li>');413if (DOCUMENTATION_OPTIONS.FILE_SUFFIX === '') {414// dirhtml builder415var dirname = item[0] + '/';416if (dirname.match(/\/index\/$/)) {417dirname = dirname.substring(0, dirname.length-6);418} else if (dirname == 'index/') {419dirname = '';420}421listItem.append($('<a/>').attr('href',422DOCUMENTATION_OPTIONS.URL_ROOT + dirname +423highlightstring + item[2]).html(item[1]));424} else {425// normal html builders426listItem.append($('<a/>').attr('href',427item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX +428highlightstring + item[2]).html(item[1]));429}430if (item[3]) {431listItem.append($('<span> (' + item[3] + ')</span>'));432Search.output.append(listItem);433listItem.slideDown(5, function() {434displayNextItem();435});436} else if (DOCUMENTATION_OPTIONS.HAS_SOURCE) {437$.ajax({url: DOCUMENTATION_OPTIONS.URL_ROOT + '_sources/' + item[0] + '.txt',438dataType: "text",439complete: function(jqxhr, textstatus) {440var data = jqxhr.responseText;441if (data !== '') {442listItem.append(Search.makeSearchSummary(data, searchterms, hlterms));443}444Search.output.append(listItem);445listItem.slideDown(5, function() {446displayNextItem();447});448}});449} else {450// no source available, just display title451Search.output.append(listItem);452listItem.slideDown(5, function() {453displayNextItem();454});455}456}457// search finished, update title and status message458else {459Search.stopPulse();460Search.title.text(_('Search Results'));461if (!resultCount)462Search.status.text(_('Your search did not match any documents. Please make sure that all words are spelled correctly and that you\'ve selected enough categories.'));463else464Search.status.text(_('Search finished, found %s page(s) matching the search query.').replace('%s', resultCount));465Search.status.fadeIn(500);466}467}468displayNextItem();469},470471/**472* search for object names473*/474performObjectSearch : function(object, otherterms) {475var filenames = this._index.filenames;476var objects = this._index.objects;477var objnames = this._index.objnames;478var titles = this._index.titles;479480var i;481var results = [];482483for (var prefix in objects) {484for (var name in objects[prefix]) {485var fullname = (prefix ? prefix + '.' : '') + name;486if (fullname.toLowerCase().indexOf(object) > -1) {487var score = 0;488var parts = fullname.split('.');489// check for different match types: exact matches of full name or490// "last name" (i.e. last dotted part)491if (fullname == object || parts[parts.length - 1] == object) {492score += Scorer.objNameMatch;493// matches in last name494} else if (parts[parts.length - 1].indexOf(object) > -1) {495score += Scorer.objPartialMatch;496}497var match = objects[prefix][name];498var objname = objnames[match[1]][2];499var title = titles[match[0]];500// If more than one term searched for, we require other words to be501// found in the name/title/description502if (otherterms.length > 0) {503var haystack = (prefix + ' ' + name + ' ' +504objname + ' ' + title).toLowerCase();505var allfound = true;506for (i = 0; i < otherterms.length; i++) {507if (haystack.indexOf(otherterms[i]) == -1) {508allfound = false;509break;510}511}512if (!allfound) {513continue;514}515}516var descr = objname + _(', in ') + title;517518var anchor = match[3];519if (anchor === '')520anchor = fullname;521else if (anchor == '-')522anchor = objnames[match[1]][1] + '-' + fullname;523// add custom score for some objects according to scorer524if (Scorer.objPrio.hasOwnProperty(match[2])) {525score += Scorer.objPrio[match[2]];526} else {527score += Scorer.objPrioDefault;528}529results.push([filenames[match[0]], fullname, '#'+anchor, descr, score]);530}531}532}533534return results;535},536537/**538* search for full-text terms in the index539*/540performTermsSearch : function(searchterms, excluded, terms, score) {541var filenames = this._index.filenames;542var titles = this._index.titles;543544var i, j, file, files;545var fileMap = {};546var results = [];547548// perform the search on the required terms549for (i = 0; i < searchterms.length; i++) {550var word = searchterms[i];551// no match but word was a required one552if ((files = terms[word]) === undefined)553break;554if (files.length === undefined) {555files = [files];556}557// create the mapping558for (j = 0; j < files.length; j++) {559file = files[j];560if (file in fileMap)561fileMap[file].push(word);562else563fileMap[file] = [word];564}565}566567// now check if the files don't contain excluded terms568for (file in fileMap) {569var valid = true;570571// check if all requirements are matched572if (fileMap[file].length != searchterms.length)573continue;574575// ensure that none of the excluded terms is in the search result576for (i = 0; i < excluded.length; i++) {577if (terms[excluded[i]] == file ||578$u.contains(terms[excluded[i]] || [], file)) {579valid = false;580break;581}582}583584// if we have still a valid result we can add it to the result list585if (valid) {586results.push([filenames[file], titles[file], '', null, score]);587}588}589return results;590},591592/**593* helper function to return a node containing the594* search summary for a given text. keywords is a list595* of stemmed words, hlwords is the list of normal, unstemmed596* words. the first one is used to find the occurance, the597* latter for highlighting it.598*/599makeSearchSummary : function(text, keywords, hlwords) {600var textLower = text.toLowerCase();601var start = 0;602$.each(keywords, function() {603var i = textLower.indexOf(this.toLowerCase());604if (i > -1)605start = i;606});607start = Math.max(start - 120, 0);608var excerpt = ((start > 0) ? '...' : '') +609$.trim(text.substr(start, 240)) +610((start + 240 - text.length) ? '...' : '');611var rv = $('<div class="context"></div>').text(excerpt);612$.each(hlwords, function() {613rv = rv.highlightText(this, 'highlighted');614});615return rv;616}617};618619$(document).ready(function() {620Search.init();621});622623