From d409ccb0cc1632b19ff8b13dc2026cc0167e600f Mon Sep 17 00:00:00 2001 From: matsuyoshi Date: Sat, 23 Oct 2021 22:00:22 +0900 Subject: Add flexsearch --- assets/js/flexsearch.bundle.js | 33 +++++++++++++++++++++++++++++++++ package-lock.json | 5 +++++ package.json | 1 + 3 files changed, 39 insertions(+) create mode 100644 assets/js/flexsearch.bundle.js diff --git a/assets/js/flexsearch.bundle.js b/assets/js/flexsearch.bundle.js new file mode 100644 index 0000000..71986df --- /dev/null +++ b/assets/js/flexsearch.bundle.js @@ -0,0 +1,33 @@ +/**! + * FlexSearch.js v0.7.21 (Bundle) + * Copyright 2018-2021 Nextapps GmbH + * Author: Thomas Wilkerling + * Licence: Apache-2.0 + * https://github.com/nextapps-de/flexsearch + */ +(function _f(self){'use strict';try{if(module)self=module}catch(e){}self._factory=_f;var t;function u(a){return"undefined"!==typeof a?a:!0}function aa(a){const b=Array(a);for(let c=0;c=this.B&&(w||!n[l])){var f=L(q,d,r),g="";switch(this.G){case "full":if(3f;h--)if(h-f>=this.B){var k=L(q,d,r,e,f);g=l.substring(f,h);M(this,n,g,k,a,c)}break}case "reverse":if(2=this.B&&M(this,n, +g,L(q,d,r,e,h),a,c);g=""}case "forward":if(1=this.B&&M(this,n,g,f,a,c);break}default:if(this.C&&(f=Math.min(f/this.C(b,l,r)|0,q-1)),M(this,n,l,f,a,c),w&&1=this.B&&!e[l]){e[l]=1;const p=this.l&&l>f;M(this,m,p?f:l,L(g+(d/2>g?0:1),d,r,h-1,k-1),a,c,p?l:f)}}}}this.m||(this.register[a]=1)}}return this}; +function L(a,b,c,d,e){return c&&1=this.B&&!c[q])if(this.s||f||this.map[q])k[w++]=q,c[q]=1;else return d;a=k;e=a.length}if(!e)return d;b||(b=100);h=this.depth&&1=d)))break;if(n){if(f)return ta(k,d,0);b[b.length]=k;return}}return!c&&k}function ta(a,b,c){a=1===a.length?a[0]:[].concat.apply([],a);return c||a.length>b?a.slice(c,c+b):a} +function ua(a,b,c,d){c?(d=d&&b>c,a=(a=a[d?b:c])&&a[d?c:b]):a=a[b];return a}t.contain=function(a){return!!this.register[a]};t.update=function(a,b){return this.remove(a).add(a,b)}; +t.remove=function(a,b){const c=this.register[a];if(c){if(this.m)for(let d=0,e;db||c)e=e.slice(c,c+b);d&&(e=za.call(this,e));return{tag:a,result:e}}}function za(a){const b=Array(a.length);for(let c=0,d;c Date: Sat, 23 Oct 2021 22:43:03 +0900 Subject: Add id to list.json --- layouts/_default/list.json | 1 + 1 file changed, 1 insertion(+) diff --git a/layouts/_default/list.json b/layouts/_default/list.json index 65d080a..618a67a 100644 --- a/layouts/_default/list.json +++ b/layouts/_default/list.json @@ -3,6 +3,7 @@ {{ if eq .Type "post" }} {{ if ne $index 0 }},{{ end }} { + "id": $index, "ref": "{{ $page.Permalink }}", "title": {{ $page.Title | jsonify }}, "section": "{{ $page.Section }}", -- cgit v1.2.3 From cf57c0b9af813fadb3c4362d5a4f2bc50b8cc3f4 Mon Sep 17 00:00:00 2001 From: matsuyoshi Date: Sun, 24 Oct 2021 01:01:49 +0900 Subject: replace lunr with flexsearch --- assets/js/search.js | 154 +++++++++++++++------------------------------ assets/list.json | 15 +++++ layouts/_default/list.json | 15 ----- layouts/partials/head.html | 7 ++- 4 files changed, 72 insertions(+), 119 deletions(-) create mode 100644 assets/list.json delete mode 100644 layouts/_default/list.json diff --git a/assets/js/search.js b/assets/js/search.js index f172bd6..4e05b77 100644 --- a/assets/js/search.js +++ b/assets/js/search.js @@ -1,84 +1,28 @@ -let lunrIndex -let lunrResult -let pagesIndex +{{ $searchData := resources.Get "list.json" | resources.ExecuteAsTemplate "search-data.json" . }} +const searchDataURL = '{{ $searchData.RelPermalink }}' -const bigramTokeniser = (obj, metadata) => { - if (obj == null || obj == undefined) { - return [] - } - - let str = obj.toString().trim().toLowerCase() - let tokens = [] - - for (let i = 0; i <= str.length - 2; i++) { - let tokenMetadata = lunr.utils.clone(metadata) || {} - tokenMetadata['position'] = [i, i + 2] - tokenMetadata['index'] = tokens.length - tokens.push(new lunr.Token(str.slice(i, i + 2), tokenMetadata)) - } - - return tokens -} - -const queryNgramSeparator = (query) => { - const str = query.toString().trim().toLowerCase() - const tokens = [] - - for (let i = 0; i <= str.length - 2; i++) { - tokens.push(str.slice(i, i + 2)) - } - - return tokens.join(' ') -} - -const index = '../post/index.json' - -const initLunr = () => { - let request = new XMLHttpRequest() - request.open('GET', index, true) - request.onload = function () { - if (this.status >= 200 && this.status < 400) { - pagesIndex = JSON.parse(this.response) - lunrIndex = lunr(function () { - this.tokenizer = bigramTokeniser - this.pipeline.reset() - this.ref('ref') - this.field('title', { boost: 10 }) - this.field('body') - this.metadataWhitelist = ['position'] - pagesIndex.forEach((page) => { - this.add(page) - }, this) - }) - } else { - console.error('Error getting Hugo index flie') - } - } - request.onerror = function () { - console.error('connection error') - } - request.send() -} - -/** - * Searching pages using lunr - * @param {String} query Query string for searching - * @return {Object[]} Array of search results - */ -const search = (query) => { - lunrResult = lunrIndex.search(queryNgramSeparator(query)) - return lunrResult.map((result) => { - return pagesIndex.filter((page) => { - return page.ref === result.ref - })[0] - }) -} - -const initUI = () => { +const init = () => { const searchBox = document.querySelector('#searchBox') if (searchBox === null) { return } + + let index = new FlexSearch.Document({ + tokenize: 'forward', + document: { + field: ['title', 'body'], + store: ['title', 'href', 'body'] + }, + }) + + fetch(searchDataURL) + .then(pages => pages.json()) + .then(pages => { + for(let i = 0; i < pages.length; i++){ + index.add(i, pages[i]); + } + }) + searchBox.addEventListener('keyup', function (event) { let searchResultsArea = document.querySelector('#searchResults') let query = event.currentTarget.value @@ -90,20 +34,19 @@ const initUI = () => { } // Display search results - renderResults(search(query)) + renderResults(index.search(query, 10, { enrich: true })); searchResultsArea.style.display = 'block' }) } /** * Rendering search results - * @param {Object[]} results Array of search results + * @param {Object[]} results Array of search results ( fields[] => { field, result[] => { document }} ) */ const renderResults = (results) => { const searchResults = document.querySelector('#searchResults') const query = document.querySelector('#searchBox').value const BODY_LENGTH = 100 - const MAX_PAGES = 10 // Clear search result while (searchResults.firstChild) @@ -117,32 +60,37 @@ const renderResults = (results) => { searchResults.append(resultPage) return } + console.log(results) let instance = new Mark(document.querySelector('#searchResults')) - // Only show the ten first results - results.slice(0, MAX_PAGES).forEach((result, idx) => { - let resultPage = document.createElement('div') - resultPage.className = 'searchResultPage' - let metadata = lunrResult[idx].matchData.metadata - let matchPosition = metadata[Object.keys(metadata)[0]].body.position[0][0] - let bodyStartPosition = - matchPosition - BODY_LENGTH / 2 > 0 ? matchPosition - BODY_LENGTH / 2 : 0 - - let resultTitle = document.createElement('a') - resultTitle.className = 'searchResultTitle' - resultTitle.href = result.ref - resultTitle.innerHTML = result.title - resultPage.append(resultTitle) - - let resultBody = document.createElement('div') - resultBody.className = 'searchResultBody' - resultBody.innerHTML = result.body.substr(bodyStartPosition, BODY_LENGTH) - resultPage.append(resultBody) - searchResults.append(resultPage) - - instance.mark(query) + results.forEach((result) => { + let isBody = result.field === "body" + + // TODO: create array remove duplicate docs + result.result.forEach((result) => { + console.log(result) + let resultPage = document.createElement('div') + resultPage.className = 'searchResultPage' + + let resultTitle = document.createElement('a') + resultTitle.className = 'searchResultTitle' + resultTitle.href = result.doc.href + resultTitle.innerHTML = result.doc.title + resultPage.append(resultTitle) + + if (isBody) { + let resultBody = document.createElement('div') + resultBody.className = 'searchResultBody' + let matchPos = result.doc.body.indexOf(query) + let bodyStartPos = matchPos - BODY_LENGTH / 2 > 0 ? matchPos - BODY_LENGTH / 2 : 0 + resultBody.innerHTML = result.doc.body.substr(bodyStartPos, BODY_LENGTH) + resultPage.append(resultBody) + } + searchResults.append(resultPage) + + instance.mark(query) + }) }) } -initLunr() -initUI() +init(); diff --git a/assets/list.json b/assets/list.json new file mode 100644 index 0000000..9126d52 --- /dev/null +++ b/assets/list.json @@ -0,0 +1,15 @@ +[ + {{ $pages := where .Site.Pages "Kind" "in" (slice "page" "post") }} + {{ $pages = where $pages "Content" "not in" (slice nil "") }} + {{ range $index, $page := $pages }} + {{ if ne $index 0 }},{{ end }} + { + "id": {{ $index }}, + "href": "{{ $page.Permalink }}", + "title": {{ $page.Title | jsonify }}, + "section": "{{ $page.Section }}", + "date" : {{ $page.Date.Format "2006.01.02" | jsonify }}, + "body": {{ $page.Plain | jsonify }} + } + {{ end }} +] diff --git a/layouts/_default/list.json b/layouts/_default/list.json deleted file mode 100644 index 618a67a..0000000 --- a/layouts/_default/list.json +++ /dev/null @@ -1,15 +0,0 @@ -[ - {{ range $index, $page := .Pages }} - {{ if eq .Type "post" }} - {{ if ne $index 0 }},{{ end }} - { - "id": $index, - "ref": "{{ $page.Permalink }}", - "title": {{ $page.Title | jsonify }}, - "section": "{{ $page.Section }}", - "date" : {{ $page.Date.Format "2006.01.02" | jsonify }}, - "body": {{ $page.Plain | jsonify }} - } - {{ end }} - {{ end }} -] diff --git a/layouts/partials/head.html b/layouts/partials/head.html index 7507d7e..9b15997 100644 --- a/layouts/partials/head.html +++ b/layouts/partials/head.html @@ -66,10 +66,15 @@ {{- if (eq .Layout `search`) -}} + {{ $flexsearch := resources.Get "js/flexsearch.bundle.js" }} + + {{ $lunr := resources.Get "js/lunr.min.js" }} {{ $mark := resources.Get "js/mark.min.js" }} {{ $basesearch := resources.Get "js/search.js" }} - {{ $search := (slice $lunr $mark $basesearch) | resources.Concat "js/search.js" | minify }} + + {{ $searchJSFile := printf "js/%s.search.js" .Language.Lang }} + {{ $search := (slice $lunr $mark $basesearch) | resources.Concat "js/search.js" | resources.ExecuteAsTemplate $searchJSFile . | resources.Fingerprint }} {{- end -}} -- cgit v1.2.3 From 4954da84f2ac474c8ca34cbc4f91ed896659fdd0 Mon Sep 17 00:00:00 2001 From: matsuyoshi Date: Sun, 24 Oct 2021 01:02:42 +0900 Subject: remove lunr --- layouts/partials/head.html | 1 - package-lock.json | 5 ----- package.json | 3 +-- 3 files changed, 1 insertion(+), 8 deletions(-) diff --git a/layouts/partials/head.html b/layouts/partials/head.html index 9b15997..4a261ea 100644 --- a/layouts/partials/head.html +++ b/layouts/partials/head.html @@ -69,7 +69,6 @@ {{ $flexsearch := resources.Get "js/flexsearch.bundle.js" }} - {{ $lunr := resources.Get "js/lunr.min.js" }} {{ $mark := resources.Get "js/mark.min.js" }} {{ $basesearch := resources.Get "js/search.js" }} diff --git a/package-lock.json b/package-lock.json index 39b02e3..b075a3a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1659,11 +1659,6 @@ "yallist": "^4.0.0" } }, - "lunr": { - "version": "2.3.9", - "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", - "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==" - }, "make-plural": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/make-plural/-/make-plural-4.3.0.tgz", diff --git a/package.json b/package.json index 2797efe..3d5bb3a 100644 --- a/package.json +++ b/package.json @@ -12,8 +12,7 @@ "license": "MIT", "dependencies": { "flexsearch": "^0.7.21", - "instant.page": "^3.0.0", - "lunr": "^2.3.9" + "instant.page": "^3.0.0" }, "devDependencies": { "eslint": "^7.23.0", -- cgit v1.2.3 From 2a14420ed48e4457486f84eaeb8edd5ec0d7d9ea Mon Sep 17 00:00:00 2001 From: matsuyoshi Date: Mon, 25 Oct 2021 22:20:44 +0900 Subject: remove unnecessary code --- assets/js/search.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/assets/js/search.js b/assets/js/search.js index 4e05b77..58d0ec7 100644 --- a/assets/js/search.js +++ b/assets/js/search.js @@ -60,7 +60,6 @@ const renderResults = (results) => { searchResults.append(resultPage) return } - console.log(results) let instance = new Mark(document.querySelector('#searchResults')) results.forEach((result) => { @@ -68,7 +67,6 @@ const renderResults = (results) => { // TODO: create array remove duplicate docs result.result.forEach((result) => { - console.log(result) let resultPage = document.createElement('div') resultPage.className = 'searchResultPage' -- cgit v1.2.3 From d18377c4d8e3e179086c7bb263f39edfb9b3d60b Mon Sep 17 00:00:00 2001 From: matsuyoshi Date: Mon, 25 Oct 2021 23:24:27 +0900 Subject: remove duplicate results --- assets/js/search.js | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/assets/js/search.js b/assets/js/search.js index 58d0ec7..a2ffc4e 100644 --- a/assets/js/search.js +++ b/assets/js/search.js @@ -61,33 +61,33 @@ const renderResults = (results) => { return } - let instance = new Mark(document.querySelector('#searchResults')) - results.forEach((result) => { - let isBody = result.field === "body" + let arr = results[0].result + if (results.length > 1) { + arr.concat(results[1].result) + } + arr.filter((element, index, self) => + self.findIndex(e => e.id === element.id) === index) - // TODO: create array remove duplicate docs - result.result.forEach((result) => { - let resultPage = document.createElement('div') - resultPage.className = 'searchResultPage' + let instance = new Mark(document.querySelector('#searchResults')) + arr.forEach((result) => { + let resultPage = document.createElement('div') + resultPage.className = 'searchResultPage' - let resultTitle = document.createElement('a') - resultTitle.className = 'searchResultTitle' - resultTitle.href = result.doc.href - resultTitle.innerHTML = result.doc.title - resultPage.append(resultTitle) + let resultTitle = document.createElement('a') + resultTitle.className = 'searchResultTitle' + resultTitle.href = result.doc.href + resultTitle.innerHTML = result.doc.title + resultPage.append(resultTitle) - if (isBody) { - let resultBody = document.createElement('div') - resultBody.className = 'searchResultBody' - let matchPos = result.doc.body.indexOf(query) - let bodyStartPos = matchPos - BODY_LENGTH / 2 > 0 ? matchPos - BODY_LENGTH / 2 : 0 - resultBody.innerHTML = result.doc.body.substr(bodyStartPos, BODY_LENGTH) - resultPage.append(resultBody) - } - searchResults.append(resultPage) + let resultBody = document.createElement('div') + resultBody.className = 'searchResultBody' + let matchPos = result.doc.body.indexOf(query) + let bodyStartPos = matchPos - BODY_LENGTH / 2 > 0 ? matchPos - BODY_LENGTH / 2 : 0 + resultBody.innerHTML = result.doc.body.substr(bodyStartPos, BODY_LENGTH) + resultPage.append(resultBody) + searchResults.append(resultPage) - instance.mark(query) - }) + instance.mark(query) }) } -- cgit v1.2.3 From c5aa5909e5820e0c7dd7e3bd62f09c684fd973fe Mon Sep 17 00:00:00 2001 From: matsuyoshi Date: Tue, 26 Oct 2021 00:04:05 +0900 Subject: fix tokenizer --- assets/js/search.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/js/search.js b/assets/js/search.js index a2ffc4e..2da9df3 100644 --- a/assets/js/search.js +++ b/assets/js/search.js @@ -8,7 +8,7 @@ const init = () => { } let index = new FlexSearch.Document({ - tokenize: 'forward', + tokenize: 'reverse', document: { field: ['title', 'body'], store: ['title', 'href', 'body'] -- cgit v1.2.3 From 9d533b819ea13f0262d6303ac67b50d53a2403eb Mon Sep 17 00:00:00 2001 From: matsuyoshi Date: Tue, 26 Oct 2021 00:06:48 +0900 Subject: remove unnecessary code --- layouts/partials/head.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layouts/partials/head.html b/layouts/partials/head.html index 4a261ea..dda2612 100644 --- a/layouts/partials/head.html +++ b/layouts/partials/head.html @@ -73,7 +73,7 @@ {{ $basesearch := resources.Get "js/search.js" }} {{ $searchJSFile := printf "js/%s.search.js" .Language.Lang }} - {{ $search := (slice $lunr $mark $basesearch) | resources.Concat "js/search.js" | resources.ExecuteAsTemplate $searchJSFile . | resources.Fingerprint }} + {{ $search := (slice $mark $basesearch) | resources.Concat "js/search.js" | resources.ExecuteAsTemplate $searchJSFile . | resources.Fingerprint }} {{- end -}} -- cgit v1.2.3 From f1670d6fbc7f3b37acc34ae66636130b701b73ee Mon Sep 17 00:00:00 2001 From: matsuyoshi Date: Tue, 26 Oct 2021 00:18:03 +0900 Subject: remove lunr --- assets/js/lunr.min.js | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 assets/js/lunr.min.js diff --git a/assets/js/lunr.min.js b/assets/js/lunr.min.js deleted file mode 100644 index cdc94cd..0000000 --- a/assets/js/lunr.min.js +++ /dev/null @@ -1,6 +0,0 @@ -/** - * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 2.3.9 - * Copyright (C) 2020 Oliver Nightingale - * @license MIT - */ -!function(){var e=function(t){var r=new e.Builder;return r.pipeline.add(e.trimmer,e.stopWordFilter,e.stemmer),r.searchPipeline.add(e.stemmer),t.call(r,r),r.build()};e.version="2.3.9",e.utils={},e.utils.warn=function(e){return function(t){e.console&&console.warn&&console.warn(t)}}(this),e.utils.asString=function(e){return void 0===e||null===e?"":e.toString()},e.utils.clone=function(e){if(null===e||void 0===e)return e;for(var t=Object.create(null),r=Object.keys(e),i=0;i0){var c=e.utils.clone(r)||{};c.position=[a,l],c.index=s.length,s.push(new e.Token(i.slice(a,o),c))}a=o+1}}return s},e.tokenizer.separator=/[\s\-]+/,e.Pipeline=function(){this._stack=[]},e.Pipeline.registeredFunctions=Object.create(null),e.Pipeline.registerFunction=function(t,r){r in this.registeredFunctions&&e.utils.warn("Overwriting existing registered function: "+r),t.label=r,e.Pipeline.registeredFunctions[t.label]=t},e.Pipeline.warnIfFunctionNotRegistered=function(t){var r=t.label&&t.label in this.registeredFunctions;r||e.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",t)},e.Pipeline.load=function(t){var r=new e.Pipeline;return t.forEach(function(t){var i=e.Pipeline.registeredFunctions[t];if(!i)throw new Error("Cannot load unregistered function: "+t);r.add(i)}),r},e.Pipeline.prototype.add=function(){var t=Array.prototype.slice.call(arguments);t.forEach(function(t){e.Pipeline.warnIfFunctionNotRegistered(t),this._stack.push(t)},this)},e.Pipeline.prototype.after=function(t,r){e.Pipeline.warnIfFunctionNotRegistered(r);var i=this._stack.indexOf(t);if(i==-1)throw new Error("Cannot find existingFn");i+=1,this._stack.splice(i,0,r)},e.Pipeline.prototype.before=function(t,r){e.Pipeline.warnIfFunctionNotRegistered(r);var i=this._stack.indexOf(t);if(i==-1)throw new Error("Cannot find existingFn");this._stack.splice(i,0,r)},e.Pipeline.prototype.remove=function(e){var t=this._stack.indexOf(e);t!=-1&&this._stack.splice(t,1)},e.Pipeline.prototype.run=function(e){for(var t=this._stack.length,r=0;r1&&(se&&(r=n),s!=e);)i=r-t,n=t+Math.floor(i/2),s=this.elements[2*n];return s==e?2*n:s>e?2*n:sa?l+=2:o==a&&(t+=r[u+1]*i[l+1],u+=2,l+=2);return t},e.Vector.prototype.similarity=function(e){return this.dot(e)/this.magnitude()||0},e.Vector.prototype.toArray=function(){for(var e=new Array(this.elements.length/2),t=1,r=0;t0){var o,a=s.str.charAt(0);a in s.node.edges?o=s.node.edges[a]:(o=new e.TokenSet,s.node.edges[a]=o),1==s.str.length&&(o["final"]=!0),n.push({node:o,editsRemaining:s.editsRemaining,str:s.str.slice(1)})}if(0!=s.editsRemaining){if("*"in s.node.edges)var u=s.node.edges["*"];else{var u=new e.TokenSet;s.node.edges["*"]=u}if(0==s.str.length&&(u["final"]=!0),n.push({node:u,editsRemaining:s.editsRemaining-1,str:s.str}),s.str.length>1&&n.push({node:s.node,editsRemaining:s.editsRemaining-1,str:s.str.slice(1)}),1==s.str.length&&(s.node["final"]=!0),s.str.length>=1){if("*"in s.node.edges)var l=s.node.edges["*"];else{var l=new e.TokenSet;s.node.edges["*"]=l}1==s.str.length&&(l["final"]=!0),n.push({node:l,editsRemaining:s.editsRemaining-1,str:s.str.slice(1)})}if(s.str.length>1){var c,h=s.str.charAt(0),d=s.str.charAt(1);d in s.node.edges?c=s.node.edges[d]:(c=new e.TokenSet,s.node.edges[d]=c),1==s.str.length&&(c["final"]=!0),n.push({node:c,editsRemaining:s.editsRemaining-1,str:h+s.str.slice(2)})}}}return i},e.TokenSet.fromString=function(t){for(var r=new e.TokenSet,i=r,n=0,s=t.length;n=e;t--){var r=this.uncheckedNodes[t],i=r.child.toString();i in this.minimizedNodes?r.parent.edges[r["char"]]=this.minimizedNodes[i]:(r.child._str=i,this.minimizedNodes[i]=r.child),this.uncheckedNodes.pop()}},e.Index=function(e){this.invertedIndex=e.invertedIndex,this.fieldVectors=e.fieldVectors,this.tokenSet=e.tokenSet,this.fields=e.fields,this.pipeline=e.pipeline},e.Index.prototype.search=function(t){return this.query(function(r){var i=new e.QueryParser(t,r);i.parse()})},e.Index.prototype.query=function(t){for(var r=new e.Query(this.fields),i=Object.create(null),n=Object.create(null),s=Object.create(null),o=Object.create(null),a=Object.create(null),u=0;u1?this._b=1:this._b=e},e.Builder.prototype.k1=function(e){this._k1=e},e.Builder.prototype.add=function(t,r){var i=t[this._ref],n=Object.keys(this._fields);this._documents[i]=r||{},this.documentCount+=1;for(var s=0;s=this.length)return e.QueryLexer.EOS;var t=this.str.charAt(this.pos);return this.pos+=1,t},e.QueryLexer.prototype.width=function(){return this.pos-this.start},e.QueryLexer.prototype.ignore=function(){this.start==this.pos&&(this.pos+=1),this.start=this.pos},e.QueryLexer.prototype.backup=function(){this.pos-=1},e.QueryLexer.prototype.acceptDigitRun=function(){var t,r;do t=this.next(),r=t.charCodeAt(0);while(r>47&&r<58);t!=e.QueryLexer.EOS&&this.backup()},e.QueryLexer.prototype.more=function(){return this.pos1&&(t.backup(),t.emit(e.QueryLexer.TERM)),t.ignore(),t.more())return e.QueryLexer.lexText},e.QueryLexer.lexEditDistance=function(t){return t.ignore(),t.acceptDigitRun(),t.emit(e.QueryLexer.EDIT_DISTANCE),e.QueryLexer.lexText},e.QueryLexer.lexBoost=function(t){return t.ignore(),t.acceptDigitRun(),t.emit(e.QueryLexer.BOOST),e.QueryLexer.lexText},e.QueryLexer.lexEOS=function(t){t.width()>0&&t.emit(e.QueryLexer.TERM)},e.QueryLexer.termSeparator=e.tokenizer.separator,e.QueryLexer.lexText=function(t){for(;;){var r=t.next();if(r==e.QueryLexer.EOS)return e.QueryLexer.lexEOS;if(92!=r.charCodeAt(0)){if(":"==r)return e.QueryLexer.lexField;if("~"==r)return t.backup(),t.width()>0&&t.emit(e.QueryLexer.TERM),e.QueryLexer.lexEditDistance;if("^"==r)return t.backup(),t.width()>0&&t.emit(e.QueryLexer.TERM),e.QueryLexer.lexBoost;if("+"==r&&1===t.width())return t.emit(e.QueryLexer.PRESENCE),e.QueryLexer.lexText;if("-"==r&&1===t.width())return t.emit(e.QueryLexer.PRESENCE),e.QueryLexer.lexText;if(r.match(e.QueryLexer.termSeparator))return e.QueryLexer.lexTerm}else t.escapeCharacter()}},e.QueryParser=function(t,r){this.lexer=new e.QueryLexer(t),this.query=r,this.currentClause={},this.lexemeIdx=0},e.QueryParser.prototype.parse=function(){this.lexer.run(),this.lexemes=this.lexer.lexemes;for(var t=e.QueryParser.parseClause;t;)t=t(this);return this.query},e.QueryParser.prototype.peekLexeme=function(){return this.lexemes[this.lexemeIdx]},e.QueryParser.prototype.consumeLexeme=function(){var e=this.peekLexeme();return this.lexemeIdx+=1,e},e.QueryParser.prototype.nextClause=function(){var e=this.currentClause;this.query.clause(e),this.currentClause={}},e.QueryParser.parseClause=function(t){var r=t.peekLexeme();if(void 0!=r)switch(r.type){case e.QueryLexer.PRESENCE:return e.QueryParser.parsePresence;case e.QueryLexer.FIELD:return e.QueryParser.parseField;case e.QueryLexer.TERM:return e.QueryParser.parseTerm;default:var i="expected either a field or a term, found "+r.type;throw r.str.length>=1&&(i+=" with value '"+r.str+"'"),new e.QueryParseError(i,r.start,r.end)}},e.QueryParser.parsePresence=function(t){var r=t.consumeLexeme();if(void 0!=r){switch(r.str){case"-":t.currentClause.presence=e.Query.presence.PROHIBITED;break;case"+":t.currentClause.presence=e.Query.presence.REQUIRED;break;default:var i="unrecognised presence operator'"+r.str+"'";throw new e.QueryParseError(i,r.start,r.end)}var n=t.peekLexeme();if(void 0==n){var i="expecting term or field, found nothing";throw new e.QueryParseError(i,r.start,r.end)}switch(n.type){case e.QueryLexer.FIELD:return e.QueryParser.parseField;case e.QueryLexer.TERM:return e.QueryParser.parseTerm;default:var i="expecting term or field, found '"+n.type+"'";throw new e.QueryParseError(i,n.start,n.end)}}},e.QueryParser.parseField=function(t){var r=t.consumeLexeme();if(void 0!=r){if(t.query.allFields.indexOf(r.str)==-1){var i=t.query.allFields.map(function(e){return"'"+e+"'"}).join(", "),n="unrecognised field '"+r.str+"', possible fields: "+i;throw new e.QueryParseError(n,r.start,r.end)}t.currentClause.fields=[r.str];var s=t.peekLexeme();if(void 0==s){var n="expecting term, found nothing";throw new e.QueryParseError(n,r.start,r.end)}switch(s.type){case e.QueryLexer.TERM:return e.QueryParser.parseTerm;default:var n="expecting term, found '"+s.type+"'";throw new e.QueryParseError(n,s.start,s.end)}}},e.QueryParser.parseTerm=function(t){var r=t.consumeLexeme();if(void 0!=r){t.currentClause.term=r.str.toLowerCase(),r.str.indexOf("*")!=-1&&(t.currentClause.usePipeline=!1);var i=t.peekLexeme();if(void 0==i)return void t.nextClause();switch(i.type){case e.QueryLexer.TERM:return t.nextClause(),e.QueryParser.parseTerm;case e.QueryLexer.FIELD:return t.nextClause(),e.QueryParser.parseField;case e.QueryLexer.EDIT_DISTANCE:return e.QueryParser.parseEditDistance;case e.QueryLexer.BOOST:return e.QueryParser.parseBoost;case e.QueryLexer.PRESENCE:return t.nextClause(),e.QueryParser.parsePresence;default:var n="Unexpected lexeme type '"+i.type+"'";throw new e.QueryParseError(n,i.start,i.end)}}},e.QueryParser.parseEditDistance=function(t){var r=t.consumeLexeme();if(void 0!=r){var i=parseInt(r.str,10);if(isNaN(i)){var n="edit distance must be numeric";throw new e.QueryParseError(n,r.start,r.end)}t.currentClause.editDistance=i;var s=t.peekLexeme();if(void 0==s)return void t.nextClause();switch(s.type){case e.QueryLexer.TERM:return t.nextClause(),e.QueryParser.parseTerm;case e.QueryLexer.FIELD:return t.nextClause(),e.QueryParser.parseField;case e.QueryLexer.EDIT_DISTANCE:return e.QueryParser.parseEditDistance;case e.QueryLexer.BOOST:return e.QueryParser.parseBoost;case e.QueryLexer.PRESENCE:return t.nextClause(),e.QueryParser.parsePresence;default:var n="Unexpected lexeme type '"+s.type+"'";throw new e.QueryParseError(n,s.start,s.end)}}},e.QueryParser.parseBoost=function(t){var r=t.consumeLexeme();if(void 0!=r){var i=parseInt(r.str,10);if(isNaN(i)){var n="boost must be numeric";throw new e.QueryParseError(n,r.start,r.end)}t.currentClause.boost=i;var s=t.peekLexeme();if(void 0==s)return void t.nextClause();switch(s.type){case e.QueryLexer.TERM:return t.nextClause(),e.QueryParser.parseTerm;case e.QueryLexer.FIELD:return t.nextClause(),e.QueryParser.parseField;case e.QueryLexer.EDIT_DISTANCE:return e.QueryParser.parseEditDistance;case e.QueryLexer.BOOST:return e.QueryParser.parseBoost;case e.QueryLexer.PRESENCE:return t.nextClause(),e.QueryParser.parsePresence;default:var n="Unexpected lexeme type '"+s.type+"'";throw new e.QueryParseError(n,s.start,s.end)}}},function(e,t){"function"==typeof define&&define.amd?define(t):"object"==typeof exports?module.exports=t():e.lunr=t()}(this,function(){return e})}(); -- cgit v1.2.3