mirror of
https://github.com/McShelby/hugo-theme-relearn.git
synced 2024-11-30 11:13:06 +00:00
136 lines
3.6 KiB
JavaScript
136 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 };
|