var runSearch = function(json_data, posts_data) {
// Bolds the keywords in the preview string function highlightKeywords(content, previewStartPosition, matchMetadata) { var previewSize = 300; var matchMap = {}; // Create an object containing search hit position and length of search hit in the document (for content within preview) for (keyword in matchMetadata) { var positionArray; if (!matchMetadata[keyword]['content']) { return; } positionArray = matchMetadata[keyword]['content']['position']; for (var positionIndex = 0; positionIndex < positionArray.length; positionIndex++) { var hitPosition = positionArray[positionIndex][0]; if ((hitPosition >= previewStartPosition) && (hitPosition < previewStartPosition+previewSize)) { matchMap[hitPosition] = positionArray[positionIndex][1]; } } } // Go through each search hit and bold it if (Object.keys(matchMap).length !== 0) { var processedPreview = ''; var currPosition = previewStartPosition; for (wordPosition in matchMap) { var wordEnd = parseInt(wordPosition) + parseInt(matchMap[wordPosition]) + 1; processedPreview += content.substring(currPosition, wordPosition) + '<b>' + content.substring(wordPosition, wordEnd) + '</b>'; currPosition = wordEnd; } if (wordEnd < previewStartPosition+previewSize) { processedPreview += content.substring(currPosition, previewStartPosition+previewSize); } return processedPreview; } return content.substring(previewStartPosition, previewStartPosition+previewSize); } // Find the earliest space in the preview closest to (firstPosition - numLeadingChars) function returnStartOfPreview(content, firstPosition) { var numLeadingChars = 30; if (firstPosition-numLeadingChars <= 0) { return 0; } else { for (var index = firstPosition-numLeadingChars; index < firstPosition; index++) { if (content.charAt(index) === ' ') { return index; } } return firstPosition; } } // Find the position of the first keyword match in the document function returnFirstKeywordPosition(matchMetadata) { var firstPosition = -1; // Iterate over each keyword in the search query for (keyword in matchMetadata) { if (matchMetadata[keyword]['content'] !== undefined) { var positionArray = matchMetadata[keyword]['content']['position']; // Find the earliest first position across all keywords for (var positionIndex = 0; positionIndex < positionArray.length; positionIndex++) { if (firstPosition == -1 || (firstPosition > positionArray[positionIndex][0])) { firstPosition = positionArray[positionIndex][0]; } } } } return firstPosition; } // Return the preview content for each search result - returns the snippet that has the first hit in the document (up to 300 chars) function returnResultsList(results) { var searchPara = ''; var post_data = posts_data; // Obtain JSON var of all the posts in the site // Iterate over the results for (var i = 0; i < results.length; i++) { var key = parseInt(results[i]['ref']); var resultObject = post_data[key]; var matchMetadata = results[i]['matchData']['metadata']; var keywordSet = new Set(); var titleTruncateLength = 90; var resultTitle = resultObject['title'].substring(0, titleTruncateLength); if (resultObject['title'].length > titleTruncateLength) { var indexOfLastWord = resultObject['title'].substring(0,titleTruncateLength).lastIndexOf(" "); var resultTitle = resultObject['title'].substring(0, indexOfLastWord); resultTitle += ' ...'; } searchPara += '<a class="search-content" href="' + resultObject['url'] + '">' + ' ' + resultTitle + '</a>'; // Find the position of the earliest keyword in the document var firstPosition = returnFirstKeywordPosition(matchMetadata); // Find the preview start position var previewStartPosition = returnStartOfPreview(resultObject['content'], firstPosition); // Process the preview to embolden keywords var processedPreview = highlightKeywords(resultObject['content'], previewStartPosition, matchMetadata); // var postDate = new Date(resultObject['datestring']).toDateString().substring(4); searchPara += '<p class="search-content permalink">' + resultObject['url'] + '</p><br>'; // searchPara += '<p class="search-content" > '+ postDate + ' ...' + processedPreview + '...</p><br>'; if (processedPreview) { searchPara += '<p class="search-content" > ' + ' ...' + processedPreview + '...</p><br>'; } } return searchPara; } // Display search results if there are results, else, state that there are no results found function displaySearchResults(results, searchTerm) { var searchResults = document.getElementById('search-results'); var searchResultsCount = document.getElementById('search-results-count'); // document.getElementById('search-bar').setAttribute("value", searchTerm); document.getElementsByName('query')[1].setAttribute("value", searchTerm); searchResultsCount.innerHTML = results.length + " results for '" + searchTerm + "'"; if (results.length) { // If there are results searchResults.innerHTML = returnResultsList(results); } else { searchResults.innerHTML = ''; } } // Obtain the query string, load the pre-built lunr index, and perform search function getQueryVariable(variable) { var query = window.location.search.substring(1); var vars = query.split('&'); for (var i = 0; i < vars.length; i++) { var pair = vars[i].split('='); if (pair[0] === variable) { return decodeURIComponent(pair[1].replace(/\+/g, '%20')); } } } var searchTerm = getQueryVariable('query'); if (searchTerm) { // Load the pre-built lunr index var idx = lunr.Index.load(JSON.parse(json_data)); // Get lunr to perform a search var results = idx.search(searchTerm); window.onload = displaySearchResults(results, searchTerm); }
};