summaryInclude = 200; var fuseOptions = { shouldSort: true, includeMatches: true, threshold: 0.0, tokenize: true, location: 0, distance: 100, maxPatternLength: 32, minMatchCharLength: 3, includeScore: true, isCaseSensitive: false, keys: [{ name: "title", weight: 0.6 }, { name: "contents", weight: 0.3 }, { name: "tags", weight: 0.05 }, { name: "categories", weight: 0.05 } ] }; var searchQuery = param("s"); if (searchQuery) { $("#search-form-wrapper").removeClass("add-margin-top-search-form"); $("#search-query").val(searchQuery); executeSearch(searchQuery); } else { $("#search-form-wrapper").addClass("add-margin-top-search-form"); } function executeSearch(searchQuery) { $("#loading-icon").fadeIn(); $.getJSON("/index.json?t=" + $("#search-db-version").text(), function (data) { var pages = data; var fuse = new Fuse(pages, fuseOptions); var result = fuse.search(searchQuery); $("#loading-icon").hide(); if (result.length > 0) { populateResults(result); } else { $('#search-results').append("
No matches found
"); } }); } function populateResults(result) { $.each(result, function (key, value) { var contents = value.item.contents; var snippet = ""; var snippetHighlights = []; var tags = []; if (fuseOptions.tokenize) { snippetHighlights.push(searchQuery); } 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 templateDefinition = $('#search-result-template').html(); //replace values var output = render(templateDefinition, { key: key, title: value.item.title, link: value.item.permalink, tags: value.item.tags, categories: value.item.categories, snippet: snippet, score: value.score }); $('#search-results').append(output); $.each(snippetHighlights, function (snipkey, snipvalue) { $("#summary-" + key).mark(snipvalue); }); }); } function param(name) { return decodeURIComponent((location.search.split(name + '=')[1] || '').split('&')[0]).replace(/\+/g, ' '); } 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; }