mirror of
https://github.com/McShelby/hugo-theme-relearn.git
synced 2024-11-27 01:33:04 +00:00
137 lines
3.6 KiB
JavaScript
137 lines
3.6 KiB
JavaScript
|
/*
|
||
|
|
||
|
# Adapter Interface
|
||
|
|
||
|
The search adapter needs to provide the following functions that are called from search.js
|
||
|
|
||
|
## init()
|
||
|
|
||
|
Initialize the search engine and the search index
|
||
|
|
||
|
### Parameters
|
||
|
|
||
|
none
|
||
|
|
||
|
### Returns
|
||
|
|
||
|
none
|
||
|
|
||
|
### Remarks
|
||
|
|
||
|
Once successfully completed, needs to call
|
||
|
|
||
|
````
|
||
|
window.relearn.isSearchEngineReady = true;
|
||
|
window.relearn.executeInitialSearch();
|
||
|
````
|
||
|
|
||
|
## search()
|
||
|
|
||
|
Performs the search and returs found results.
|
||
|
|
||
|
### Parameters
|
||
|
|
||
|
term: string // the search term that was typed in by the user
|
||
|
|
||
|
### Returns
|
||
|
|
||
|
Must return an array of found pages, sorted with the most relevant page first.
|
||
|
|
||
|
Each array item needs the following layout:
|
||
|
|
||
|
````
|
||
|
{
|
||
|
index: string, // optional, id of the page in the search index
|
||
|
matches: string[], // optional, TODO: have to find out what it does
|
||
|
page: {
|
||
|
breadcrumb: string,
|
||
|
title: string,
|
||
|
uri: string,
|
||
|
content: string,
|
||
|
tags: string[]
|
||
|
}
|
||
|
}
|
||
|
````
|
||
|
*/
|
||
|
|
||
|
let lunrIndex, pagesIndex;
|
||
|
|
||
|
function init() {
|
||
|
function initLunrIndex( index ){
|
||
|
pagesIndex = index;
|
||
|
// Set up Lunr by declaring the fields we use
|
||
|
// Also provide their boost level for the ranking
|
||
|
lunrIndex = lunr(function() {
|
||
|
this.use(lunr.multiLanguage.apply(null, contentLangs));
|
||
|
this.ref('index');
|
||
|
this.field('title', {
|
||
|
boost: 15
|
||
|
});
|
||
|
this.field('tags', {
|
||
|
boost: 10
|
||
|
});
|
||
|
this.field('content', {
|
||
|
boost: 5
|
||
|
});
|
||
|
|
||
|
this.pipeline.remove(lunr.stemmer);
|
||
|
this.searchPipeline.remove(lunr.stemmer);
|
||
|
|
||
|
// Feed Lunr with each file and let index them
|
||
|
pagesIndex.forEach(function(page, idx) {
|
||
|
page.index = idx;
|
||
|
this.add(page);
|
||
|
}, this);
|
||
|
});
|
||
|
|
||
|
window.relearn.isSearchEngineReady = true;
|
||
|
window.relearn.executeInitialSearch();
|
||
|
}
|
||
|
|
||
|
if( window.index_js_url ){
|
||
|
var js = document.createElement("script");
|
||
|
js.src = index_js_url;
|
||
|
js.setAttribute("async", "");
|
||
|
js.onload = function(){
|
||
|
initLunrIndex(relearn_searchindex);
|
||
|
};
|
||
|
js.onerror = function(e){
|
||
|
console.error('Error getting Hugo index file');
|
||
|
};
|
||
|
document.head.appendChild(js);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function search(term) {
|
||
|
function searchPatterns(word) {
|
||
|
// for short words high amounts of typos doesn't make sense
|
||
|
// for long words we allow less typos because this largly increases search time
|
||
|
var typos = [
|
||
|
{ len: -1, typos: 1 },
|
||
|
{ len: 60, typos: 2 },
|
||
|
{ len: 40, typos: 3 },
|
||
|
{ len: 20, typos: 4 },
|
||
|
{ len: 16, typos: 3 },
|
||
|
{ len: 12, typos: 2 },
|
||
|
{ len: 8, typos: 1 },
|
||
|
{ len: 4, typos: 0 },
|
||
|
];
|
||
|
return [
|
||
|
word + '^100',
|
||
|
word + '*^10',
|
||
|
'*' + word + '^10',
|
||
|
word + '~' + typos.reduce( function( a, c, i ){ return word.length < c.len ? c : a; } ).typos + '^1'
|
||
|
];
|
||
|
}
|
||
|
|
||
|
// Find the item in our index corresponding to the Lunr one to have more info
|
||
|
// Remove Lunr special search characters: https://lunrjs.com/guides/searching.html
|
||
|
term = term.replace( /[*:^~+-]/g, ' ' );
|
||
|
var searchTerm = lunr.tokenizer( term ).reduce( function(a,token){return a.concat(searchPatterns(token.str))}, []).join(' ');
|
||
|
return !searchTerm || !lunrIndex ? [] : lunrIndex.search(searchTerm).map(function(result) {
|
||
|
return { index: result.ref, matches: Object.keys(result.matchData.metadata), page: pagesIndex[ result.ref ] };
|
||
|
});
|
||
|
}
|
||
|
|
||
|
export { init, search };
|