]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_GCC/freedom-metal/doc/html/_static/searchtools.js
Base project to replace existing Freedom Studio project using latest Freedom Studio...
[freertos] / FreeRTOS / Demo / RISC-V_RV32_SiFive_HiFive1_GCC / freedom-metal / doc / html / _static / searchtools.js
1 /*
2  * searchtools.js_t
3  * ~~~~~~~~~~~~~~~~
4  *
5  * Sphinx JavaScript utilities for the full-text search.
6  *
7  * :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
8  * :license: BSD, see LICENSE for details.
9  *
10  */
11
12
13 /* Non-minified version JS is _stemmer.js if file is provided */ 
14 /**
15  * Porter Stemmer
16  */
17 var Stemmer = function() {
18
19   var step2list = {
20     ational: 'ate',
21     tional: 'tion',
22     enci: 'ence',
23     anci: 'ance',
24     izer: 'ize',
25     bli: 'ble',
26     alli: 'al',
27     entli: 'ent',
28     eli: 'e',
29     ousli: 'ous',
30     ization: 'ize',
31     ation: 'ate',
32     ator: 'ate',
33     alism: 'al',
34     iveness: 'ive',
35     fulness: 'ful',
36     ousness: 'ous',
37     aliti: 'al',
38     iviti: 'ive',
39     biliti: 'ble',
40     logi: 'log'
41   };
42
43   var step3list = {
44     icate: 'ic',
45     ative: '',
46     alize: 'al',
47     iciti: 'ic',
48     ical: 'ic',
49     ful: '',
50     ness: ''
51   };
52
53   var c = "[^aeiou]";          // consonant
54   var v = "[aeiouy]";          // vowel
55   var C = c + "[^aeiouy]*";    // consonant sequence
56   var V = v + "[aeiou]*";      // vowel sequence
57
58   var mgr0 = "^(" + C + ")?" + V + C;                      // [C]VC... is m>0
59   var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$";    // [C]VC[V] is m=1
60   var mgr1 = "^(" + C + ")?" + V + C + V + C;              // [C]VCVC... is m>1
61   var s_v   = "^(" + C + ")?" + v;                         // vowel in stem
62
63   this.stemWord = function (w) {
64     var stem;
65     var suffix;
66     var firstch;
67     var origword = w;
68
69     if (w.length < 3)
70       return w;
71
72     var re;
73     var re2;
74     var re3;
75     var re4;
76
77     firstch = w.substr(0,1);
78     if (firstch == "y")
79       w = firstch.toUpperCase() + w.substr(1);
80
81     // Step 1a
82     re = /^(.+?)(ss|i)es$/;
83     re2 = /^(.+?)([^s])s$/;
84
85     if (re.test(w))
86       w = w.replace(re,"$1$2");
87     else if (re2.test(w))
88       w = w.replace(re2,"$1$2");
89
90     // Step 1b
91     re = /^(.+?)eed$/;
92     re2 = /^(.+?)(ed|ing)$/;
93     if (re.test(w)) {
94       var fp = re.exec(w);
95       re = new RegExp(mgr0);
96       if (re.test(fp[1])) {
97         re = /.$/;
98         w = w.replace(re,"");
99       }
100     }
101     else if (re2.test(w)) {
102       var fp = re2.exec(w);
103       stem = fp[1];
104       re2 = new RegExp(s_v);
105       if (re2.test(stem)) {
106         w = stem;
107         re2 = /(at|bl|iz)$/;
108         re3 = new RegExp("([^aeiouylsz])\\1$");
109         re4 = new RegExp("^" + C + v + "[^aeiouwxy]$");
110         if (re2.test(w))
111           w = w + "e";
112         else if (re3.test(w)) {
113           re = /.$/;
114           w = w.replace(re,"");
115         }
116         else if (re4.test(w))
117           w = w + "e";
118       }
119     }
120
121     // Step 1c
122     re = /^(.+?)y$/;
123     if (re.test(w)) {
124       var fp = re.exec(w);
125       stem = fp[1];
126       re = new RegExp(s_v);
127       if (re.test(stem))
128         w = stem + "i";
129     }
130
131     // Step 2
132     re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;
133     if (re.test(w)) {
134       var fp = re.exec(w);
135       stem = fp[1];
136       suffix = fp[2];
137       re = new RegExp(mgr0);
138       if (re.test(stem))
139         w = stem + step2list[suffix];
140     }
141
142     // Step 3
143     re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;
144     if (re.test(w)) {
145       var fp = re.exec(w);
146       stem = fp[1];
147       suffix = fp[2];
148       re = new RegExp(mgr0);
149       if (re.test(stem))
150         w = stem + step3list[suffix];
151     }
152
153     // Step 4
154     re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;
155     re2 = /^(.+?)(s|t)(ion)$/;
156     if (re.test(w)) {
157       var fp = re.exec(w);
158       stem = fp[1];
159       re = new RegExp(mgr1);
160       if (re.test(stem))
161         w = stem;
162     }
163     else if (re2.test(w)) {
164       var fp = re2.exec(w);
165       stem = fp[1] + fp[2];
166       re2 = new RegExp(mgr1);
167       if (re2.test(stem))
168         w = stem;
169     }
170
171     // Step 5
172     re = /^(.+?)e$/;
173     if (re.test(w)) {
174       var fp = re.exec(w);
175       stem = fp[1];
176       re = new RegExp(mgr1);
177       re2 = new RegExp(meq1);
178       re3 = new RegExp("^" + C + v + "[^aeiouwxy]$");
179       if (re.test(stem) || (re2.test(stem) && !(re3.test(stem))))
180         w = stem;
181     }
182     re = /ll$/;
183     re2 = new RegExp(mgr1);
184     if (re.test(w) && re2.test(w)) {
185       re = /.$/;
186       w = w.replace(re,"");
187     }
188
189     // and turn initial Y back to y
190     if (firstch == "y")
191       w = firstch.toLowerCase() + w.substr(1);
192     return w;
193   }
194 }
195
196
197
198 /**
199  * Simple result scoring code.
200  */
201 var Scorer = {
202   // Implement the following function to further tweak the score for each result
203   // The function takes a result array [filename, title, anchor, descr, score]
204   // and returns the new score.
205   /*
206   score: function(result) {
207     return result[4];
208   },
209   */
210
211   // query matches the full name of an object
212   objNameMatch: 11,
213   // or matches in the last dotted part of the object name
214   objPartialMatch: 6,
215   // Additive scores depending on the priority of the object
216   objPrio: {0:  15,   // used to be importantResults
217             1:  5,   // used to be objectResults
218             2: -5},  // used to be unimportantResults
219   //  Used when the priority is not in the mapping.
220   objPrioDefault: 0,
221
222   // query found in title
223   title: 15,
224   // query found in terms
225   term: 5
226 };
227
228
229
230
231
232 var splitChars = (function() {
233     var result = {};
234     var singles = [96, 180, 187, 191, 215, 247, 749, 885, 903, 907, 909, 930, 1014, 1648,
235          1748, 1809, 2416, 2473, 2481, 2526, 2601, 2609, 2612, 2615, 2653, 2702,
236          2706, 2729, 2737, 2740, 2857, 2865, 2868, 2910, 2928, 2948, 2961, 2971,
237          2973, 3085, 3089, 3113, 3124, 3213, 3217, 3241, 3252, 3295, 3341, 3345,
238          3369, 3506, 3516, 3633, 3715, 3721, 3736, 3744, 3748, 3750, 3756, 3761,
239          3781, 3912, 4239, 4347, 4681, 4695, 4697, 4745, 4785, 4799, 4801, 4823,
240          4881, 5760, 5901, 5997, 6313, 7405, 8024, 8026, 8028, 8030, 8117, 8125,
241          8133, 8181, 8468, 8485, 8487, 8489, 8494, 8527, 11311, 11359, 11687, 11695,
242          11703, 11711, 11719, 11727, 11735, 12448, 12539, 43010, 43014, 43019, 43587,
243          43696, 43713, 64286, 64297, 64311, 64317, 64319, 64322, 64325, 65141];
244     var i, j, start, end;
245     for (i = 0; i < singles.length; i++) {
246         result[singles[i]] = true;
247     }
248     var ranges = [[0, 47], [58, 64], [91, 94], [123, 169], [171, 177], [182, 184], [706, 709],
249          [722, 735], [741, 747], [751, 879], [888, 889], [894, 901], [1154, 1161],
250          [1318, 1328], [1367, 1368], [1370, 1376], [1416, 1487], [1515, 1519], [1523, 1568],
251          [1611, 1631], [1642, 1645], [1750, 1764], [1767, 1773], [1789, 1790], [1792, 1807],
252          [1840, 1868], [1958, 1968], [1970, 1983], [2027, 2035], [2038, 2041], [2043, 2047],
253          [2070, 2073], [2075, 2083], [2085, 2087], [2089, 2307], [2362, 2364], [2366, 2383],
254          [2385, 2391], [2402, 2405], [2419, 2424], [2432, 2436], [2445, 2446], [2449, 2450],
255          [2483, 2485], [2490, 2492], [2494, 2509], [2511, 2523], [2530, 2533], [2546, 2547],
256          [2554, 2564], [2571, 2574], [2577, 2578], [2618, 2648], [2655, 2661], [2672, 2673],
257          [2677, 2692], [2746, 2748], [2750, 2767], [2769, 2783], [2786, 2789], [2800, 2820],
258          [2829, 2830], [2833, 2834], [2874, 2876], [2878, 2907], [2914, 2917], [2930, 2946],
259          [2955, 2957], [2966, 2968], [2976, 2978], [2981, 2983], [2987, 2989], [3002, 3023],
260          [3025, 3045], [3059, 3076], [3130, 3132], [3134, 3159], [3162, 3167], [3170, 3173],
261          [3184, 3191], [3199, 3204], [3258, 3260], [3262, 3293], [3298, 3301], [3312, 3332],
262          [3386, 3388], [3390, 3423], [3426, 3429], [3446, 3449], [3456, 3460], [3479, 3481],
263          [3518, 3519], [3527, 3584], [3636, 3647], [3655, 3663], [3674, 3712], [3717, 3718],
264          [3723, 3724], [3726, 3731], [3752, 3753], [3764, 3772], [3774, 3775], [3783, 3791],
265          [3802, 3803], [3806, 3839], [3841, 3871], [3892, 3903], [3949, 3975], [3980, 4095],
266          [4139, 4158], [4170, 4175], [4182, 4185], [4190, 4192], [4194, 4196], [4199, 4205],
267          [4209, 4212], [4226, 4237], [4250, 4255], [4294, 4303], [4349, 4351], [4686, 4687],
268          [4702, 4703], [4750, 4751], [4790, 4791], [4806, 4807], [4886, 4887], [4955, 4968],
269          [4989, 4991], [5008, 5023], [5109, 5120], [5741, 5742], [5787, 5791], [5867, 5869],
270          [5873, 5887], [5906, 5919], [5938, 5951], [5970, 5983], [6001, 6015], [6068, 6102],
271          [6104, 6107], [6109, 6111], [6122, 6127], [6138, 6159], [6170, 6175], [6264, 6271],
272          [6315, 6319], [6390, 6399], [6429, 6469], [6510, 6511], [6517, 6527], [6572, 6592],
273          [6600, 6607], [6619, 6655], [6679, 6687], [6741, 6783], [6794, 6799], [6810, 6822],
274          [6824, 6916], [6964, 6980], [6988, 6991], [7002, 7042], [7073, 7085], [7098, 7167],
275          [7204, 7231], [7242, 7244], [7294, 7400], [7410, 7423], [7616, 7679], [7958, 7959],
276          [7966, 7967], [8006, 8007], [8014, 8015], [8062, 8063], [8127, 8129], [8141, 8143],
277          [8148, 8149], [8156, 8159], [8173, 8177], [8189, 8303], [8306, 8307], [8314, 8318],
278          [8330, 8335], [8341, 8449], [8451, 8454], [8456, 8457], [8470, 8472], [8478, 8483],
279          [8506, 8507], [8512, 8516], [8522, 8525], [8586, 9311], [9372, 9449], [9472, 10101],
280          [10132, 11263], [11493, 11498], [11503, 11516], [11518, 11519], [11558, 11567],
281          [11622, 11630], [11632, 11647], [11671, 11679], [11743, 11822], [11824, 12292],
282          [12296, 12320], [12330, 12336], [12342, 12343], [12349, 12352], [12439, 12444],
283          [12544, 12548], [12590, 12592], [12687, 12689], [12694, 12703], [12728, 12783],
284          [12800, 12831], [12842, 12880], [12896, 12927], [12938, 12976], [12992, 13311],
285          [19894, 19967], [40908, 40959], [42125, 42191], [42238, 42239], [42509, 42511],
286          [42540, 42559], [42592, 42593], [42607, 42622], [42648, 42655], [42736, 42774],
287          [42784, 42785], [42889, 42890], [42893, 43002], [43043, 43055], [43062, 43071],
288          [43124, 43137], [43188, 43215], [43226, 43249], [43256, 43258], [43260, 43263],
289          [43302, 43311], [43335, 43359], [43389, 43395], [43443, 43470], [43482, 43519],
290          [43561, 43583], [43596, 43599], [43610, 43615], [43639, 43641], [43643, 43647],
291          [43698, 43700], [43703, 43704], [43710, 43711], [43715, 43738], [43742, 43967],
292          [44003, 44015], [44026, 44031], [55204, 55215], [55239, 55242], [55292, 55295],
293          [57344, 63743], [64046, 64047], [64110, 64111], [64218, 64255], [64263, 64274],
294          [64280, 64284], [64434, 64466], [64830, 64847], [64912, 64913], [64968, 65007],
295          [65020, 65135], [65277, 65295], [65306, 65312], [65339, 65344], [65371, 65381],
296          [65471, 65473], [65480, 65481], [65488, 65489], [65496, 65497]];
297     for (i = 0; i < ranges.length; i++) {
298         start = ranges[i][0];
299         end = ranges[i][1];
300         for (j = start; j <= end; j++) {
301             result[j] = true;
302         }
303     }
304     return result;
305 })();
306
307 function splitQuery(query) {
308     var result = [];
309     var start = -1;
310     for (var i = 0; i < query.length; i++) {
311         if (splitChars[query.charCodeAt(i)]) {
312             if (start !== -1) {
313                 result.push(query.slice(start, i));
314                 start = -1;
315             }
316         } else if (start === -1) {
317             start = i;
318         }
319     }
320     if (start !== -1) {
321         result.push(query.slice(start));
322     }
323     return result;
324 }
325
326
327
328
329 /**
330  * Search Module
331  */
332 var Search = {
333
334   _index : null,
335   _queued_query : null,
336   _pulse_status : -1,
337
338   init : function() {
339       var params = $.getQueryParameters();
340       if (params.q) {
341           var query = params.q[0];
342           $('input[name="q"]')[0].value = query;
343           this.performSearch(query);
344       }
345   },
346
347   loadIndex : function(url) {
348     $.ajax({type: "GET", url: url, data: null,
349             dataType: "script", cache: true,
350             complete: function(jqxhr, textstatus) {
351               if (textstatus != "success") {
352                 document.getElementById("searchindexloader").src = url;
353               }
354             }});
355   },
356
357   setIndex : function(index) {
358     var q;
359     this._index = index;
360     if ((q = this._queued_query) !== null) {
361       this._queued_query = null;
362       Search.query(q);
363     }
364   },
365
366   hasIndex : function() {
367       return this._index !== null;
368   },
369
370   deferQuery : function(query) {
371       this._queued_query = query;
372   },
373
374   stopPulse : function() {
375       this._pulse_status = 0;
376   },
377
378   startPulse : function() {
379     if (this._pulse_status >= 0)
380         return;
381     function pulse() {
382       var i;
383       Search._pulse_status = (Search._pulse_status + 1) % 4;
384       var dotString = '';
385       for (i = 0; i < Search._pulse_status; i++)
386         dotString += '.';
387       Search.dots.text(dotString);
388       if (Search._pulse_status > -1)
389         window.setTimeout(pulse, 500);
390     }
391     pulse();
392   },
393
394   /**
395    * perform a search for something (or wait until index is loaded)
396    */
397   performSearch : function(query) {
398     // create the required interface elements
399     this.out = $('#search-results');
400     this.title = $('<h2>' + _('Searching') + '</h2>').appendTo(this.out);
401     this.dots = $('<span></span>').appendTo(this.title);
402     this.status = $('<p style="display: none"></p>').appendTo(this.out);
403     this.output = $('<ul class="search"/>').appendTo(this.out);
404
405     $('#search-progress').text(_('Preparing search...'));
406     this.startPulse();
407
408     // index already loaded, the browser was quick!
409     if (this.hasIndex())
410       this.query(query);
411     else
412       this.deferQuery(query);
413   },
414
415   /**
416    * execute search (requires search index to be loaded)
417    */
418   query : function(query) {
419     var i;
420     var 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"];
421
422     // stem the searchterms and add them to the correct list
423     var stemmer = new Stemmer();
424     var searchterms = [];
425     var excluded = [];
426     var hlterms = [];
427     var tmp = splitQuery(query);
428     var objectterms = [];
429     for (i = 0; i < tmp.length; i++) {
430       if (tmp[i] !== "") {
431           objectterms.push(tmp[i].toLowerCase());
432       }
433
434       if ($u.indexOf(stopwords, tmp[i].toLowerCase()) != -1 || tmp[i].match(/^\d+$/) ||
435           tmp[i] === "") {
436         // skip this "word"
437         continue;
438       }
439       // stem the word
440       var word = stemmer.stemWord(tmp[i].toLowerCase());
441       // prevent stemmer from cutting word smaller than two chars
442       if(word.length < 3 && tmp[i].length >= 3) {
443         word = tmp[i];
444       }
445       var toAppend;
446       // select the correct list
447       if (word[0] == '-') {
448         toAppend = excluded;
449         word = word.substr(1);
450       }
451       else {
452         toAppend = searchterms;
453         hlterms.push(tmp[i].toLowerCase());
454       }
455       // only add if not already in the list
456       if (!$u.contains(toAppend, word))
457         toAppend.push(word);
458     }
459     var highlightstring = '?highlight=' + $.urlencode(hlterms.join(" "));
460
461     // console.debug('SEARCH: searching for:');
462     // console.info('required: ', searchterms);
463     // console.info('excluded: ', excluded);
464
465     // prepare search
466     var terms = this._index.terms;
467     var titleterms = this._index.titleterms;
468
469     // array of [filename, title, anchor, descr, score]
470     var results = [];
471     $('#search-progress').empty();
472
473     // lookup as object
474     for (i = 0; i < objectterms.length; i++) {
475       var others = [].concat(objectterms.slice(0, i),
476                              objectterms.slice(i+1, objectterms.length));
477       results = results.concat(this.performObjectSearch(objectterms[i], others));
478     }
479
480     // lookup as search terms in fulltext
481     results = results.concat(this.performTermsSearch(searchterms, excluded, terms, titleterms));
482
483     // let the scorer override scores with a custom scoring function
484     if (Scorer.score) {
485       for (i = 0; i < results.length; i++)
486         results[i][4] = Scorer.score(results[i]);
487     }
488
489     // now sort the results by score (in opposite order of appearance, since the
490     // display function below uses pop() to retrieve items) and then
491     // alphabetically
492     results.sort(function(a, b) {
493       var left = a[4];
494       var right = b[4];
495       if (left > right) {
496         return 1;
497       } else if (left < right) {
498         return -1;
499       } else {
500         // same score: sort alphabetically
501         left = a[1].toLowerCase();
502         right = b[1].toLowerCase();
503         return (left > right) ? -1 : ((left < right) ? 1 : 0);
504       }
505     });
506
507     // for debugging
508     //Search.lastresults = results.slice();  // a copy
509     //console.info('search results:', Search.lastresults);
510
511     // print the results
512     var resultCount = results.length;
513     function displayNextItem() {
514       // results left, load the summary and display it
515       if (results.length) {
516         var item = results.pop();
517         var listItem = $('<li style="display:none"></li>');
518         if (DOCUMENTATION_OPTIONS.FILE_SUFFIX === '') {
519           // dirhtml builder
520           var dirname = item[0] + '/';
521           if (dirname.match(/\/index\/$/)) {
522             dirname = dirname.substring(0, dirname.length-6);
523           } else if (dirname == 'index/') {
524             dirname = '';
525           }
526           listItem.append($('<a/>').attr('href',
527             DOCUMENTATION_OPTIONS.URL_ROOT + dirname +
528             highlightstring + item[2]).html(item[1]));
529         } else {
530           // normal html builders
531           listItem.append($('<a/>').attr('href',
532             item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX +
533             highlightstring + item[2]).html(item[1]));
534         }
535         if (item[3]) {
536           listItem.append($('<span> (' + item[3] + ')</span>'));
537           Search.output.append(listItem);
538           listItem.slideDown(5, function() {
539             displayNextItem();
540           });
541         } else if (DOCUMENTATION_OPTIONS.HAS_SOURCE) {
542           var suffix = DOCUMENTATION_OPTIONS.SOURCELINK_SUFFIX;
543           if (suffix === undefined) {
544             suffix = '.txt';
545           }
546           $.ajax({url: DOCUMENTATION_OPTIONS.URL_ROOT + '_sources/' + item[5] + (item[5].slice(-suffix.length) === suffix ? '' : suffix),
547                   dataType: "text",
548                   complete: function(jqxhr, textstatus) {
549                     var data = jqxhr.responseText;
550                     if (data !== '' && data !== undefined) {
551                       listItem.append(Search.makeSearchSummary(data, searchterms, hlterms));
552                     }
553                     Search.output.append(listItem);
554                     listItem.slideDown(5, function() {
555                       displayNextItem();
556                     });
557                   }});
558         } else {
559           // no source available, just display title
560           Search.output.append(listItem);
561           listItem.slideDown(5, function() {
562             displayNextItem();
563           });
564         }
565       }
566       // search finished, update title and status message
567       else {
568         Search.stopPulse();
569         Search.title.text(_('Search Results'));
570         if (!resultCount)
571           Search.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.'));
572         else
573             Search.status.text(_('Search finished, found %s page(s) matching the search query.').replace('%s', resultCount));
574         Search.status.fadeIn(500);
575       }
576     }
577     displayNextItem();
578   },
579
580   /**
581    * search for object names
582    */
583   performObjectSearch : function(object, otherterms) {
584     var filenames = this._index.filenames;
585     var docnames = this._index.docnames;
586     var objects = this._index.objects;
587     var objnames = this._index.objnames;
588     var titles = this._index.titles;
589
590     var i;
591     var results = [];
592
593     for (var prefix in objects) {
594       for (var name in objects[prefix]) {
595         var fullname = (prefix ? prefix + '.' : '') + name;
596         if (fullname.toLowerCase().indexOf(object) > -1) {
597           var score = 0;
598           var parts = fullname.split('.');
599           // check for different match types: exact matches of full name or
600           // "last name" (i.e. last dotted part)
601           if (fullname == object || parts[parts.length - 1] == object) {
602             score += Scorer.objNameMatch;
603           // matches in last name
604           } else if (parts[parts.length - 1].indexOf(object) > -1) {
605             score += Scorer.objPartialMatch;
606           }
607           var match = objects[prefix][name];
608           var objname = objnames[match[1]][2];
609           var title = titles[match[0]];
610           // If more than one term searched for, we require other words to be
611           // found in the name/title/description
612           if (otherterms.length > 0) {
613             var haystack = (prefix + ' ' + name + ' ' +
614                             objname + ' ' + title).toLowerCase();
615             var allfound = true;
616             for (i = 0; i < otherterms.length; i++) {
617               if (haystack.indexOf(otherterms[i]) == -1) {
618                 allfound = false;
619                 break;
620               }
621             }
622             if (!allfound) {
623               continue;
624             }
625           }
626           var descr = objname + _(', in ') + title;
627
628           var anchor = match[3];
629           if (anchor === '')
630             anchor = fullname;
631           else if (anchor == '-')
632             anchor = objnames[match[1]][1] + '-' + fullname;
633           // add custom score for some objects according to scorer
634           if (Scorer.objPrio.hasOwnProperty(match[2])) {
635             score += Scorer.objPrio[match[2]];
636           } else {
637             score += Scorer.objPrioDefault;
638           }
639           results.push([docnames[match[0]], fullname, '#'+anchor, descr, score, filenames[match[0]]]);
640         }
641       }
642     }
643
644     return results;
645   },
646
647   /**
648    * search for full-text terms in the index
649    */
650   performTermsSearch : function(searchterms, excluded, terms, titleterms) {
651     var docnames = this._index.docnames;
652     var filenames = this._index.filenames;
653     var titles = this._index.titles;
654
655     var i, j, file;
656     var fileMap = {};
657     var scoreMap = {};
658     var results = [];
659
660     // perform the search on the required terms
661     for (i = 0; i < searchterms.length; i++) {
662       var word = searchterms[i];
663       var files = [];
664       var _o = [
665         {files: terms[word], score: Scorer.term},
666         {files: titleterms[word], score: Scorer.title}
667       ];
668
669       // no match but word was a required one
670       if ($u.every(_o, function(o){return o.files === undefined;})) {
671         break;
672       }
673       // found search word in contents
674       $u.each(_o, function(o) {
675         var _files = o.files;
676         if (_files === undefined)
677           return
678
679         if (_files.length === undefined)
680           _files = [_files];
681         files = files.concat(_files);
682
683         // set score for the word in each file to Scorer.term
684         for (j = 0; j < _files.length; j++) {
685           file = _files[j];
686           if (!(file in scoreMap))
687             scoreMap[file] = {}
688           scoreMap[file][word] = o.score;
689         }
690       });
691
692       // create the mapping
693       for (j = 0; j < files.length; j++) {
694         file = files[j];
695         if (file in fileMap)
696           fileMap[file].push(word);
697         else
698           fileMap[file] = [word];
699       }
700     }
701
702     // now check if the files don't contain excluded terms
703     for (file in fileMap) {
704       var valid = true;
705
706       // check if all requirements are matched
707       if (fileMap[file].length != searchterms.length)
708           continue;
709
710       // ensure that none of the excluded terms is in the search result
711       for (i = 0; i < excluded.length; i++) {
712         if (terms[excluded[i]] == file ||
713             titleterms[excluded[i]] == file ||
714             $u.contains(terms[excluded[i]] || [], file) ||
715             $u.contains(titleterms[excluded[i]] || [], file)) {
716           valid = false;
717           break;
718         }
719       }
720
721       // if we have still a valid result we can add it to the result list
722       if (valid) {
723         // select one (max) score for the file.
724         // for better ranking, we should calculate ranking by using words statistics like basic tf-idf...
725         var score = $u.max($u.map(fileMap[file], function(w){return scoreMap[file][w]}));
726         results.push([docnames[file], titles[file], '', null, score, filenames[file]]);
727       }
728     }
729     return results;
730   },
731
732   /**
733    * helper function to return a node containing the
734    * search summary for a given text. keywords is a list
735    * of stemmed words, hlwords is the list of normal, unstemmed
736    * words. the first one is used to find the occurrence, the
737    * latter for highlighting it.
738    */
739   makeSearchSummary : function(text, keywords, hlwords) {
740     var textLower = text.toLowerCase();
741     var start = 0;
742     $.each(keywords, function() {
743       var i = textLower.indexOf(this.toLowerCase());
744       if (i > -1)
745         start = i;
746     });
747     start = Math.max(start - 120, 0);
748     var excerpt = ((start > 0) ? '...' : '') +
749       $.trim(text.substr(start, 240)) +
750       ((start + 240 - text.length) ? '...' : '');
751     var rv = $('<div class="context"></div>').text(excerpt);
752     $.each(hlwords, function() {
753       rv = rv.highlightText(this, 'highlighted');
754     });
755     return rv;
756   }
757 };
758
759 $(document).ready(function() {
760   Search.init();
761 });