summaryInclude = 60; var fuseOptions = { shouldSort: true, includeMatches: true, threshold: 0.0, tokenize: true, location: 0, distance: 100, maxPatternLength: 32, minMatchCharLength: 1, keys: [ { name: "title", weight: 0.8 }, { name: "contents", weight: 0.5 }, { name: "tags", weight: 0.3 }, { name: "categories", weight: 0.3 } ] }; var query = param("s"); if (query) { $("#search-query").val(query); search(query); } function search(query) { $.getJSON("/index.json", function (data) { var pages = data; var fuse = new Fuse(pages, fuseOptions); var result = fuse.search(query); if (result.length > 0) { results(result); } else { $('#search-results').append("

No matches found

"); } }); } function results(result) { $.each(result, function (key, value) { var contents = value.item.contents; var snippet = ""; var snippetHighlights = []; var tags = []; if (fuseOptions.tokenize) { snippetHighlights.push(query); } else { $.each(value.matches, function (matchKey, mvalue) { if (mvalue.key == "tags" || mvalue.key == "categories") { snippetHighlights.push(mvalue.value); } else if (mvalue.key == "contents") { start = mvalue.indices[0][0] - summaryInclude > 0 ? mvalue.indices[0][0] - summaryInclude : 0; end = mvalue.indices[0][1] + summaryInclude < contents.length ? mvalue.indices[0][1] + summaryInclude : contents.length; snippet += contents.substring(start, end); snippetHighlights.push(mvalue.value.substring(mvalue.indices[0][0], mvalue.indices[0][1] - mvalue.indices[0][0] + 1)); } }); } if (snippet.length < 1) { snippet += contents.substring(0, summaryInclude * 2); } //pull template from hugo templarte definition var tpl = $('#search-result-template').html(); //replace values var output = render(tpl, { key: key, title: value.item.title, link: value.item.permalink, tags: value.item.tags, categories: value.item.categories, snippet: snippet }); $('#search-results').append(output); $.each(snippetHighlights, function (snipkey, snipvalue) { $("#summary-" + key).mark(snipvalue); }); }); } function render(templateString, data) { var conditionalMatches, conditionalPattern, copy; conditionalPattern = /\$\{\s*isset ([a-zA-Z]*) \s*\}(.*)\$\{\s*end\s*}/g; //since loop below depends on re.lastInxdex, we use a copy to capture any manipulations whilst inside the loop copy = templateString; while ((conditionalMatches = conditionalPattern.exec(templateString)) !== null) { if (data[conditionalMatches[1]]) { //valid key, remove conditionals, leave contents. copy = copy.replace(conditionalMatches[0], conditionalMatches[2]); } else { //not valid, remove entire section copy = copy.replace(conditionalMatches[0], ''); } } templateString = copy; //now any conditionals removed we can do simple substitution var key, find, re; for (key in data) { find = '\\$\\{\\s*' + key + '\\s*\\}'; re = new RegExp(find, 'g'); templateString = templateString.replace(re, data[key]); } return templateString; } function param(name) { return decodeURIComponent((location.search.split(name + '=')[1] || '').split('&')[0]).replace(/\+/g, ' '); }